状態: ★取り下げ(2026-10-27 同日)★。実装しない。却下した案の記録として残す。
clean_timetable_id のまま★(NULL = 予定外のタスク)、事前チェックかどうかは ★予定の行の precheck 列★で決める。★今のコードがすでにこの作り★なので変更なしclean_timetable_id が入ることが確認できたため(以下は取り下げ前の設計案) 根拠: 監督の実測(ステージング・読み取りのみ・2026-10-27 時点の先方投入ダミー)と、サブエージェント4本の調査。
/api/prechecks・/api/clean-logs)は dynamic / revalidate / use cache なし。Next 16 の Route Handler は既定でキャッシュしない(node_modules/next/dist/docs/01-app/01-getting-started/15-route-handlers.md)lib/api/client.ts の apiFetch は cache 指定なし。応答に max-age / Last-Modified なしlib/db のメモリ上のキャッシュは Prisma の接続だけproxy_cache は未確認(リポジトリに設定が無い)robot_error_reports.clean_timetable_id でつながるエラー行があるか」だけで決まる(lib/db/precheck-mapping.ts statusColumnsFromPrecheckRows)
/api/prechecks)に出るのは、エラー行がある回だけ(と過去の本清掃の出発失敗)lib/db/index.ts の isFutureSchedule)。02:00 の事前チェックの結果は 03:00 の本清掃が始まるまで詳細ログに出ないclean_timetable_id を使っている箇所| 列 | 使い道 |
|---|---|
clean_task_reports.clean_timetable_id |
清掃詳細ログ・CSV・ダッシュボード・清掃エリアの完了率と未実施(cleanLogs() / areaCompletions())、アラートの出発失敗(prechecks() / precheckItemById())、レポート当期KPI・施設別成績、連続日数 L1〜L3、清掃エリア(clean-area-source.ts。重複検知も id の groupBy)。突き合わせは latestReportByTimetableId()(lib/db/clean-log-mapping.ts)に集まるが、レポートを引くクエリ(clean_timetable_id IN (...))は7か所に重複 |
robot_error_reports.clean_timetable_id |
清掃詳細ログの事前チェック列、アラート(事前チェックかどうか・何分前か・親の本清掃)、レポートのエラー率の分子とエラー内訳(本清掃のエラーだけ数える。D-114)、エラー一覧の「紐づく予定」(なし/不明/本清掃/事前チェック) |
clean_task_reports 1行(clean_timetable_id は NULL)。時刻での照合はまだ試せないclean_timetables 1,047行(本清掃 539・事前チェック 60分前 253・30分前 254・10分前 1)
parent_id(本清掃の id)があるrobot_error_reports 49行中48行に clean_timetable_id あり
errored_at が予定の時間帯に入る。うち16件は重なる別の本清掃にも入るが、「開始が直前の予定」を採れば全件が今の id と一致errored_at が事前チェックの時刻ちょうど。下の区間の決め方なら全件が今の id と同じ回に入るlib/judge/)now)で判定するlib/db/time-match.ts)matchEventsToSchedules(schedules, events, policy) → { bySchedule, unmatched }
id / sectionId / startAt / endAt / precheck / parentId(本表と履歴の2表。同じ id は本表を採る。lib/db/timetable-source.ts)started_at、エラーは errored_at ?? created_at(detectedAtFromError() を使う)。清掃エリアは section_idunmatched で返し、ログに出す(黙って捨てない)lib/config の設定(SCHEDULE_TIME_MATCH)に置く: 本清掃の終了後の余裕、開始より前を許すか、レポートを完全一致で照合するか時間帯で照合するかclean_timetable_id が NULL)lib/judge/precheck-state.ts)judgePrecheckSlot({ slotAt, now, evidence, reportsPass, waitMinutes }) → { state, basis, label }
上から順に評価し、最初に当てはまったものを採る(時刻は fromDbJst() で直した値)。
| 順 | 条件 | 状態 | 画面の表示(案) |
|---|---|---|---|
| 1 | 事前チェックの予定行が無い | なし | -(D-171 のまま) |
| 2 | 今 < 回の時刻 | 予定前 | 予定前 |
| 3 | 失敗の記録が1件でもある | 失敗 | エラーの内容(今と同じ) |
| 4 | 成功の記録がある | 成功 | 成功 |
| 5 | 今 < 回の時刻+待ち時間(PRECHECK_RESULT_WAIT_MINUTES) |
結果待ち | 結果待ち |
| 6 | 取得元が成功を記録できない表(robot_error_reports だけ) |
成功(推定) | 異常なし |
| 7 | 取得元が成功を記録できる表なのに記録が無い | 判定不能 | 結果なし |
例(本清掃 03:00、事前チェック 02:00 / 02:30、待ち時間15分、取得元は robot_error_reports):
| 見た時刻 | 1回目(02:00) | 2回目(02:30) |
|---|---|---|
| 01:50 | 予定前 | 予定前 |
| 02:05(エラーはまだ無い) | 結果待ち | 予定前 |
| 02:05(02:01 のエラーが書かれた後) | エラーの内容 | 予定前 |
| 02:40(エラーなし) | 異常なし | 結果待ち |
| 翌朝 | 異常なし/エラーの内容 | 異常なし/エラーの内容 |
lib/dashboard/__tests__/aggregate.test.ts が見張る)lib/prechecks/result-source.ts・lib/db/precheck-sources/)PrecheckResultSource { name; reportsPass: boolean; evidenceForSlots(slots) → Map<slotId, PrecheckEvidence[]> }
PrecheckEvidence = { kind: "fail" | "pass"; at: Date; label: string | null; errorId?: string }robot-error-reports.ts(今すぐ作る。reportsPass = false。section_id と時刻の範囲で引き、§3 で回に振り分ける)fixture.ts(fixtures 用)lib/config の PRECHECK_RESULT_SOURCE を変えるだけで切り替える。複数の表を合わせる combineSources() も用意するprisma/schema.prisma)
robot_error_reports: 失敗だけ。今使えるclean_status_histories: 予定の行ごとに clean_error(0 正常 / 1 未実施 / 2 セキュリティ / 3 制御盤 / 4 ロボット異常)。成功も失敗も取れる最有力候補。ただし CLAUDE.md §4.7 で「読まない」と決めてあり、ステージングは0行(10-01 時点)clean_statuses: 同じ列だが現在値だけ。過去に遡れないrobots.status などの現在値: チェック時点の状態は復元できないので使わないd-watch-api.yaml を先に直す。追加だけ)CleanLogItem に status_1h_result / status_30m_result(upcoming | pending | passed | failed | unknown。status_1h が null のときだけ null)を足す。既存の status_1h の文字列は変えない/prechecks はエラー行が1件の単位で、PATCH の id もエラー)。案: GET /precheck-slots(絞り込みは /prechecks と同じ。1件 = 1回。state・何分前・回の時刻・本清掃の予定時刻・エラーの id 一覧)Cache-Control: no-store を明示する(今もキャッシュされる根拠は無いが、本番の nginx 未確認のための保険)| # | 論点 | 案 |
|---|---|---|
| Q1 | レポートを予定に当てる方法 | 推奨: 時間帯(開始 ≦ started_at ≦ 終了、重なれば開始が直前の予定)/ 開始時刻の完全一致 |
| Q2 | 事前チェックの回の区間 | 推奨: 次の回の手前まで / 回の時刻ちょうどだけ |
| Q3 | 本清掃の終了後のエラー | 推奨: 紐づく予定なし / 直前の本清掃に寄せる |
| Q4 | 結果待ちの時間(PRECHECK_RESULT_WAIT_MINUTES) |
TeamWorks がエラー行を書くまでの遅れ次第。仮に15分 |
| Q5 | アラート画面に出す回 | 失敗と結果待ちだけ / 全部の回(異常なしも) |
| Q6 | エラーしか無い表での「異常なし」の表示 | 「異常なし」と出す / 「エラーなし」など推定と分かる文言 |
errored_at が null、日またぎ(23:30 のチェック → 00:00 の本清掃)、別の清掃エリア、予定外のタスクreportsPass が true で記録なし、遅れて書かれたエラーtime-match.ts、precheck-state.ts、読み口の型、robot_error_reports と fixtures のアダプタ、テストcleanLogs() / areaCompletions() / prechecks() / precheckItemById() / レポート当期 / 連続日数 / 清掃エリア / エラー一覧。7か所に重複しているレポートの取得は1本にまとめるclean_timetable_id で集計していると、当期(時刻照合)と確定期間(id)で数え方が食い違う。照会が要るrobot_error_reports だけでの「異常なし」は推定。データ収集が止まっていると、誤って異常なしに見えるrobot_error_reports.errored_at と clean_task_reports.started_at には索引が無い(section_id の索引に頼る)errored_at が NULL で created_at に頼る行は、TIMESTAMP の時刻ずれが残っていると誤るprecheckItemById() も時刻照合になり、404 になる条件が変わるlib/fixtures/clean-task-reports.ts)の clean_timetable_id が NULL でも予定時刻と同じ started_at の行は、時刻照合では「予定あり」に変わる。テストの期待値の見直しが要る