Newer
Older
client_dwatch / docs / handoff / 点検記録_決まっていないこと_20260917.md

点検記録(F-05 / inspections)— 決まっていること / 決まっていないこと

作成日: 2026-09-17 / ブランチ: develop / 種別: 調査。★指示書ではない★


0. この文書の位置づけ

ユーザーの言:「★点検記録はまだ色々決まってないので、指示書は作れない★」。 であれば ★何が決まれば指示書を書けるのか★ を先に確定させる、というのが本書の目的です。

書き方の約束

  • ★すべての「決まっている」に file:line の実測根拠を付けた★。根拠を書けないものは 「決まっていない」側に置いた(CLAUDE.md §6-6 / §7「推測で埋めない」)。
  • ★「たぶんこうだろう」で埋めていない★。資料に無いものは「記述なし(実測)」と書いた。
  • 本書の作成でコードは1行も触っていない。★新規作成したのは本ファイルのみ★。
  • ★本番DB(133.125.238.144)には接続していない★(D-148)。

件数(本書の結論)

区分 件数
★決まっていること★ ★34件★(決定5 / API契約16 / 画面7 / 既存コード6)
★決まっていないこと★ ★35件★
うち ★着手をブロックするもの★ ★5件★
うち ★暫定で進められるもの★ ★30件★
★API契約とモックの食い違い★ ★8件★(うち1件は既に解消)

1. 材料の所在(実測)

材料 場所 中身
API契約 d-watch-api.yaml:1289-1401(パス)/ :2221-2256(スキーマ)/ :59-60(タグ)/ :20-22(データソース注記) 4本のエンドポイントとスキーマ2種
画面モック d-watch-mock.jsx:80(点検7項目)/ :81-89(データ7件)/ :1071-1145(一覧画面)/ :1976-2025(詳細モーダル)/ :2027-2085(新規登録モーダル) 画面の姿
機能一覧 docs/spec.md:16 / :75-81(F-05)/ :128(並走可)/ :215-221(M6) 作るものと順序
決定 docs/decisions.md:38-41(D-004)/ :197-199(D-031)/ :1059-1066(D-072 項7)/ :2182(D-079 項3)/ :2642-2657(D-083 項6)/ :6666-6673(D-111 項6)/ :11359-11380(D-143 項1) なぜ今の状態か
fixtures lib/fixtures/inspections.ts(全157行)/ docs/fixtures.md:233-243(§9) 用意済みのサンプル6件
型 lib/types/index.ts:979-1009 InspectionItemName / InspectionPhoto / InspectionListItem / InspectionDetail
現在の実装 app/(dashboard)/inspections/page.tsx(全5行、PlaceholderScreen)/ components/layout/AppShell.tsx:17-22(メニューのコメントアウト) 画面は空
データ層 lib/db/index.ts:310-311(宣言)/ :521-525(fixtures 実装)/ :1704-1708(prisma は notImplemented) 2メソッドだけ
ログ lib/logger/events.ts:225-232(InspectionLogEvent) 名前空間は確保済み

★要件定義書 P1 / UI仕様書 v6.0 には点検記録の記述が無い★ — D-031(docs/decisions.md:198)が 「モックに存在していたが★要件定義書・画面要件整理シートに記載がなかった★」と明記している。 つまり ★この機能の一次資料はモックと d-watch-api.yaml の2つだけ★で、他画面のように 「UI仕様書に戻って裏を取る」ことができない。★これが本件の不確定性の根本原因★。


2. 決まっていること(34件)

2.1 決定として確定しているもの(5件)

# 決まっていること 根拠
D1 ★点検記録はメインDBに保存しない★。DFA独自ストア(SQLite + オブジェクトストレージ)で管理する docs/decisions.md:38-40(D-004)/ CLAUDE.md §3・§7
D2 ★P1スコープに含む★(モック由来で正式にスコープ入り)。★TeamWorks への確認・依頼は不要★ docs/decisions.md:197-199(D-031)
D3 ★実装順は最後★。他の実装が全部終わってから docs/decisions.md:1059-1066(D-072 項7)/ :6666-6673(D-111 項6)
D4 ★メニューからは一時的に隠す。ルート(page.tsx)と lib/i18n.ts のエントリは残す★。復活はコメント1行を外すだけ docs/decisions.md:2642-2651(D-083 項6)/ components/layout/AppShell.tsx:17-22
D5 ★モックの実在人名・店舗名・申し送り本文は1文字もコピーしない★ docs/decisions.md:2596-2601 / CLAUDE.md §7

2.2 API契約から読み取れること(16件)

★d-watch-api.yaml は「API契約の正」(CLAUDE.md §5)なので、以下は確定として扱ってよい★。

# 決まっていること 根拠
A1 ★エンドポイントは4本★: GET /inspections / POST /inspections / GET /inspections/{id} / DELETE /inspections/{id} d-watch-api.yaml:1290 / :1340 / :1380 / :1393
A2 一覧のクエリは ★date_from date_to customer_id facility_name q page per_page の7つ★ :1297-1321
A3 date_from / date_to は ★訪問日(visited_on)の範囲★ :1300
A4 facility_name は施設名の部分一致。★実装時は includesFoldName を通す(記号・大文字小文字を無視)★ :1308-1313
A5 q は ★記入者名 or シリアル番号★の部分一致。★includesFoldPlain(大文字小文字だけ無視)★ :1317-1319
A6 一覧のレスポンスは ★summary + items + meta★。summary は ★total(記録数)/ facilities(施設ユニーク数)/ with_notes(申し送りあり件数)の3値★ :1330-1339
A7 InspectionListItem は ★8フィールド★(id visited_on inspector_name inspector_company customer_name facility_name serial_number has_notes) :2221-2232
A8 ★「ブランド」列は customer_name。facility → customer 経由で導出する★ :2223 / :2229
A9 InspectionDetail = InspectionListItem + ★notes(nullable)+ photos[]★ :2234-2256
A10 写真1件は ★item_type / phase / url の3フィールド★。item_type は ★英語 enum 7値★(brush dust_box filter squeegee suction_hose waste_tank brush_back)、phase は ★before / after★ :2246-2252
A11 ★未撮影の組み合わせは photos 配列に含めない★(空要素を返さない) :2242
A12 詳細の写真URLは ★署名付き一時URL(有効期限あり)★ :1387 / :2256
A13 登録は ★multipart/form-data★。写真のフィールド名は ★photos[{item_type}][{phase}]★ :1344-1346 / :1351 / :1365-1370
A14 ★必須5項目★: visited_on facility_id robot_id inspector_name inspector_company。★notes と写真は任意★ :1354
A15 ★上限値★: 写真 ★1枚10MB / jpeg・png / 最大14枚★、inspector_name ★100★、inspector_company ★100★、notes ★2000★ :1347 / :1362-1364
A16 ★削除は論理削除(誤登録対応)で 204★。{id} の検証は ★PathId(1以上の整数、0・負値・非整数は422)★ :1393-1401 / :1444-1448(PathId)

補足(契約として確定している周辺事項):

  • ★ロボットは「施設選択後に GET /facilities の robots から選ばせる」★(:1361)。 ★モックの空セレクトを契約側が補っている★。
  • ★認証は cookie 方式(dwatch_session)がグローバルに適用される★(:35-36 の security)。 ★IP制限も proxy.ts が全ルートで判定する★(proxy.ts:112-114 の matcher は 静的ファイル以外すべてを通す)。★点検記録だけを除外する記述は無い(実測)★。

2.3 モックから読み取れる画面の姿(7件)

# 決まっていること 根拠
U1 一覧画面は ★見出し + サマリカード3枚 + フィルタ + 8列の表★ d-watch-mock.jsx:1071-1145
U2 サマリカードは ★総点検数(期間内)/ 点検施設数(ユニーク)/ 申し送りあり(要確認)★ :1097-1110
U3 フィルタは ★日付範囲(from〜to)/ グループ選択 / 会社選択 / フリーテキスト(プレースホルダ「施設名 / 記入者」)★の4つ :1083-1096
U4 表の列は ★訪問日 / 記入者 / 所属会社 / 店舗名 / ブランド / シリアル / 申し送り / 操作★ の8列。申し送りは ★「あり」/「ー」★の2値表示 :1114-1122 / :1134
U5 詳細はモーダル。★上段に記入者・所属会社・ブランド・シリアル、その下に Before / After の2列★、各列に ★7項目★が縦に並ぶ。★申し送りは本文があるときだけ表示★ :1976-2025
U6 新規登録もモーダル。★入力欄は 訪問日 / 店舗 / 記入者氏名 / 所属会社 / ロボット* の5つ+Before/After×7項目の写真アップロード+申し送り事項★ :2027-2085
U7 点検7項目の ★日本語名と並び順★: ブラシ / ダストボックス / フィルター / スクイジー / 吸引ホース / 汚水タンク / ブラシ裏面 d-watch-mock.jsx:80 / docs/spec.md:77 / d-watch-api.yaml:2249

2.4 既存コードとして用意済みのもの(6件)

# 決まっていること 根拠
C1 ★TS型は定義済み★(InspectionItemName / InspectionPhoto / InspectionListItem / InspectionDetail) lib/types/index.ts:979-1009
C2 ★fixtures は用意済み★(6件。写真全14枚 / 一部欠け / なし、申し送り長文 / 空、同一施設の複数回) lib/fixtures/inspections.ts:24-157 / docs/fixtures.md:233-243
C3 DataSource に ★inspections() と inspectionDetail(id) が宣言済み★ lib/db/index.ts:310-311
C4 ★fixturesSource 側は実装済み★(:521-525)、★prismaSource 側は notImplemented()★(:1704-1708) 同上
C5 ★ログイベントの名前空間は確保済み★(inspection.read / inspection.write / inspection.photo。★メインDB系 db.* と分ける★) lib/logger/events.ts:225-232
C6 ★実装するときは最初から Pagination を入れる★(一覧にページ送りを後付けしない) docs/decisions.md:7910 / :7998(D-120 の申し送り)

3. ★決まっていないこと(35件)★ — 本題

観点ごとに「決まっているか / いないか」を1つずつ判定した。 ★「資料に記述なし」は grep の実測結果であり、見落としではなく不存在として扱っている★。

3.1 データの保存先(6件)

# 論点 状態 判定の根拠
★N1★ ★SQLite を本当に使うのか★(採否そのもの) ★未決★ D-004(docs/decisions.md:39)は「SQLite + オブジェクトストレージ」と書くが、★package.json に SQLite ドライバの依存が1つも無い★(better-sqlite3 / sqlite3 / libsql いずれも0件。実測)。Prisma 7 で2つ目のクライアントを立てるのか、better-sqlite3 を直に使うのか、★どちらの記述も無い★
★N2★ ★SQLite ファイルの置き場所★ ★未決★ 記述なし(実測)。★既存の独自ストアは data/settings/*.json★(lib/settings/json-store.ts:8-10)で、★/data は .gitignore:50 に入っている= git のバックアップが無い★。同じ場所に置くのかも未決
★N3★ ★オブジェクトストレージの実体★(さくらのオブジェクトストレージ / 他の S3互換 / VM のローカルディスク) ★未決★ ★grep で「オブジェクトストレージ」は12箇所ヒットするが、すべて「SQLite + オブジェクトストレージ」という同じ1文の引用★。★具体のサービス名は1箇所も無い(実測)★
★N4★ ★バケットの用意・費用・アカウント発行を誰がやるか★ ★未決★ D-143(docs/decisions.md:11366-11373)は「★サーバー・ネットワークの用意と構築保守はすべて TeamWorks★」と確定したが、★対象として挙がっているのは「本番のアプリVM / DB / テスト環境」の3つだけ★。★オブジェクトストレージは名指しされていない★。→ §5 の「実は決まっているかもしれないもの」も参照
★N5★ ★バックアップと復旧★(写真とSQLiteの両方) ★未決★ 記述なし(実測)。★VM の保守は TeamWorks(D-143)だが、DFA独自ストアがバックアップ対象に入るかは書かれていない★
★N6★ ★USE_FIXTURES の切替をこのストアにも適用するか★ ★未決★ CLAUDE.md §9.5 は「APIルートは USE_FIXTURES で fixtures / Prisma を切り替える」と定めるが、★点検記録は Prisma を使わない★。prismaSource.inspections() が notImplemented() のまま(lib/db/index.ts:1704-1708)である現状をどう解消するかが未決 — ★「独自ストアを第3の実装として DataSource に足す」のか「lib/db の外に別系統を作る」のか★。docs/handoff/analysis/prismaSource実装前チェックリスト.md:415 も ★「そもそも prismaSource で実装すべきものか要確認」★と書いている

3.2 写真(9件)

# 論点 状態 判定の根拠
★N7★ 枚数の上限 ★決まっている★ ★最大14枚(Before/After × 7項目)★(d-watch-api.yaml:1347)
★N8★ 1枚あたりのサイズ上限 ★決まっている★ ★10MB★(同上)
★N9★ 形式 ★決まっている(ただし §3.2 の N10 参照)★ ★jpeg / png★(同上)
★N10★ ★HEIC(iPhone の既定形式)をどうするか★ ★未決★ 記述なし(実測)。★現場がスマホで撮るなら必ず当たる★。「弾く」「サーバで変換する」「端末側の設定に任せる」のどれも書かれていない
★N11★ ★1リクエストの合計サイズ★(10MB × 14 = ★最大140MB★を1回の POST で受ける) ★未決★ 記述なし(実測)。Next.js の Route Handler の body サイズ制限、nginx の client_max_body_size のどちらにも触れた記述が無い。★「1枚ずつ送る」設計に変えるかどうかも未決★
★N12★ ★縮小・サムネイル生成をするか★ ★未決★ 記述なし(実測)。★一覧・詳細グリッドで14枚をフル解像度で出すと重い★が、方針の記録が無い
★N13★ ★元画像を保持するか / EXIF(位置情報)を落とすか★ ★未決★ 記述なし(実測)。★lib/logger/redact.ts は個人情報13キーを弾く仕組みを持つが、画像のメタデータは対象外★
★N14★ ★Before / After の対応づけ — 片方だけの登録を許すか★ ★実質未決★ 契約は「★未撮影の組み合わせは配列に含めない★」(:2242)としか書いておらず、★「Before だけ登録して保存してよいか」は書かれていない★。fixtures は片方だけのケースを作ってある(lib/fixtures/inspections.ts:47-56)ので ★許す前提に見えるが、明記は無い★
★N15★ ★署名付きURLの有効期限★ ★未決★ 契約は「有効期限あり」としか書いていない(:1387 / :2256)。★分か時間か日かが無い★。★誰が署名するか(ストレージ側の機能か、アプリが自前で発行して自分で配信するか)も未決★ — 後者なら proxy.ts の IP制限が写真URLにも掛かる(proxy.ts:112-114)

3.3 点検項目(5件)

# 論点 状態 判定の根拠
★N16★ 項目は何か(7項目の名前と順序) ★決まっている★ d-watch-mock.jsx:80 / d-watch-api.yaml:2248-2249 / docs/spec.md:77 の3つが一致
★N17★ ★固定かマスタ化か★ ★未決★ 契約は ★enum(固定)★(:2248)。しかし ★P1 の対応機種は PUDU CC1 のみ★(CLAUDE.md §1)で、★MT1 / Keenon C30・C40 が入ると部位が変わる★(lib/config/index.ts の ROBOT_MODELS。D-087)。★機種が増えたときどうするかの記録が無い★
★N18★ ★チェック式か自由記述か — 「点検結果」を記録する欄が無い★ ★未決★ ★契約にもモックにも、項目ごとの OK/NG・数値・コメントの欄が1つも無い(実測)★。★記録できるのは「写真」と「記録全体に1つの申し送り」だけ★。「点検記録」という名前に対して ★点検の合否がどこにも残らない★
★N19★ ★写真が無い項目の意味★(「未実施」か「異常なし」か) ★未決★ 記述なし(実測)。★N18 が決まらないと決められない★
★N20★ ★消耗品の交換記録を残すか★(ブラシ交換等) ★未決★ 記述なし(実測)。CLAUDE.md §4.5 の L2 が「★消耗品交換★」を想定対応に挙げているが、★点検記録との接続は書かれていない★

3.4 運用(5件)

# 論点 状態 判定の根拠
★N21★ ★誰が入力するか★(現場スタッフ / DFA の訪問担当 / DFA運用担当が代理入力) ★未決★ 記述なし(実測)。★モックの記入者は全件同一人物(d-watch-mock.jsx:82-88)で、所属会社の既定値が DFA Robotics(:2050)★なので ★DFA の訪問者を想定しているように見えるが、明記は無い★。CLAUDE.md §1 の P1 利用者は「★DFA社内のみ★」
★N22★ ★入力端末★(PC / スマホ / タブレット) ★未決★ 記述なし(実測)。★モックはモーダル幅 640px の PC 前提★(:1979)だが、★写真はスマホで撮る★のが自然。★スマホ対応の記述はリポジトリ全体で点検記録には1件も無い★
★N23★ ★社外から入力するか★ ★未決。ただし決めないと詰む★ ★IP制限が全ルートに掛かる★(proxy.ts:112-114 / lib/config/allowed-ips.ts:24-26)。★ALLOWED_IPS は完全一致のみで CIDR 非対応★(lib/config/allowed-ips.ts:14-16)。→ ★現場のモバイル回線から入力させる運用は、いまの認証設計では成立しない★
★N24★ ★オフライン入力が要るか★ ★未決★ 記述なし(実測)。★店舗のバックヤードは電波が弱い★という想定の有無自体が書かれていない
★N25★ ★いつ入力するか★(訪問中 / 帰社後) ★未決★ 記述なし(実測)。N24 と連動

3.5 保持・削除(3件)

# 論点 状態 判定の根拠
★N26★ ★保持期間(何年)★ ★未決★ 記述なし(実測)。★メインDB側は「保持2年」という前提がある★(lib/db/index.ts:176)が、★点検記録に適用するとは書かれていない★。D-004(docs/decisions.md:41)は ★年間8,400枚★という規模想定だけを書いている
★N27★ ★論理削除した記録の写真をどうするか★ ★未決★ 契約は「論理削除」(:1395)とだけ。★ストレージ上の実ファイルを消すのか残すのかが無い★。★InspectionDetail に deleted_at 相当のフィールドも無い★(:2234-2256。実測)
★N28★ ★削除した記録の復元導線★ ★未決★ 記述なし(実測)。論理削除にした以上、★復元できないなら物理削除と運用上同じ★

3.6 認証・権限(3件)

# 論点 状態 判定の根拠
★N29★ ★誰でも登録・削除できてよいか★ ★未決★ ★P1 は共有トークン1本★(d-watch-api.yaml:1406-1414 の cookieAuth)。★ユーザー管理・権限管理は P1 スコープ外★(D-032。docs/decisions.md:201-204)。→ ★ログインできる人は全員、誰の記録でも削除できる★。これでよいかの記録が無い
★N30★ ★記入者名が自己申告のテキストのままでよいか★ ★未決★ inspector_name は ★自由入力の文字列(maxLength 100)★(:1362)。★ログイン主体と紐づける仕組みが無い★(N29 の帰結)
★N31★ ★編集(更新)ができなくてよいか★ ★未決★ ★契約に PUT / PATCH が無い★(:1290-1401。実測)。★モックにも編集ボタンが無い★。「誤ったら削除して再登録」という運用を意図しているように読めるが、★記録が無い★

3.7 施設との紐づけ(2件)

# 論点 状態 判定の根拠
★N32★ ★★表示名(facility_name / customer_name / serial_number)をどう解決するか★★ ★未決。★実装の核心★★ ★保存するのは facility_id / robot_id(:1354)、返すのは名前3つ(:2229-2231)★。★独自ストアとメインDBは別物なので SQL の JOIN ができない★。取りうる案は ★(a) 読み取り時にメインDBを引いて突き合わせる / (b) 登録時に名前をコピーして独自ストアに保存する★ の2つで、★どちらとも書かれていない★
★N33★ ★施設名・シリアルが変わったとき、過去の記録は「当時の値」と「現在の値」のどちらを見せるか★ ★未決★ N32 の (a) なら現在の値、(b) なら当時の値になる。★施設がメインDBから消えたときの表示も未決★

3.8 一覧・検索(2件)

# 論点 状態 判定の根拠
★N34★ ★並び順★ ★未決★ ★契約に sort パラメータも既定順の記述も無い★(:1296-1321。実測)。★モックは配列順に出しているだけ★(d-watch-mock.jsx:1126)
★N35★ ★サマリ3値(total / facilities / with_notes)の集計範囲★ ★未決★ ★フィルタ適用後の全件か、ページング前か、フィルタ無視の全件かが書かれていない★(:1330-1335。実測)。モックは ★フィルタが効かない飾り★なので判断材料にならない

4. ★ユーザーが決めるべき論点の一覧★(1論点1行・帰結つき)

4.1 ★★これが決まらないと1行も書けない(5件)★★

# 論点 ★この選択をするとこうなる★
★B1★ ★そもそも点検記録をサービスとして出すのか★(docs/decisions.md:6670-6671 で「★サービスとして展開するかも保留中です★」とユーザー自身が述べている) ★「出さない」なら以下の全論点が不要になり、AppShell.tsx:22 のコメントアウトを恒久化して終わり★。★「出す」なら B2 以降に進む★。★ここが未決のまま B2 以降を決めると、決め損になる★
★B2★ ★オブジェクトストレージの実体は何か★(さくらのオブジェクトストレージ / 他の S3互換 / VM のローカルディスク) ★S3互換なら★ SDK を1つ足して署名付きURLはストレージ側の機能で済む(★アプリは URL を返すだけ★)。★VM のローカルディスクなら★ ストレージ課金は不要だが ★署名付きURLを自前で実装することになり、写真配信が proxy.ts の IP制限の内側に入る★(=社外からは写真が見えない。N23 と連動)。★どちらでも「写真のURL」という契約(:2256)は守れるが、実装量が桁で違う★
★B3★ ★誰がストレージを用意し、費用を払い、保守するのか★ ★TeamWorks なら★ 第10回の確認事項に1問足すだけで、DFA は使うだけになる(★ただし回答待ちの分だけ着手が遅れる★)。★DFA なら★ 今日から契約して進められるが、★D-143 で確定した「DFA はビューアーのみ」から外れる★ので、責任分界を1件上書きする決定が要る
★B4★ ★点検記録に「点検結果」を持たせるか(N18)★ ★持たせないなら★ いまの契約のまま(写真+申し送りだけ)で書ける。★持たせるなら★ d-watch-api.yaml のスキーマ変更が先(CLAUDE.md §6-1)で、★InspectionDetail に項目別の結果配列が増え、fixtures と型も作り直し★になる。★後から足すと既存レコードが全部「結果なし」になる★
★B5★ ★誰がどこから入力するか(N21 / N22 / N23)★ ★DFA社内のPCからだけなら★ モックのモーダルをそのまま移植でき、IP制限も現行のままでよい。★現場スタッフがスマホから入れるなら★ ①スマホ幅のレイアウトを新規に設計(★モックに無い=「モックが正」の原則から外れる決定が要る★)②IP制限の設計変更(ALLOWED_IPS は完全一致のみで CIDR 非対応。lib/config/allowed-ips.ts:14-16)③共有トークン1本で現場に配るかの判断(N29)— ★3つとも別々の決定になる★

4.2 暫定で進められるもの(30件)— ★決め方の提案付き★

★以下は「決めないと止まる」ではなく「決めずに始めて、後で差し替えられる」もの★。 ★ただし ★印を付けた4件は、後から変えると作り直しになる★。

# 論点 暫定で進める場合の置き方 後から変えると
N1 / N2 SQLite の採否と置き場所 ★data/inspections/ に置き、読み書きを lib/inspections/ の1モジュールに閉じ込める★(lib/settings/json-store.ts と同じ作法) 中で差し替え可
★N15★ 署名付きURLの有効期限 設定値として lib/config/ に外出し(CLAUDE.md §7 の閾値ハードコード禁止と同じ扱い) 設定変更で済む
★N11★ 1リクエスト合計サイズ ★先に「1枚ずつアップロードする」設計にしておくと後で困らない★ ★一括POST前提で作ると作り直し★
N12 / N13 縮小・EXIF 保存時に原本+長辺1600pxの2枚を持つ ★既存写真の再処理が要る★
N10 HEIC 当面は弾いて 422 追加は容易
N14 片方だけの登録 許す(fixtures がそうなっている) —
N17 項目のマスタ化 ★P1 は enum 固定★(契約どおり) ★マスタ化は作り直し★
N19 / N20 写真なしの意味 / 消耗品 B4 に従属。B4 が「持たせない」なら記録しない —
N24 / N25 オフライン / 入力タイミング ★P1 はオンライン前提★ ★オフライン対応は全面的な作り直し★
N26 保持期間 ★メインDB に合わせて2年を暫定値、設定値として外出し★ 設定変更で済む
N27 / N28 削除時の写真 / 復元 論理削除では写真を消さない。復元導線は作らない —
N29 / N30 権限 / 記入者 P1 は共有トークンのまま。inspector_name は自己申告 P2 のユーザー管理と同時
N31 編集機能 ★作らない(削除→再登録)★ ★API 追加が要る★
★N32★ 表示名の解決 ★登録時に名前をコピーして保存する((b)案)★を推す — ★メインDBが読めない場面でも一覧が出る/過去の記録が「当時の店名」で残る★ ★(a)案から(b)案への移行は既存レコードの埋め戻しが要る★
N33 施設の改名・消滅 N32 の帰結として自動的に決まる —
N34 並び順 ★訪問日の降順、同日は id の降順★(他一覧と同じ作法) —
N35 サマリの集計範囲 ★フィルタ適用後・ページング前の全件★(他画面と同じ) —
N5 バックアップ /data ごと VM のバックアップ対象に含めるよう申し送る —
N6 USE_FIXTURES ★DataSource に足さず、lib/inspections/ を独立させる★ 中で差し替え可
N23 社外からの入力 B5 に従属 —
その他 CSVインポート(§6 の M3)/ group_id 絞り込み(M2)/ 写真の見せ方(M6) いずれも ★P1 では作らない★ で進められる —

5. ★実は既に決まっているもの★(ユーザーが「未決」と思っている可能性があるもの)

# 「決まっていない」と思われがちなもの ★実際には決まっている★
1 写真の上限(枚数・サイズ・形式) ★決まっている★ — ★14枚 / 10MB / jpeg・png★(d-watch-api.yaml:1347)。★契約に書いてあるので、変えたければ先に YAML を直す★(CLAUDE.md §6-1)
2 点検項目が何か ★決まっている★ — ★7項目、英語 enum まで確定★(:2248)。★モック・spec・YAML の3つが一致している(実測)★
3 入力欄と必須項目 ★決まっている★ — ★必須5項目★(:1354)。モックの入力欄(d-watch-mock.jsx:2030-2060)と一致
4 削除の方式 ★決まっている★ — ★論理削除★(:1395)
5 文字数上限 ★決まっている★ — 記入者100 / 所属会社100 / 申し送り2000(:1362-1364)
6 メインDBに保存しないこと ★決まっている★ — D-004(docs/decisions.md:38-40)。★CLAUDE.md §7 の禁止事項にも入っている★
7 サンプルデータと型 ★用意済み★ — lib/fixtures/inspections.ts(6件)/ lib/types/index.ts:979-1009。★書き始める段階でここは作らなくていい★
8 メニューの復活方法 ★決まっている★ — components/layout/AppShell.tsx:22 のコメントを外すだけ(D-083 項6)
9 ページ送り ★決まっている★ — ★最初から入れる★(docs/decisions.md:7910 / :7998)
10 ★サーバーの用意と保守★ ★決まっている(ただし射程に注意)★ — ★TeamWorks★(D-143。docs/decisions.md:11366-11373)。★★ただし名指しされているのは「アプリVM / DB / テスト環境」の3つで、オブジェクトストレージは含まれていない★★。→ ★「同じ扱いだろう」と推測せず、論点 B3 として出す★(CLAUDE.md §7)

6. ★API契約とモックの食い違い(8件)★

# 食い違い モック API契約 状態
★M1★ ★写真の項目名★ ★TS型は日本語リテラル★(lib/types/index.ts:979-986 の InspectionItemName、フィールド名は item) ★英語 enum★(d-watch-api.yaml:2246-2249 の item_type) ★★未解決のまま残っている★★ — D-083 項3 #2(docs/decisions.md:2579)と D-084 項11(:2745)が ★「点検記録に着手する前に解決が必要」★と明記。★fixtures も日本語側(lib/fixtures/inspections.ts:24-32)なので、直すと fixtures も型も一緒に動く★
★M2★ ★グループ絞り込み★ ★「全グループ / PPIH」のセレクトがある★(d-watch-mock.jsx:1089-1091) ★group_id パラメータが無い★(:1296-1321。実測。他の一覧11本は持っている) ★契約の抜け。足すなら YAML が先★
★M3★ ★CSVインポート★ ★ボタンがある★(d-watch-mock.jsx:1080)。★ただし onClick が無い飾り★ ★該当エンドポイントが無い★ docs/spec.md:220 は ★「過去のGフォームデータのCSVインポート(任意)」★。★D-083 項4 #3(docs/decisions.md:2592)の前例に従えば「動かないボタンは置かない」=実装しない★
★M4★ ★customer_id が実際には使われていない★ 「全会社」のセレクトがある(:1092-1094) ★契約が自分で「★/inspections の customer_id だけは例外で、まだ絞り込みに使っていない★」と書いている★(d-watch-api.yaml:1452-1454) ★画面が復活したときに足す、と契約自身が指示している★
★M5★ ★ページ送り★ ★無い★(7件を一括描画。:1126) page / per_page あり(:1320-1321) ★契約が正。最初から入れる(C6)★
★M6★ ★写真の見せ方★ ★「📷 写真」は onClick の無い飾り★(:2004)。★押して何が起きるか定義されていない★ 契約は URL を返すだけ(:2253-2256) ★モーダルの中でモーダルを開くのか、サムネイルを並べるのかが未定義★。docs/spec.md:77 は ★「写真グリッド」★と書くが、★モックはグリッドではなく項目名の縦並び★
★M7★ ★ロボット選択★ ★選択肢が空★(「店舗を選択すると表示」。:2057) ★GET /facilities の robots から選ばせる★と明記(:1361) ★契約側が補っている。食い違いではなく補完★
★M8★ ★ブランド列に複数ブランドが出る★ ★ドン・キホーテ / ユニーの2ブランド★(:82-88) — ★P1 の対象顧客はドン・キホーテのみ★(CLAUDE.md §1)。★モックの見た目と実データの見た目が違う★(他画面と同種の既知事項)

★既に解消していたもの★: D-083 項4(docs/decisions.md:2609-2612)が ★YAML の example に実在の人名が残っている★と指摘していたが、 ★現在の d-watch-api.yaml は "点検 太郎" に置換済み★(:1362 / :2227。★grep "香原" d-watch-api.yaml は0件。実測★)。

★契約そのものの抜け(モックとの食い違いではないが、実装時に必ず詰まる)★:

  • ★GET /inspections に 422 の宣言が無い★(:1322-1339)。★他の一覧(例 /schedules の :1287)は宣言している★。 ★customer_id / page / per_page の検証は共通で効くので、宣言だけが漏れている★
  • ★POST /inspections に 413(サイズ超過)の宣言が無い★(:1371-1377)。★10MB の上限を書きながら、超えたときの応答が未定義★
  • ★InspectionDetail に created_at / deleted_at が無い★(:2234-2256)。★論理削除を謳いながら、状態を表すフィールドが応答に無い★

7. ★指示書の見取り図★(決まった場合にどうなるか。骨格のみ)

★どの決定がどの段階をブロックしているか★を示す。★詳細は決まってから書く★。

段階 内容 ★ブロックしている決定★
★段階0★ ★契約の食い違いを先に潰す★ — M1(item_type vs item)、M2 / M4(絞り込み)、422 / 413 / deleted_at の宣言漏れ。★CLAUDE.md §6-1 により YAML が先★ ★B4★(点検結果を持たせるならスキーマが大きく変わるので、B4 の後でないと二度手間)
★段階1★ ★独自ストアの土台★ — lib/inspections/ にスキーマと読み書きを作る。fixtures と型は流用 ★B2 / B3★(置き場所が決まらないと1行目が書けない)、N1 / N2
★段階2★ ★写真の保存と取り出し★ — アップロード受け、保存、署名付きURL発行 ★B2★(実体が S3互換かローカルかで実装が別物)、N11 / N15
★段階3★ ★GET /inspections と GET /inspections/{id}★(読み取り2本) ★N32★(表示名の解決方法)。★N34 / N35 は暫定で進められる★
★段階4★ ★一覧画面★(サマリ3枚 + フィルタ + 8列の表 + ページ送り) ★B5★(PC のみかスマホもか)。★モック移植で足りるのは PC のみの場合だけ★
★段階5★ ★詳細モーダル★(Before/After × 7項目) ★M6★(写真の見せ方)、★B4★(結果欄の有無)
★段階6★ ★POST /inspections(登録)と登録モーダル★ ★B4 / B5 / N11 / N29★
★段階7★ ★DELETE /inspections/{id}(論理削除)★ ★N27 / N29★(写真をどうするか / 誰が消せるか)
★段階8★ ★メニューの復活★(AppShell.tsx:22 のコメントを外す)と docs/architecture.md:68 / :130 の更新 段階4〜7 の完了

★要約★: ★B2(ストレージの実体)と B3(誰が用意するか)が決まれば段階1〜3 は書ける★。 ★B4(点検結果を持たせるか)と B5(誰がどこから入力するか)が決まれば段階0 と段階4〜7 まで書ける★。 ★B1(そもそも出すのか)が No なら、全段階が不要になる★。


8. 本書を書くにあたって触れていないもの(確認用)

  • ★コードは1行も変更していない★(lib/ app/ components/ prisma/ d-watch-api.yaml d-watch-mock.jsx はすべて読み取りのみ)
  • ★docs/decisions.md docs/handoff.md CLAUDE.md docs/spec.md も読み取りのみ★
  • ★他の docs/handoff/*.md に触れていない★
  • ★git のコミット・push・git add を実行していない★
  • ★本番DB(133.125.238.144)に接続していない★(D-148)