作成: 2026-09-15 / ブランチ: develop / 前提: 指示書AJ 完了(D-137)
D-Watch の実装をお願いします。ブランチは develop です。
■ 最初に読むもの(この順で、全部)
1. CLAUDE.md(全文。特に §2 責任分界 / §4.2 KPI / §4.6 契約フラグ / §5 モックが正 /
§7 禁止事項 / §9 実装規約)
2. docs/handoff/指示書AK_分類を復活させる.md(全文)
3. docs/decisions.md の D-053 / D-011 / D-102 / D-133
(grep -nE "^### D-(0|1)[0-9][0-9]" docs/decisions.md で位置を出してから読む。
★番号順に並んでいません★)
4. lib/facilities/resolve-by-name.ts(全文。★今回の実装が真似る作法そのもの★)
■ やること
指示書AK の 段階1 から 段階9 までを、★番号順に★実行してください。
★段階6(確定期間KPIの安全弁)だけは、段階2〜4 が終わるまで着手しないでください★ —
顧客で絞る手段が無い状態で安全弁を外すと、静かに誤った数字が出ます。
■ 段階ごとに必ずやること
1. npx tsc --noEmit → 0 であること
2. npm run lint → 0 であること
3. npm test → 全パス
4. コミットする(★段階ごとに1コミット★。まとめない)
■ コミットの決まり
・git add -A は使わないでください。必ずファイルパスを明示してください
・コミットメッセージは日本語。「なぜそうしたか」を1〜2行入れてください
・push はしないでください
■ 絶対に触らないファイル
README.md / docs/code-map.md /
docs/handoff/管理画面_設計検討_20260910.md / .claude/worktrees/** /
d-watch-mock.jsx / lib/judge/**(判定ロジックは今回変えません)
lib/db/prisma.ts
■ 絶対にやらないこと
・生SQL($queryRaw / $executeRaw / *Unsafe / Prisma.raw)— ESLint が落とします
・メインDBのスキーマ変更・マイグレーション作成
・customers.contract の参照(facilities.contract が正)
・contract を数値として比較すること(varchar(10) の桁位置です)
・新しい CSS に font-family を書くこと
・仕様が不明なところを推測で実装すること
■ 迷ったら
推測で埋めず、手を止めて「ここが決まっていません」と報告してください。
指示書AK の §12(実装者へ — 特に踏みやすい落とし穴)に、
例外もテスト失敗も出ないまま壊れる箇所を挙げてあります。着手前に読んでください。
■ 動作確認
★テストDBには グループ1件・顧客1件・施設12件 しか入っていません★。
そのままでは3階層の絞り込みを確かめられないので、
段階8 で scripts/seed-local-db.ts を拡張してローカルDBで確かめます。
★テストDB(133.125.238.144)には書き込まないでください★。
期待される結果は指示書AK の §10 に書いてあります。
■ 終わったら
・段階ごとのコミットハッシュ
・tsc / lint / test の結果(テスト本数も)
・★§10 の動作確認を実際に行った結果★
・指示書どおりにできなかったところと、その理由
・判断に迷って自分で決めたところ(あれば全部)
ユーザーの新要件4件のうち、★3件目★です。
| 要件 | 状態 |
|---|---|
| 要レスキュー店舗 | ★完了★(D-135 / D-137) |
| 詳細ログの期間上限2年 + CSV上限 | ★完了★(D-136) |
| ★分類の復活★ | ★★この指示書★★ |
| 総清掃面積の新画面 | ★次★(★この指示書の絞り込みに乗るので、順番が後★) |
TeamWorks確認事項_第9回_20260915.md で3件を照会中です。
| 照会中 | この指示書への影響 |
|---|---|
Q7-1: customers は屋号か法人か |
★画面の見出し語だけ★。構造は変わらない |
| Q7-5: 「屋号が無い顧客」はどの段が空くか | ★表示の出し方だけ★ |
Q7-4: group_id = 0 が FK で入らない |
★データ投入側の話★。読む側は 0 → null で扱えばよい |
★★どれも構造を変えません。★★ ★DBの階層は groups → customers → facilities の3段しかなく、 4段目の受け皿が無いからです。★ ★したがって、仕組みは今すぐ作れます。★
★見出し語は lib/i18n.ts の1箇所に置く★ので、★回答が来たら差し替えるのは1行★です。
★D-053(docs/decisions.md)の原文★:
- 決定: グループ・会社の絞り込み
<select>は、マスタが揃うまで画面から削除する- 理由: 固定の選択肢だけがあって何も起きないUIは、不具合と区別できないため
- 運用: ★マスタが揃った時点で、グループ・会社の絞り込みは全画面まとめて実装する★
★★「全画面まとめて」と書かれています。★★ ★1画面ずつ足さないこと。★
削除したコミットは 441c8bb(2026-09-01)です。
| 状態 | |
|---|---|
| DBの3階層 | ★groups → customers.group_id → facilities.customer_id。実在★ |
| Prisma のモデル | ★Group / Customer / Facility。実在★ |
API契約の group_id / customer_id |
★11エンドポイントに定義済み★ |
GET /groups / GET /customers |
★契約にはある。★ルートが無い★ |
| 実装 | ★受け取って無視している★(D-053 のコメントが13ファイル) |
★★つまり契約の追加ではなく、実装の穴埋めです。★★
・分類をホールディングス、各グループ(ブランド)、店舗 分類を復活
★真ん中は屋号(ブランド)★(2026-09-15「屋号でよいです、ただ顧客によってはない場合もあります」)。
★対応:★
ホールディングス → 屋号(ブランド) → 店舗 groups customers facilities
★ユーザーに個別の確認を取らず、既存の規則との整合から決めた事項です。★
★これが今回いちばん重要な決定です。★
背景: /reports/kpi の確定期間は customer_summaries を読みます(D-102)。 現在は「複数顧客の行が混ざったら例外(500)」という安全弁が入っています(D-133)。
合算できないことが実測で分かっています。
| 指標 | サマリの分子 | サマリの分母 | 合算できるか |
|---|---|---|---|
| 清掃完了率 | clean_area |
task_area |
★できる★ |
| 出発成功率 | launch_count |
task_count? |
★式が未確認★ |
| ★稼働率★ | ★列が無い★ | task_count? |
★★できない★★ |
| ★エラー発生率★ | error_count |
★列が無い★ | ★★できない★★ |
★「清掃実施回数」に当たる列がサマリにありません。★ ★率の平均を取るのは誤り★です(店舗数の違いが消えます)。
★決定:★
customer_id が指定されている → その顧客で絞る
group_id が指定されている → 傘下の顧客が1社なら、その顧客で絞る
2社以上なら 422
どちらも指定なし・顧客が1社だけ → その顧客(★P1 はここ★)
どちらも指定なし・顧客が2社以上 → ★★422★★
★422 のメッセージ★:
「顧客またはグループを指定してください。複数の顧客のデータを合算した数値は出せません。」
details: { customer_ids: [...] } ← ★候補を返す★
★★500 ではなく 422 にすること★★ — ★サーバの不具合ではなく、指定が足りないという話★です。 ★details に候補を返すこと★ — ★画面が「どれを選べばよいか」を示せます。★
★★「静かに1社を選ぶ」ことは絶対にしないこと★★(D-133 が明確に否定しています。 どの顧客かを決める根拠が無いまま選ぶと、選び間違いに誰も気づけません)。
★P1 の対象顧客は1社だけ★(CLAUDE.md §1)なので、★この422は当面発火しません★。 ★2社目が入った日に、画面が「選んでください」と言うようになります。★
★却下した案と理由(記録に残すこと)★:
| 案 | なぜ却下したか |
|---|---|
| 全顧客を合算する | ★4指標のうち2つを正しく合算する材料がDBに無い★(上の表) |
| 率の加重平均で近似する | ★TeamWorks が計算した値ではなくなる★。検算可能性(D-022 の設計意図)を失う |
| 500 のまま | ★2社目が入った瞬間、レポート画面が常時500になる★。運用が止まる |
| 顧客が1社のときだけ暗黙に選ぶ | ★候補が1つなら選び間違いようが無いので採用★(上の決定に含めた)。★2社以上で暗黙に選ぶのは却下★ |
★既存の作法に乗せます★(lib/facilities/resolve-by-name.ts、指示書AC / AG の帰結)。
group_id / customer_id → 対象の施設IDの配列 → where: { facility_id: { in: [...] } }
★★null と [] を区別すること★★:
| 値 | 意味 |
|---|---|
null |
★条件なし(全件)★ |
[] |
★0件ヒット★ |
[1,2,3] |
その施設だけ |
★★必ず !== null で分岐すること★★ — ★in: undefined は条件が消えて全件になります★。 ★?.length で判定すると、「0件ヒット」が「全件表示」に化けます。例外もテスト失敗も出ません。★
★既存の正しい書き方が2箇所にあります★。★そのまま真似ること★:
lib/db/index.ts の cleanLogs()(facility_ids !== null ? { facility_id: { in: ... } } : {})lib/db/index.ts の facilityPerformance()★★施設名の検索と併用されたときは、両方の積集合を取ること★★(AND)。 ★どちらか片方を捨てないこと。★
★施設名検索がアプリ側照合になっているのは、「中点を無視する比較が MariaDB に無い」からです★ (実測済み。lib/facilities/resolve-by-name.ts の冒頭コメント)。
★group_id / customer_id は整数の完全一致★なので、★その制約はありません★。 ★全件をメモリに読んで照合する必要はありません。★
★真似るのは「null / [] の戻り値の契約」と「in に渡す形」だけ★です。
★eq_range_index_dive_limit = 200★(MariaDB 10.11 で実測)。 ★IN の要素数が200を超えると、索引ダイブをやめて統計推定に切り替わります。★ ★遅くなるだけで、エラーは出ません。★
★グループの絞り込みは「1グループ=傘下の全店」なので、施設名検索より200を超えやすい★です。
★決定: 今回は素通しする。★
★理由★: P1 の施設数は200件程度の想定で、★本番の施設数の見積もりが資料に1件も無い★ (第9回 8章で照会中)。★測れない相手に対策を入れても、効いたかどうかが分かりません。★
★★申し送りに書くこと★★: 施設が200件を超えたら実行計画を測り直す。 ★JOIN(リレーションフィルタ)に切り替える案があるが、このプロジェクトに前例が0件で、 Prisma 7 + MariaDB adapter がどんなSQLを出すか未実測★。
★ユーザーの言葉を使う★。★lib/i18n.ts の1箇所に置くこと★。
| 語 | EN |
|---|---|
| ホールディングス | Holdings |
| 屋号 | Brand |
| 全ホールディングス | All Holdings |
| 全屋号 | All Brands |
★★既存の「全グループ」「全会社」を再定義しないこと★★(lib/i18n.ts に既にあります)。 ★古い語を消すかどうかは実装者判断★ですが、★消すなら他に使っていないことを確かめること★。
★★TeamWorks の回答(Q7-1)で customers が法人だと分かったら、この表だけ差し替えます。★★ ★だから1箇所に集めておくこと。★
| 対象 | 理由 |
|---|---|
README.md / docs/code-map.md / docs/handoff/管理画面_設計検討_20260910.md / .claude/worktrees/** |
★別作業★ |
d-watch-mock.jsx |
★モックは原型として保存する★ |
★lib/judge/**★ |
★判定ロジックは今回変えません★ |
lib/db/prisma.ts |
★未コミットの変更が乗っている★ |
★テストDB(133.125.238.144)への書き込み★ |
★★読み取り専用。SELECT 以外を投げないこと★★ |
★★禁止★★(CLAUDE.md §7):
git add -A★ — 必ずファイルパスを明示するcustomers.contract の参照★(★facilities.contract が正★。D-010 / D-080)contract を数値として比較すること★ — ★varchar(10) の桁位置です★。 ★Number("0000000000") は例外を出さずに 0 になり、★★全施設が「契約なし」になってメニューが 全部消えるのに、例外もテスト失敗も出ません★★★(D-080)font-family★d-watch-api.yaml の /groups と /customers は★定義済み★です。★先に読むこと。★
★ただし、そのままでは足りない点が5つ★あります。★どう埋めるかを決めてから実装すること。★
| # | 足りない点 | どうするか |
|---|---|---|
| 1 | ★meta が無い★(CLAUDE.md §9.3 は「一覧APIは必ず meta を返す」) |
★セレクトリスト用なのでページングは要らない★。★meta を足すか、YAML に「セレクト用なので meta を返さない」と明記するか、どちらかに決めて理由を書くこと★ |
| 2 | ★エラー応答の宣言が無い★ | ★他のルートも全部同じ状態★(別課題として記録済み)。★今回だけ足すと書式が揃わない★。★足さないことを選んでよいが、選んだ理由を書くこと★ |
| 3 | ★group_id に「未設定を明示する」値が無い★ |
★group_id=0 を API に漏らさないこと★(D-011 は「API層で 0 → null に変換する」と定めている)。★「ホールディングスなしの顧客だけ」を引く手段は今回作らない★ |
| 4 | ★inactive / deleted_at の扱いが未定義★ |
★deleted_at IS NULL で絞る★(db.facilities() と揃える)。★inactive では絞らない★。★YAML の description に書くこと★ |
| 5 | ★ソート順が未定義★ | ★id の昇順★。★契約に明記すること★(D-052 / D-055 の前例) |
app/api/groups/route.ts / app/api/customers/route.tsapp/api/schedules/route.ts★(items + meta だけの一覧で、形が近い)proxy.ts が横断して処理しますGET だけ★。★POST / PUT / DELETE を足さないこと★(マスタのCRUDは D-Security 側の画面。docs/spec.md)DataSource への追加lib/db/index.ts の interface DataSource に足し、 ★fixtureSource と prismaSource の両方に実装すること★。
★★fixtures 側を notImplemented にしないこと★★ — ★USE_FIXTURES=true で画面が落ちます。★
★lib/fixtures/ に groups.ts / customers.ts が存在しません。新設すること。★ ★施設12件をどの顧客に割り当てるかは実装者判断★ですが、 ★★1グループ・1顧客にしないこと★★ — ★それでは3階層のUIを fixtures で確かめられません。★
group_id = 0 の扱い★DB: customers.group_id = 0 (NOT NULL。0 = グループなしのセンチネル。D-011) API: group_id = null
★変換は1箇所に閉じ込めること★(lib/format/ か lib/config/ の純粋関数。D-080 の作法)。 ★画面やルートに === 0 を散らさないこと。★
★★「グループ0」という行を作らないこと★★ — ★グループ一覧に id=0 が現れてはいけません。★
group_id / customer_id を足す| ファイル |
|---|
lib/prechecks/query.ts |
lib/ds-devices/query.ts |
lib/ds-alerts/query.ts |
lib/reports/query.ts |
lib/facilities/query.ts |
lib/clean-logs/query.ts |
lib/schedules/query.ts |
★「D-053。マスタ未整備のため無視する」というコメントを消し、実際に読むようにする。★
lib/prechecks/__tests__/query.test.ts lib/ds-devices/__tests__/query.test.ts lib/ds-alerts/__tests__/query.test.ts lib/reports/__tests__/query.test.ts lib/facilities/__tests__/query.test.ts
すべて it("group_id / customer_id を渡してもパース結果に含まれない(D-053)") です。
★★it ごと消さないこと★★ — ★テストが1本も残らないと、次に誰かが「無視する」実装に戻しても 気づけません。★
★反転させて、さらに強くすること★:
| # | 入力 | 期待 |
|---|---|---|
| 2-1 | group_id=1 |
★1 が入る★(★toHaveProperty ではなく値まで見ること★) |
| 2-2 | customer_id=2 |
★2 が入る★ |
| 2-3 | ★未指定★ | ★null★ |
| 2-4 | ★group_id=0★ |
★★422★★(★0 はセンチネルで有効なIDではない★) |
| 2-5 | ★group_id=1abc★ |
★★422★★(★parseInt の前方一致で 1 にしないこと★。D-123 で踏んだ罠) |
| 2-6 | group_id=-1 |
★422★ |
| 2-7 | ★group_id=1.5★ |
★422★ |
| 2-8 | ★巨大な整数★(Number.MAX_SAFE_INTEGER 超) |
★422★ |
★★2-5 は過去に実際に踏んだ罠です★★(D-123)。★必ずテストに入れること。★ ★既存の parsePathId()(lib/api/path-params.ts)が ^\d+$ + Number.isSafeInteger で やっているので、★同じ作法を使うこと★。
d-watch-api.yaml の GroupId / CustomerId:
グループで絞り込み。★グループ・会社マスタ未整備のため現在は受け取るが無視する。実DB接続時に対応する★
★この記述を書き換えること。★ ★minimum: 1 を足すこと★(0 はセンチネルなので有効なIDではない)。
★★group_id と customer_id を同時に指定したときの扱いを決めて、契約に書くこと★★ — ★資料のどこにも定義がありません。★ ★AND(両方を満たす施設)が素直★ですが、 ★決めたら必ず YAML に書くこと★(次の人が推測しないように)。
lib/facilities/ に足す(resolve-by-name.ts の隣)。
groupId / customerId → 対象の施設IDの配列 | null
★戻り値の契約は resolveFacilityIdsByName() と完全に同じにすること★:
| 状況 | 戻り値 |
|---|---|
| どちらも未指定 | ★null★(条件なし) |
| 指定されたが該当0件 | ★[]★ |
| 該当あり | ID の配列 |
★施設名の絞り込みと同時に指定されたら、積集合を取ること★(AND)。
| 施設名 | グループ | 期待 |
|---|---|---|
null |
null |
★null★ |
[1,2,3] |
null |
[1,2,3] |
null |
[2,3,4] |
[2,3,4] |
★[1,2,3]★ |
★[2,3,4]★ |
★★[2,3]★★ |
★[1]★ |
★[2]★ |
★★[]★★(★null にしないこと★) |
[] |
[1,2] |
★[]★ |
★★最後の2行が要です★★ — ★積集合が空になったとき [] を返すこと★。 ★null にすると全件表示に化けます。★
deleted_at で絞るかどうか★: ★facilityNameIndex() は絞っていません★ (★削除済み施設のログが見えなくなるのを避けるため。罠7★)。★同じ扱いにすること。★ ★違う扱いにするなら、理由をコメントに書くこと。★| ルート | 備考 |
|---|---|
/clean-logs / /clean-logs/export |
★YAML は宣言済み。コードにコメントも無い★ |
/prechecks |
|
/ds-devices |
|
/ds-alerts |
|
/facilities |
★YAML に宣言が無い。足すこと★ |
/schedules |
★同上★ |
/dashboard |
★要レスキューと数値カードの両方に効く★ |
/reports/facility-performance |
★施設単位なので普通に効く★ |
/reports/continuous-problems |
★同上★ |
/reports/error-breakdown |
★★当期は施設単位。確定期間は段階6 の話★★ |
/dashboard の注意★★数値カード(summary)にも絞り込みが効きます。★ ★それが正しい★です (「この屋号の昨夜の成績」が見たいので)。
★★ただし、要レスキューと数値カードで母集団がずれないようにすること★★ — ★同じ facility_ids を両方に渡すこと。★
facility_error_summaries の絞り込み★lib/db/index.ts の errorBreakdown() は facility_error_summaries を ★facility_id で絞らずに読んでいます★(D-133 の申し送り③)。
★今回、絞り込みが入るので解決できます。★ ★ReportDbQuery に facility_ids を足すこと★ (現在は FacilityPerformanceDbQuery にしかありません)。
Facility に所属を足すd-watch-api.yaml の Facility と lib/types/index.ts の Facility に足す:
| フィールド | 型 | 備考 |
|---|---|---|
customer_id |
integer |
★NOT NULL なので nullable にしない★ |
customer_name |
string |
★一覧の「ブランド」列★。★InspectionListItem.customer_name に前例があり、文言を揃えること★ |
group_id |
integer, nullable |
★nullable 必須★(0 → null。D-011) |
group_name |
string, nullable |
同上 |
lib/db/index.ts の facilities() は既に include: { robots: ... } しています。 ★include: { customer: { include: { group: true } } } を足すだけ★です。 ★施設12件なので N+1 にはなりません。★
lib/fixtures/facilities.ts は Facility[] を直接持っています。 ★12件すべてに新しい4フィールドを足すこと。★
★★段階2〜4 が終わるまで着手しないこと。★★ ★顧客で絞る手段が無い状態で安全弁を外すと、静かに誤った数字が出ます。★
lib/db/report-mapping.ts の customerSummariesByPeriodKey():
customer_id が1種類かを確認し、★2種類以上なら例外★customer_id で where を絞って回避しないこと★ — ★どの顧客かを決める根拠が無い★」★★分類が復活すると「どの顧客かを決める根拠」ができます。★★ ★この docstring は書き換えること★ — ★残すと、次の人が矛盾した指示を読みます。★
★§2-1 の決定のとおり★:
customer_id が決まる → lib/db/index.ts の customerSummary.findMany の where に customer_id を足す 決まらない → 422
★同じ期間キーの重複を検知する分岐は残すこと★ — ★一意制約が無いので、同一顧客でも重複しうるからです。★
| # | 状況 | 期待 |
|---|---|---|
| 6-1 | customer_id=1 指定・顧客1社のデータ |
★200。その顧客の数字★ |
| 6-2 | customer_id=1 指定・DBに2社ぶんある |
★★200。顧客1だけの数字★★(★絞れているか★) |
| 6-3 | ★指定なし・顧客が1社だけ★ | ★★200★★ |
| 6-4 | ★指定なし・顧客が2社★ | ★★422★★(★500 ではない★) |
| 6-5 | 6-4 の details |
★候補の customer_ids が入る★ |
| 6-6 | group_id 指定・傘下1社 |
★200★ |
| 6-7 | ★group_id 指定・傘下2社★ |
★★422★★ |
| 6-8 | 同じ期間キーが重複 | ★例外のまま★(★この検知は残す★) |
| 6-9 | ★customer_id が存在しないID★ |
★200・空★(★422 にしない★。「該当なし」は正常) |
★★6-2 が要です★★ — ★絞り込みが本当に効いているかを、2社ぶんのデータで確かめます。★ ★段階8 の seed 拡張が要ります。★
モックに <select>全グループ</select><select>全会社</select> があるのは6画面です。
| モックの行 | 画面 |
|---|---|
:556 |
清掃詳細ログ |
:610 |
アラート(事前チェック) |
:669 |
レポート |
:836 |
D-Secログ |
:923 |
D-Secアラート |
:1091 |
★点検記録★ — ★★画面自体が未実装(D-083 で非表示)。今回は対象外★★ |
★★実質5画面です。★★ ★点検記録は画面が無いので、足しようがありません。★ ★対象外であることを記録に書くこと。★
★現在 D-053 のコメントが残っているのは3画面だけ★(清掃詳細ログ / レポート / 施設マスタ)で、 ★残りは移植時にそもそも作られていません★。★無い画面にも足すこと。★
/groups と /customers から取る★。★固定の選択肢を書かないこと★ (★それをやったのが D-053 で消された元のUIです★)GET /customers?group_id=X)ReportsScreen.tsx に前例があります★。★1操作ごとに叩かないこと★apiFetch★(lib/api/client.ts)。★fetch を画面に直書きしない★t() を通す★。★色は CSS 変数★。★新しいCSSに font-family を書かない★★選択肢が取れなかったら、絞り込みUIを出さないこと。★ ★★空の <select> を出すと、D-053 で消した「押しても何も起きないUI」に逆戻りします。★★
★133.125.238.144 は読み取り専用で扱います。★ ★拡張するのは scripts/seed-local-db.ts(ローカルの MySQL 8.4 dwatch_local)です。★
groups 1件("テストグループ001") customers 1件("テスト顧客001") facilities 12件(全部 customer_id=1)
★これでは3階層の絞り込みも、§9-3 の 6-2 / 6-4 も確かめられません。★
| 最低限 | |
|---|---|
groups |
★2件以上★ |
customers |
★4件以上★ — ①グループA傘下 ②グループA傘下(★同一グループ2社目★)③グループB傘下 ④★グループなし★ |
facilities |
★12件を複数の顧客に散らす★ |
customer_summaries |
★顧客ごとに作る★ — ★★これが §9-3 の 6-4(2社で422)を再現する唯一の手段★★ |
facility_error_summaries |
★複数顧客の施設に散らす★(申し送り③の再現) |
group_id = 0 の投入について★★ローカルは MySQL 8.4 で、FK の状況がテストDBと違う可能性があります。★ ★group_id = 0 が入らない場合は、無理に入れようとしないこと★ — ★★TeamWorks へ照会中の項目です(第9回 Q7-4)★★。
★入らなければ「グループなし」の検証は保留★とし、★そう記録すること★。 ★★FK制約を外すなどの回避をしないこと。★★
scripts/seed-local-db.ts の末尾に groups=1 customers=1 ... と★数がハードコード★されています。 ★実際の件数を出すように直すこと★ — ★でないと拡張後に嘘のログが出ます。★
docs/decisions.md★★採番の前に必ず実測すること★★:
grep -nE "^### D-(0|1)[0-9][0-9]" docs/decisions.md | tail -3
★番号順に並んでいません。★ 末尾を見て最大値を判断しないこと。
書くこと:
[破棄] または [一部破棄] の印と行き先を書くこと★★ (D-024 / D-067 / D-135 と同じ作法。★これを忘れると、次の人が「絞り込みを出すな」と読みます★)lib/i18n.ts に集めた理由★(TeamWorks の回答で差し替えるため)group_id = 0 の投入が保留であること★docs/handoff.md に追記group_summaries か「清掃実施回数」カラムが手に入れば合算できる(第9回 6章で照会中)★| # | 落とし穴 | どうなるか |
|---|---|---|
| ★1★ | ★facility_ids を ?.length で分岐する★ |
★「0件ヒット」が「全件表示」に化ける。例外もテスト失敗も出ない★ |
| ★2★ | ★施設名とグループの積集合が空のとき null を返す★ |
同上 |
| ★3★ | ★group_id = 0 を API に漏らす★ |
「グループ0」という存在しないグループが画面に出る |
| ★4★ | ★contract を数値として比較する★ |
★★全施設が「契約なし」になってメニューが全部消えるのに、例外もテスト失敗も出ない★★(D-080) |
| ★5★ | ★customers.contract を読む★ |
★削除依頼済みの列★。facilities.contract が正 |
| ★6★ | ★2社以上のとき静かに1社を選ぶ★ | ★選び間違いに誰も気づけない★(D-133 が明確に否定) |
| ★7★ | ★parseInt の前方一致で 1abc を 1 にする★ |
★過去に実際に踏んだ罠★(D-123) |
| ★8★ | ★既存テスト5本を消す★ | 「無視する」実装に戻っても気づけない |
| ★9★ | ★fixtures 側を notImplemented にする★ |
★USE_FIXTURES=true で画面が落ちる★ |
| ★10★ | ★fixtures を1グループ1顧客のままにする★ | 3階層のUIを fixtures で確かめられない |
| ★11★ | ★空の <select> を出す★ |
★D-053 で消した「押しても何も起きないUI」に逆戻り★ |
| ★12★ | ★D-053 / D-133 に印を付けない★ | ★次の人が古い決定を読んで、実装を「壊れている」と判定する★ |
| ★13★ | ★テストDBに書き込む★ | ★★読み取り専用。絶対にしないこと★★ |
| ★14★ | ★施設ごとにループでクエリを撃つ★ | 施設数ぶんの往復が発生する |
| 項目 | なぜ |
|---|---|
| ★総清掃面積の新画面★ | ★次の指示書★。この絞り込みに乗る |
| ★グループ管理・顧客管理の画面★ | ★docs/spec.md が「実装しない(D-Security側の画面を流用)」と定めている★ |
| ★点検記録の絞り込み★ | ★画面自体が未実装★(D-083) |
| ★複数顧客の合算★ | ★4指標のうち2つを合算する材料がDBに無い★(第9回 6章で照会中) |
| ★200件超の実行計画対策★ | ★測れる見積もりが無い★(第9回 8章で照会中) |
★group_summaries の新設★ |
★TeamWorks の領域★。第9回 6章で照会中 |
★group_id = 0 を入れられるようにすること★ |
★DDLの話。DFAは直せない★(第9回 Q7-4) |
| ★スマートフォン幅のレイアウト★ | 別課題 |