prismaSource 実装前チェックリスト作成: 2026-09-08 根拠: D-074 / D-077 / D-078 / D-079 / ★D-081★ / ★D-082★(docs/decisions.md) 起票のきっかけ: 他メンバーからの申し送り(D-079 項3「実装上の申し送り」)
★B2/B3 が日本語文字列の完全一致で判定している件、重要な指摘です。★ ★実データ接続後に「エラーも出さずに発火しなくなる」は、テストでも気づけないタイプの事故です。
prismaSourceの必須確認項目として確実に残してください。★
★「確実に残す」ことが求められたため、他の文書に埋め込まず独立した文書にしました。★ prismaSource に着手する担当者は、★コードを1行書く前に本文書を通読すること★。
★prismaSource(実DB接続)に着手する前と着手中に、必ず確認することの一覧です。★
★ここに集めてあるのは「型エラーもテスト失敗も出ないまま、実データで静かに壊れる」箇所です。★
tsc は通ります。npm test も緑になります。lint も通ります。それでも壊れます。string のまま合っているので、コンパイラにも fixtures ベースのテストにも見えません。status_1h / status_30m の生成元は lib/fixtures/clean-logs.ts:53-54 の1箇所だけ)。 ★実データ由来の値は、このコードベースを一度も流れたことがありません。★したがって ★「テストが緑だから大丈夫」は本件では成立しません。★ ★実データの値の分布を数えることだけが検証手段です★(→ §C)。
★本文書は「優先度の高低」ではなく「気づけない箇所」を集めたものです★(D-082)。 ★優先度が低いものも載っています。★ 載っている=今すぐ直せ、という意味ではありません。 ★載せる基準は「放置しても例外もテスト失敗も出ないため、忘れると誰も気づけないこと」★ です。 ★したがって、優先度が下がった項目でも本文書からは消さないでください。★
★本文書は「保留質問」も持っています★(→ §H)。 ★第6回の確認書から取り下げた質問を、実データで確認してから聞き直すために預けてあります★(D-081)。 ★取り下げではなく延期です。数えた結果しだいで TeamWorks に送る必要があります。★
★行番号は 2026-09-08 に実測して確認済み★。ファイルを編集したらここも直すこと。
| 箇所 | 何が起きるか | 確認方法 | ||
|---|---|---|---|---|
★lib/judge/advice.ts:80-82(B2)★★優先度: 中(D-082)★ |
★日本語文字列の完全一致で発火★(`status1h === "ハンドルアップ" \ | \ | status30m === "ハンドルアップ")。生値方針(D-077)では DB から日本語は来ないため、★**例外もテスト失敗も出さずに発火しなくなる**★。lib/judge/tests/advice.test.ts:132-146` が★日本語リテラルを直接渡している★ので ★テストは緑のまま★ |
実データの error_type に ★Handrail Lifted★ が実在するかを数える(→ §C-1)。D-078 項2 の暫定値で、★24値の受領リストには含まれていない★。★見つからなかったら §H の保留質問1 を TeamWorks に送る★(D-081 項4)。★優先度は中(D-082)— アドバイスの主軸 R1〜R4 は影響を受けない★(R1 は初回の出発失敗、R2 は単日の完了率×で発火。連続を見るのは R3/R4 だけ。CLAUDE.md §4.5)。★ただし「静かに発火しなくなる」性質は変わらないので、この行を消さないこと★ |
★lib/judge/advice.ts:83-85(B3)★★優先度: 中(D-082)★ |
同上(=== "オフライン")。★B3 は値そのものが未定★。error_type 24値にも robots.status 46値にも該当が無い(D-074 項6 / D-078 項2)。★マッチ文字列は空=発火しないままとする★ |
★オフラインを表す値が DB に存在するかを数える★(→ §C-4)。無ければ「最終報告時刻からの導出」を別途設計する。★それでも判断がつかなければ §H の保留質問2 を送る★。★優先度は中(D-082)— アドバイスの主軸 R1〜R4 は影響を受けない★(連続を見るのは R3/R4 だけ。R1/R2 は単日で発火)。★ただし「静かに発火しなくなる」性質は変わらないので、この行を消さないこと★ | ||
★lib/judge/__tests__/advice.test.ts:132-176★ |
B2/B3 のテストが★日本語リテラルを直接 matchAdviceRules() に渡す★ため、実装が実データで死んでも★永久に緑★。:150-176 の「複数該当」も同じ |
期待値を★設定値経由★に書き換える(D-078 項2 の影響ファイル表)。★リテラルを直接渡すテストを残さないこと★ | ||
★lib/theme-status.ts:5-11★ |
★日本語6文字列の完全一致で色を決め、それ以外は c.txD(グレー)にフォールバック★(:11 の return c.txD)。実データでは ★全部グレーになる★。if の連鎖なので例外も型エラーも出ない |
画面(F-02 清掃詳細ログ / F-03 アラート)を開いて★色が付いているか目視★。全行グレーなら発症している | ||
★components/features/alerts/AlertsScreen.tsx:30-38★ |
★lib/theme-status.ts と同一ロジックの重複2実装★(D-077 項3)。★片方だけ直すと不整合になる★ |
上と同じ。★必ず2箇所そろえて直すこと★ | ||
★lib/types/index.ts:60-61★ |
status_1h / status_30m が ★string★。コメント(:62)に日本語6状態が並ぶだけで、★型としては何でも通る★。生値が入っても ★型エラーは1件も出ない★ |
上流(prismaSource.cleanLogs())が入れる値を決めた時点で、★コメントを実際の値域に直す★ |
||
★lib/reports/query.ts:41-49, 270-278★ |
件数同値時のタイブレークを ERROR_TYPE_ORDER.indexOf() で決めている(:276)。生値では ★全て -1 を返し、-1 - (-1) = 0★ となる。Array.prototype.sort は安定なので例外は出ず、★「定義順で安定させる」が黙って「DB の返却順」に変わる★ |
★件数が同じ error_type が2つ以上あるデータ★で /api/reports/error-breakdown を叩き、★リロードして並びが変わらないか★を確認する。変わるなら安定化キーを生値向けに決め直す(D-077 の影響箇所表) |
||
★components/features/reports/ReportsScreen.tsx:56-64, 440★ |
ERROR_TONE: Record<ErrorType, ...>(:56)を ERROR_TONE[item.type](:440)で引く。生値キーでは ★undefined が ProgressBar の tone に渡る★。ErrorType を string に緩めた時点で ★型エラーも消える★ |
エラー内訳カードの★バーに色が付いているか★を目視。undefined 由来の無色バーが並ぶ |
||
★prisma/schema.prisma:113(facilities.contract)★ ★2026-09-08 に仕様が確定(D-080)。指示書M・D-086でlib/format/contract.tsとして実装済み★ |
★varchar(10) の文字列。桁位置がサービスに対応する★(★1桁目 = D-Security / 2桁目 = D-Watch、契約済みなら 1★。0000000000 = 未設定 / 1100000000 = 両方)。★数値ではない★ — ★CLAUDE.md §4.6 と D-010 の「0/1/2/3」という数値表現が誤りだった★(D-080 で訂正済み)。★数値として比較すると全施設が契約なしになり、メニューが全部消える★。Number("0000000000") は ★例外を出さずに 0★ になり、contract === 3 は絶対に真にならない。★例外もテスト失敗も出ない★(fixtures は monitoring_enabled / d_security_enabled の boolean を直接持つのでテストは緑のまま)。Facility.monitoring_enabled / d_security_enabled(lib/types/index.ts:334-336)への★変換規則はまだ未実装★ |
★SELECT contract, COUNT(*) FROM facilities GROUP BY contract で実際の値を数える★(→ §C-8)。★10桁の文字列が返ることを確認する★。変換関数は ★lib/format/ か lib/config/ の純粋関数1箇所に閉じ込め、桁位置をハードコードしない★(D-080)。★customers.contract は参照禁止★ |
||
★lib/db/index.ts:48★ |
process.env.USE_FIXTURES !== "false" — ★文字列 "false" に完全一致しない限り fixtures のまま★。USE_FIXTURES=0 / False / FALSE / 末尾空白では ★実DB に切り替わらず、しかも何のエラーも出ない★ |
切替後に ★API のレスポンスが fixtures の店舗名(架空)でないこと★ を確認する。または一時的に prismaSource 側へログを1行入れて到達を確認する |
||
★lib/reports/query.ts:332-347(selectKpiRow)★ |
★当期(進行中の週・月)はサマリテーブルに行が無いのが正常★(CLAUDE.md §4.7 / D-023)。現状は当期でも★確定期間でも同じく null を返し、ルート側が空KPIを組み立てる★。実DB接続後、当期を開くと ★エラーも出さずに全項目が空のレポートが出る★ |
★当週・当月を開いて KPI が空になっていないか★を確認する。:339-346 が「詳細テーブルからその場集計」に差し替える分岐点。★器だけ置いてある状態★ |
||
lib/format/period.ts:126(weekOfMonth()) |
月跨ぎ週の帰属ルールを知っている★唯一の箇所★(D-071)。DB のサマリが月境界で分割されていなければ、★週番号がズレた行を無言で拾う★(該当なし=空表示になり、エラーにはならない) | ★月跨ぎ週が2行に分かれて格納されているか★(→ §C-7)と、★week=6 の行が実在するか★(→ §C-5)を数える |
||
prisma/schema.prisma:504-509(clean_schedules.start_time / end_time)★指示書M・D-086で lib/format/schedule.tsのformatEndTime()として実装済み★ |
★HHMM 文字列で、時が 24〜29 を取りうる★(2830 は翌日4:30)。HH:MM として素朴にパースすると ★壊れるが例外は出ず、日付だけ1日ずれる★(D-060) |
実データに★時が 24 以上の行があるか★を数える(SELECT DISTINCT LEFT(end_time,2) FROM clean_schedules) |
||
★prisma/schema.prisma(CleanSchedule.inactive)★★指示書L・D-084で追加。指示書M・D-086で active: row.inactive === 0として実装済み★ |
★論理が反転している★。Int @default(0)で ★0 = 有効★。API/TSはactive: booleanのため、名前の類似からactive: Boolean(row.inactive)と書きたくなるが ★それでは全件反転する★(有効なスケジュールが無効として並ぶ)。正しくはactive: row.inactive === 0。★Boolean(0)がfalseになる分、書いた瞬間にテストが落ちる可能性は高いが、Boolean(row.inactive)ではなく!!row.inactiveのような書き方だと同じ罠に気づきにくい★ |
実データでinactiveの値の分布を数える(SELECT inactive, COUNT(*) FROM clean_schedules GROUP BY inactive)。実装後、fixturesと同じ有効/無効件数比になるか確認する |
||
★DB のweeksカラム(clean_schedules)★★指示書L・D-084で追加。指示書M・D-086で解決済み( row.weeks→weekdaysに明示的にマッピング)★ |
★カラム名がAPI/TSのweekdaysと違う★(DBはweeks、VarChar(7))。単純なspreadでは移せない。★フィールド名の違いに気づかずrow.weekdaysのように書くとundefinedになり、型エラーも出ない可能性がある(Prismaのモデル定義で気づくはずだが念のため)★ |
prismaSource.schedules()実装時、DBの列名(weeks)とAPI/TSのプロパティ名(weekdays)を対応表で確認しながらマッピングする |
||
★Schedule.weekdays_label★★指示書L・D-084で追加。指示書M・D-086で lib/format/schedule.tsのweekdaysLabel()として実装済み★ |
★DBに存在しない。表示用ラベル(「毎日」「月水金」「平日のみ」「土日のみ」「日火木土」)はサーバ側でweeksから生成する必要がある★。DBから素直にselectしただけでは埋まらず、undefinedが画面のスケジュール管理(F-09)の「曜日」列にそのまま出る(型エラーはweekdays_label: stringが必須なら出るはずだが、生成漏れに気づきにくい) |
lib/schedules/query.tsのdocstringに同じ4点の記載あり(指示書L)。実装時はラベル生成関数を1箇所(lib/format/推奨)に閉じ込め、fixturesの5パターン(毎日/月水金/平日のみ/土日のみ/日火木土)と同じ出力になることをテストで固定する |
| ★lib/db/index.ts(prismaSourceから生成済みPrismaクライアントへの新しい参照)★
★★指示書M・D-086で発見。残り10メソッド実装時にも当てはまる★★ | lib/logger/index.tsがUSE_FIXTURES判定のために@/lib/dbをimportしており、lib/loggerはinstrumentation.ts(register()/onRequestError)経由でEdge Runtimeでもコンパイルされる。prismaSourceのメソッドが生成済みPrismaクライアントを動的import(await import("./prisma"))すると、実行されるかどうかに関わらずTurbopackがそのimport先を静的にバンドル対象として解析し、Prismaクライアントが依存するnode:path等のNode組み込みモジュールがEdgeバンドルに引きずり込まれる。★例外もテスト失敗も出ない。USE_FIXTURES=falseでdev serverを起動してもnpm testは全部緑のまま★。実際に発生した症状は/api/reports/*が軒並み404(他のAPIは正常)という★一見無関係な画面が壊れる★形だった | USE_FIXTURES=falseにしてdev serverを再起動し、★実装した画面だけでなく他の全画面・全APIも一通り叩く★こと。ビルドログにA Node.js module is loaded (...) which is not supported in the Edge Runtimeの警告やEcmascript file had an errorが出ていないか確認する。直す場合は、Prismaクライアントに依存するモジュール(lib/db/index.ts本体やlib/db/prisma.ts)をlib/logger等のEdge到達経路から importしないよう分離する(実例: lib/db/use-fixtures.ts) |
★上の表の「静かに壊れる」共通構造★: いずれも ★「文字列が一致しなかったときのフォールバックが正常系に見える」★ (グレーになる / 発火しない / 空になる / 順序が変わる)。★例外を投げる箇所が1つもありません。★ ★ただし直近の発見(Edge Runtimeバンドル破壊)は毛色が違い、「文字列不一致」ではなく 「ビルドの依存グラフに引きずり込まれる」という構造。実行時の値ではなくimport文の到達可能性の 問題なので、fixtures/純粋関数のテストでは原理的に検出できない★。
★接続できたら、実装の前にまずこれを流して分布を記録すること★(D-078 項1「接続後にすぐ確認すべきこと」)。 ★参照用アカウントは SELECT のみなので、これらは全て実行できます★。DB名は clean_watch。
★結果は本文書に追記して残すこと★(次の担当者が同じ調査を繰り返さないため)。
robot_error_reports.error_type の値と件数分布SELECT error_type, COUNT(*) AS cnt FROM robot_error_reports GROUP BY error_type ORDER BY cnt DESC;
docs/handoff/analysis/error-type-mapping.md)と実態が合っているか★Handrail Lifted が実在するか★(★空白入り★。他24値はすべて PascalCase なので ★値の形が1種類ではない可能性がある★。D-078 項2)-- Handrail Lifted の実在確認。前後空白・大小文字ゆれも拾う SELECT error_type, COUNT(*) AS cnt FROM robot_error_reports WHERE REPLACE(LOWER(TRIM(error_type)), ' ', '') LIKE '%handrail%' GROUP BY error_type;
-- 表記ゆれの検出(前後空白・空文字) SELECT COUNT(*) FROM robot_error_reports WHERE error_type <> TRIM(error_type); SELECT COUNT(*) FROM robot_error_reports WHERE TRIM(error_type) = '';
robot_error_reports.error_levelSELECT error_level, COUNT(*) AS cnt FROM robot_error_reports GROUP BY error_level;
Warning / Event が本当に格納されていないか★(D-074 項2。先方の回答は 「ファイルに記録するが DB に格納しない予定」「後から判断するかもしれない」)Fatal / Error の2段階前提SELECT error_level, COUNT(*) FROM facility_error_summaries GROUP BY error_level; SELECT error_type, COUNT(*) FROM facility_error_summaries GROUP BY error_type;
robots.status の値SELECT status, COUNT(*) AS cnt FROM robots GROUP BY status ORDER BY status;
docs/handoff/TeamWorks回答_第2回_20260903.md:53-98。★103 が欠番★で 102 の次が 104)のうち、実際に何が使われているか★ (★起票時に「47件」と数えたのは誤りで実測46件★。D-077 項2 で訂正済み)-200 が実在するか★(Lost Loaction. / LostLocation。★変換はしない★ — D-077 項2)SELECT COUNT(*) FROM robots WHERE status = -200;
SELECT status, clean_status, COUNT(*) FROM section_robot_statuses GROUP BY status, clean_status;
★これが本節で最も重要な問いです★(B3 の発火条件がここで決まる)。
robots.status の46値は ★移動・充電・清掃・帰還の動作フェーズしか表現しておらず、 ハンドルアップも通信断も無い★(第2回回答が自ら明記。:107-108)error_type 24値にも該当なし(D-074 項4)-- 「報告が来ない」状態なので、行が立つのではなく「最終報告からの経過」で見るしかない可能性が高い SELECT r.id, r.serial_number, MAX(cr.created_at) AS last_report FROM robots r LEFT JOIN control_reports cr ON cr.facility_id = r.facility_id GROUP BY r.id, r.serial_number ORDER BY last_report;
lib/config/ の設定値にする★(ハードコード禁止)week = 6 の行があるか(D-071 / 第5回 X-1)SELECT year, month, week, COUNT(*) AS cnt FROM facility_summaries WHERE week > 0 GROUP BY year, month, week ORDER BY year, month, week; SELECT COUNT(*) FROM facility_summaries WHERE week = 6; SELECT MAX(week) FROM facility_summaries;
week の上限は 6 として実装する」で承認済み★(D-074 項3)。 ★指示書H(D-073)の実装はやり直し不要★。★実データで裏を取るのがここ★lib/reports/query.ts:63-64 の WEEK_MIN = 1 / WEEK_MAX = 6 と一致するかweek=0 / month=0 AND week=0 の粒度(第5回 X-2)-- 月次のはずの行 SELECT year, month, COUNT(*) FROM facility_summaries WHERE week = 0 GROUP BY year, month; -- 年次のはずの行 SELECT year, COUNT(*) FROM facility_summaries WHERE month = 0 AND week = 0 GROUP BY year;
week=0 が月次、month=0 AND week=0 が年次★という理解でよいか(D-074 項3 で承認済み)week=0 は予約値。API の week は 1 以上のみ受け付ける★(lib/reports/query.ts:63 の WEEK_MIN を下げないこと)。内部表現としては ★monthly のとき week = 0★(D-072)-- 2026-09-06(日) 6:00 のバッチが 2026/8月第6週 と 2026/9月第1週 の2行を作っているか SELECT year, month, week, facility_id, task_count, clean_area, task_area FROM facility_summaries WHERE year = 2026 AND ((month = 8 AND week = 6) OR (month = 9 AND week = 1)) ORDER BY month, week, facility_id;
lib/format/period.ts:126 の weekOfMonth()(D-071 方式)と帰属がズレる。★その場合は実装ではなく照会に戻ること★facilities.contract の値の分布SELECT contract, COUNT(*) AS cnt FROM facilities GROUP BY contract ORDER BY cnt DESC; SELECT LENGTH(contract), COUNT(*) FROM facilities GROUP BY LENGTH(contract);
VarChar(10) で既定 "0000000000"★(prisma/schema.prisma:113)docs/handoff/analysis/table-definitions-01-master.md:122)。 ★1桁目 = D-Security / 2桁目 = D-Watch、契約済み(有効)なら 1★。 0000000000 = 未設定 / 1000000000 = D-Securityのみ / 0100000000 = D-Watchのみ / 1100000000 = 両方。3桁目以降は予備(★定義書に明記なし。P1では読まない★)CLAUDE.md §4.6 / D-010 にあった「0/1/2/3」という数値表現は誤り★。D-080 で訂正済みcustomers.contract は参照禁止★(削除依頼済み。D-010 / CLAUDE.md §4.6 / §7)-- 最新DDLの反映状況(A-1 / A-3 / B-3b。D-066 で未反映と判明していた3件) -- → prisma db pull の diff を見れば分かる(§D-3) -- clean_schedules の end_time が 24 時以上を取るか(D-060) SELECT DISTINCT LEFT(end_time, 2) AS hh FROM clean_schedules ORDER BY hh; -- 書き込み許可4カラムの現状(更新用アカウント到着後の検証用に、先に分布を取っておく) SELECT status, COUNT(*) FROM robot_error_reports GROUP BY status; SELECT status, COUNT(*) FROM control_error_histories GROUP BY status;
★位置は §C の直後ですが、既存の節番号を変えないため記号は H としました★(A〜G はそのまま)。
★2026-09-08 / D-082 により、本節の優先度は「中」に下がりました★(★B2/B3 は当面「生値をそのまま表示するだけ」とし、実データで値が確定してから直す。アドバイスの主軸 R1〜R4 は影響を受けない★)。★ただし保留質問そのものは維持します — 忘れると誰も気づけないためです。★
★ここにあるのは、第6回の確認書(docs/handoff/TeamWorks確認事項_第6回_20260908.md)から 取り下げた質問です★(D-081)。 ★取り下げたのではなく延期しました。★ 参照用アカウントで実データを数えれば当方で確認できるため第6回から外しましたが、 ★数えた結果しだいでは、あらためて TeamWorks に送る必要があります★。
| # | 実データで確認すること | 見つからなかったら聞くこと |
|---|---|---|
| ★1★ | robot_error_reports.error_type に ★Handrail Lifted★(または類似の値)があるか(→ §C-1) |
★ハンドルアップは error_type のどの値で来るか。error_type に来ないなら、どのテーブル・カラムから判定するか★ |
| 2 | ★オフラインを表す値があるか★(→ §C-4) | ★オフラインはどこから判定するか。最終報告時刻からの導出でよいか(よい場合、しきい値の目安は何分か)★ |
★これが本節の存在理由です。★
GROUP BY の結果)を添えると、 ★先方が「これがそれです」と指せます★lib/config/ の設定値(既定は空=発火しない)★ です(D-078 項2)。 ★空のままでも例外もテスト失敗も出ません。★ ★誰も気づかないまま「アドバイスが出ないのが正常」になります★| 出典 | 内容 |
|---|---|
| ★D-081★ | ★本節の根拠★。第6回から第4部(エラー情報についての確認)を削除し質問を2件に絞った決定。★項4 が保留質問の表★ |
| ★D-082★ | ★B2/B3 は暫定値のまま進め、実データ確定後に修正する★(優先度を中に下げる決定)。★項2 が R1〜R4 の整理★/★項3 が「保留質問と §B の一覧を残し続けること」★/★項5 が修正のタイミング★ |
| D-078 項2 | B2 の暫定マッチ値 Handrail Lifted(★暫定。変更のおそれあり★)。B3 は値未定でマッチ文字列は空のまま |
| D-077 項1 / 項3 | エラー種別は変換せず生値で表示する / B2・B3 が実データで発火しなくなる |
| D-079 項3 | 「質問が少ないほど回答は早く返ります」 |
★接続先(ホスト名・ポート)を受領する★ ★2026-09-08 時点で未受領。これが無いと始まらない★(D-078 項1 の未解決2点のうち1件目)。 .env.local には <HOST> のプレースホルダを入れて待機させてある。 ★第6回の確認書の最優先事項★(docs/handoff/TeamWorks確認事項_第6回_20260908.md)。 ★参照用アカウント自体は受領済み★(GRANT SELECT ON clean_watch.*。DB名 clean_watch。D-078 項1)
.env.local の DATABASE_URL を有効化する ★パスワードに % と @ が含まれるため URL エンコードが必須★(% → %25、@ → %40)。 ★生のままだと Prisma が @ 以降をホスト名と解釈して必ず失敗する★。 ★具体的な値は .env.local のコメントに書いてある。本文書にも他の git 管理下の文書にも書かない★ (CLAUDE.md §9.3「認証情報を絶対にコミットしない」。.env.local は .gitignore:34 の .env* で追跡外)。
.env のみ。.env.local は明示的に読み込む必要がある★(既知の地雷)datasource に url を書けない★(P1012)。接続先は prisma7.config.ts が正npx prisma db pull ★スキーマの取り込みのみ。マイグレーション作成・スキーマ変更は禁止★(CLAUDE.md §7 / D-056)。
db pull はコメントを保持しない★。現行 prisma/schema.prisma には TeamWorks 回答由来の注記が多数入っている(例: :505-508 の HHMM / 24〜29 時の注意)。 ★再 pull したらコミットの diff を見ながらコメントを移植し直すこと★(同ファイル冒頭の注記)schema.prisma は ★2026-09-03 にローカル DB dwatch_ddl(元DDL clean_watch_20260902.sql) に対して pull したもの★。★実DB への pull は初回★npx prisma generate ★lib/generated/prisma は未生成(ディレクトリ自体が存在しない)★(実測。prisma/schema.prisma:3 の output 先)。★接続作業は実質ここから始まる★
datasource.urlだけでは接続できない)。MySQL/MariaDB用は @prisma/adapter-mariadb(@prisma/clientとバージョンを揃える。指示書M・D-086で追加済み)export * from './enums'等)を使う★。 このプロジェクトのtsconfig.jsonのmoduleResolution: "bundler"前提のコードで、素のnodeの ESMローダー(拡張子必須)では解決できない(実測。node --experimental-transform-typesでも 同じERR_MODULE_NOT_FOUND)。単発スクリプトから直接importする場合はtsxを使うこと (npm run seed:localが実例。指示書M・D-086)dwatch_local)を使う場合、dwatch_localは現行prisma/schema.prismaと 一致していない★★(指示書M・D-086で発見): robots.task_id/version、 clean_schedules.started_at/ended_atがdwatch_local側にだけ存在する(余分な列はNULL許容/ 既定値付きなのでINSERTには影響しない)。★dwatch_localに対してdb pull/db push/migrateを 実行しないこと★(前者は実DDLの姿から乖離する。後者は余分な列をDROPしようとする)★§C のクエリを流して分布を記録する★ ★結果を本文書に追記する★。ここで §B の各項目が「発症しているか」が確定する。 ★実装より先にこれをやること★(分布を知らずに書くと、静かに壊れる実装をそのまま作り込む)
lib/db/index.ts の notImplemented() を1つずつ実装する ★まとめて書かない★。1メソッドずつ、§F の表の順(依存の少ない順)で進める。 ★フィルタ・ソート・集計はこの層に持ち込まない★(lib/db/index.ts:51-54 の方針。 ★引数を取らせない契約★ — :65-73)。★判定ロジックは切替の外側★(D-044)
★各メソッドについて、fixtures 版と同じ入力で同じ形の出力が返るかを突き合わせる★
USE_FIXTURES=true / false の両モードで同じ API を叩き、★レスポンスの形(キー・型・ meta の有無)が一致すること★を確認する。★値そのものは一致しない★(データが違う)ので、 ★形と件数の整合★を見るmeta: { total, page, per_page } を返す★(CLAUDE.md §9.3)CLAUDE.md §4.3 / §9.4)selectKpiRow の項を参照GRANT SELECT ON clean_watch.* — 全テーブルの参照)。 ★更新用は後日付与予定★(ユーザー原文「※後で必要なテーブルに更新権限を付与する」)。 ★したがって現時点では書き込み系の実装は検証できない★(D-Sec アラートの対応状況更新、 エラー報告の備考など)。D-078 項1robot_error_reports / control_error_histories の status, comment, responded_at, resolved_at の4カラムのみ★(CLAUDE.md §3 / §7 / D-042)。 ★この4カラム以外への書き込みコードを書かない★(権限エラーになる)prisma db pull で取り込むだけ。CLAUDE.md §7 / D-056)customers.contract の参照禁止★。★facilities.contract を使う★(D-010 / CLAUDE.md §4.6)CLAUDE.md §4.3。判定は★丸める前の生値★で行う)lib/config/ から読む。CLAUDE.md §7 / D-078 項2)robots.status = -200 → LostLocation の変換も行わない。D-077 項2).env.local にのみ置く(CLAUDE.md §9.3)lib/fixtures/ は DB 接続後も削除しない★(テスト・デモ用。CLAUDE.md §9.5)。 ★fixtures の不変条件★: 「有効スケジュールの曜日該当件数=当日の清掃ログ行数」 (lib/fixtures/__tests__/schedules.test.ts)。★スケジュールを1件足すとダッシュボードの 既定表示が異常系になる★★lib/db/index.ts:140-177 の prismaSource を実測★(2026-09-08)。 ★notImplemented() は 12メソッド。DataSource インターフェース(:55-82)の全メソッドが未実装★ (fixtures 版 :86-123 のみが動いている)。
「使われる画面」は ★API ルートから追跡した実測★(grep -rn "db\.<method>" app/ lib/)。
| # | メソッド | lib/db/index.ts |
呼び出している API ルート | 使われる画面 |
|---|---|---|---|---|
| 1 | cleanLogs() |
:141-143 |
app/api/clean-logs/route.ts:39 / app/api/clean-logs/export/route.ts:68 / app/api/clean-logs/[id]/advice/route.ts:41 / app/api/clean-logs/[id]/areas/route.ts:36 / app/api/dashboard/route.ts:57 |
★F-01 ダッシュボード / F-02 清掃詳細ログ★(CSVエクスポート・アドバイス・清掃エリア内訳を含む)。★最も影響が広い★ |
| 2 | prechecks() |
:144-146 |
app/api/prechecks/route.ts:44 |
F-03 アラート(components/features/alerts/AlertsScreen.tsx:73) |
| 3 | dsDevices() |
:147-149 |
app/api/ds-devices/route.ts:42 / app/api/ds-devices/[serial_number]/note/route.ts:80 |
F-06 D-Secログ(備考入力を含む。DsLogScreen.tsx:169, 217) |
| 4 | dsAlerts() |
:150-152 |
app/api/ds-alerts/route.ts:43 / app/api/dashboard/route.ts:59 |
F-07 D-Secアラート / F-01 ダッシュボード |
| 5 | ★facilities()★★★実装済み(指示書M・D-086)★★ |
実装済み | app/api/facilities/route.ts |
F-08 施設ロボットマスタ。指示書MでUSE_FIXTURES=falseでの動作を確認済み |
| 6 | schedules()★★実装済み(指示書M・D-086)★★ |
実装済み | app/api/dashboard/route.ts:58 / app/api/schedules/route.ts |
F-01 ダッシュボード / F-09 スケジュール管理。指示書MでUSE_FIXTURES=falseでの動作を確認済み。§Bのinactive反転・weeksカラム名・weekdays_label生成・end_time24〜29時の4項目は解決済み(lib/format/schedule.ts) |
| 7 | ★inspections()★ |
:159-161 |
★なし★ | ★inspections 画面は PlaceholderScreen★。★点検記録は独自ストア(SQLite + オブジェクトストレージ)でメインDBとは完全分離★(CLAUDE.md §3 / §7)。★そもそも prismaSource で実装すべきものか要確認★。D-031 のスコープは変えない(D-079 項3) |
| 8 | ★inspectionDetail(id)★ |
:162-164 |
★なし★ | 同上。★引数を取る唯一のメソッド★ |
| 9 | reportKpis() |
:165-167 |
app/api/reports/kpi/route.ts:55 |
F-04 レポート(ReportsScreen.tsx:141)。★当期はサマリに行が無い★(§B / selectKpiRow) |
| 10 | facilityPerformance() |
:168-170 |
app/api/reports/facility-performance/route.ts:45 |
F-04 レポート(ReportsScreen.tsx:143) |
| 11 | continuousProblems() |
:171-173 |
app/api/reports/continuous-problems/route.ts:43 |
F-04 レポート(ReportsScreen.tsx:146)。★「連続」はスケジュール存在日の連続★(D-026) |
| 12 | ★errorBreakdown()★ |
:174-176 |
app/api/reports/error-breakdown/route.ts:55 |
F-04 レポート(ReportsScreen.tsx:151)。★生値方針の影響を最も強く受ける★(§B の ERROR_TYPE_ORDER / ERROR_TONE の2項目。D-077 の「変換ロジックはまだ1行も書かれていない=手戻りが最小のタイミング」) |
★実装順の目安★: 5 / 7 / 8 は ★呼び出し元が無いので後回し★。 ★先に 1(cleanLogs)を仕上げること★ — §B の B2/B3・色分けの検証がここで初めて可能になる。
| 記録 | 内容 |
|---|---|
| ★★D-086★★ | ★指示書M(ローカルDBで動かす第1歩)完了記録★。facilities()/schedules()実装・ローカルDBセットアップ手順・Edge Runtimeバンドル破壊の発見と修正・dwatch_localが現行schema.prismaと一致しない事実 |
| ★D-085★ | 指示書M着手前確認2件(devices.maker_id採番=1:PUDU/2:Keenon、施設12スケジュールの構造的除外) |
| ★D-081★ | ★第6回からエラー情報の照会を取り下げ、質問を2件に絞った★ / ★保留質問(→ §H)★ / 「データに出てこないこと」は「存在しないこと」の証明にならない |
| ★D-078★ | 参照用アカウントの受領 / ★接続前に未解決な2点(ホスト名・ポート未受領、パスワードの URL エンコード)★ / ★B2 の暫定マッチ値 Handrail Lifted★ / ★接続後にすぐ確認すべきこと★ |
| ★D-079★ | ★本文書の起票根拠(項3 の実装上の申し送り)★ / プロキシ1段 / resolution_status は2状態化の対象外 |
| ★D-077★ | ★エラーは変換せず DB の生値をそのまま表示する★ / ★B2/B3 が実データで発火しなくなる(項3)★ / 影響箇所の実測表 |
| D-074 | error_type 24値・error_level 4値の受領 / 第5回 X-1〜X-3・Y-3 の承認 / PUDU 公開ドキュメントの実閲覧結果 |
docs/handoff/analysis/error-type-mapping.md |
24値の原文と意味の推測(★参考資料。実装に使わない★)。★§4-2 / §5-4 が本文書 §B の元ネタ★ |
docs/handoff/TeamWorks回答_第2回_20260903.md:53-98 |
robots.status のコード表(★46件。103 が欠番★)。★:107-108 が「画面に出す6状態と一致しない」と自ら明記★ |
docs/handoff/TeamWorks確認事項_第6回_20260908.md |
★接続先(ホスト名・ポート)の依頼を含む最新の確認書★ |
docs/handoff/指示書K_エラー値を変換せず生値で表示する.md |
★段階7-B の Handrail Lifted 実在確認は実データ接続が要る★(D-079 帰結の表) |
CLAUDE.md §3 / §4.3 / §4.6 / §4.7 / §7 / §9.3 / §9.5 |
権限・丸め・契約フラグ・集計期間・禁止事項・コーディング規約・fixtures |