日付: 2026-09-30 / 前提: ユーザー指示 2026-09-30、CSV実測189行、本番DB実測
| # | 決定 | 出所 |
|---|---|---|
| 1 | ★確定期間のサマリは *_summaries から取得する。★週・月・年の3粒度★が入る(週=毎週日曜作成 / 月=月初作成) |
ユーザー指示 2026-09-30 |
| 2 | ★直近・昨日の清掃情報は clean_task_reports から取得する★ |
同上 |
| 3 | ★clean_status_histories は使わない(clean_task_reports に一本化)★ |
同上(選択肢の帰結を明示したうえでの選択) |
| 4 | ★清掃完了率は clean_ratio を採用する。面積比(Σclean_area÷Σtask_area)は廃止★ |
同上 |
| 5 | ★clean_timetable_id は今後 TeamWorks が埋める前提で実装する★ |
同上 |
| 6 | ★エラーは robot_error_reports に集約する。ただし実装は TeamWorks の入れ方を確認してから★ |
同上(本指示書の範囲外) |
出所: ★ユーザー提供CSV clean_task_reports.csv 189行★(2026-09-30 受領。本番DBの clean_task_reports は0行なので、当DBからは取得できない)。
| 実測 | 値 |
|---|---|
clean_area > task_area の行 |
★129 / 189(68.3%)★ |
Σclean_area ÷ Σtask_area |
90.2% |
DBの clean_ratio の平均 |
★78.5%★ |
| 個別行の乖離例 | 面積比 13.8% ↔ clean_ratio 100.0% / 面積比 162.8% ↔ clean_ratio 61.0% |
★面積比と clean_ratio は相関しない★。面積比のままでは ★◎(90%以上)が常態化して判定が機能しない★。
clean_task_reports に ★clean_error 相当の列が無い★。代わりに次を正とする。
未実施 = 本清掃の clean_timetables 行に対応する clean_task_reports の行が無い
★これは推測ではなく、現行実装の第1分岐(notExecutedFromHistory() の if (!history) return true)と同じ規則★。 ★「出発失敗」と「未実施」は同一扱いのまま★(ユーザー確認 2026-09-30)。
status の生値を出す★clean_task_reports.status(CSV実測値 ★3 / 4 / 5 / 6★、分布 3:2 / 4:161 / 5:4 / 6:22)は ★定義書に値の説明が無い★(prisma/schema.prisma:520-521 が明記)。
★★推測で CLEAN_ERROR に対応づけないこと★★ — ★D-077 と同じ扱いにする(生値をそのまま表示)★。 CLEAN_ERROR(lib/config/index.ts:231-300)は ★削除しない★(clean_statuses 側で今後使う可能性があるため)。
clean_area / task_area は ★総清掃面積(F-08)では引き続き使う★。 ★使わなくなるのは「完了率の計算に使うこと」だけ★。
clean_task_reports.ended_at は ★nullable★(prisma/schema.prisma:533)。 順序キーは ★ended_at があればそれ、無ければ started_at★ とし、★決める場所は1関数だけ★にする。
| 担当 | 所有ファイル | 内容 |
|---|---|---|
| ★A★ | lib/format/period.ts + lib/format/__tests__/period.test.ts |
年次対応。periodRange / isCurrentPeriod / periodLabel / prevPeriodLabel / shiftPeriod |
| ★B★ | lib/types/index.ts / d-watch-api.yaml / lib/reports/query.ts + そのテスト |
Period に yearly を追加。month=0 / week=0 を年次で許可 |
| ★C★ | lib/db/clean-log-mapping.ts / lib/format/clean-result.ts + そのテスト |
未実施判定(1-1)と清掃結果の生値化(1-2)、順序キー(1-4) |
| ★D★ | lib/db/report-mapping.ts + そのテスト |
periodOfSummaryRow が month を見るように。完了率を clean_ratio ベースに |
| ★E★ | lib/db/consecutive-source.ts / lib/db/clean-area-source.ts + そのテスト |
参照元の差し替え |
| ★F★ | scripts/seed-local-db.ts / lib/fixtures/ |
★clean_task_reports のシードと fixtures を新設★(無いと切替後に全画面0件) |
| 担当 | 所有ファイル | 内容 |
|---|---|---|
| ★G★ | lib/db/index.ts |
8箇所の参照元置換 + 年次除外 filter 3箇所の削除 + :2191 の fail-loud 見直し |
| 担当 | 所有ファイル | 内容 |
|---|---|---|
| ★H★ | components/features/reports/ReportsScreen.tsx |
粒度タブを3つに |
| ★I★ | lib/clean-logs/csv.ts / components/features/detail-log/CleanLogTable.tsx |
清掃結果列の生値化 |
| ★J★ | app/api/**/__tests__/ |
モック形状の追従(176ケース) |
| # | 罠 | なぜ危険か |
|---|---|---|
| 1 | ★clean_timetable_id が nullable★ |
★NULL は IN に一致しない★。行が消えるのではなく ★「未実施」として集計される★(fail-silent)。稼働率・出発成功率が0に落ちる |
| 2 | ★periodOfSummaryRow() が week===0 → monthly だけ見ている★ |
年次除外 filter を消すと ★年次行が「月次」として静かに混入★し、customerSummariesByPeriodKey() が重複検知で ★500★ |
| 3 | ★ended_at が nullable★ |
latestHistoryByTimetableId() は非nullを型で要求している。型ごと直す |
| 4 | ★status の意味は未受領★ |
推測でマッピングしない(1-2) |
| 5 | ★clean_task_reports はローカルDB 0行★ |
★担当F が先にシードを入れないと、他担当は動作確認できない★ |
| 6 | ★年次は month=0 かつ week=0★ |
Month の minimum: 1(d-watch-api.yaml:1491)と MONTH_MIN = 1(lib/reports/query.ts:57)に当たる |
robot_error_reports への集約★ — robot_id が NOT NULL で FK があり、★値を捏造せずに入れる手が無い★。TeamWorks に入れ方を確認してから着手する(決定6)CLAUDE.md §3)| # | 決定 | 理由 | |
|---|---|---|---|
| 5-1 | ★総清掃面積画面(F-08)の completion_rate も clean_ratio 由来にする★。★面積の合計(Σclean_area / Σtask_area)は表示に残す★ |
★同じ「清掃完了率」が画面によって別の式になるのを防ぐ★。面積比のままだと、同じ施設が★レポート画面で78%・F-08で120%★と出うる(CSV実測: 面積比90.2% ↔ clean_ratio 平均78.5%)。複数行の畳み方は★担当Dが lib/db/report-mapping.ts に決めた関数を共用する★(2箇所で別々に畳まない) |
|
| 5-2 | ★API のフィールド CleanLogItem.clean_error を task_status に改名する★。★d-watch-api.yaml を先に直す★(CLAUDE.md §6-1) |
★中身が clean_task_reports.status に変わるのに名前が clean_error のままだと、読み手が旧コード表(0:正常 / 1:未実施 …)で解釈する★。担当Cが関数名を formatCleanTaskStatus に変えたのと同じ理屈(型が同じ `number \ |
null` なので、名前を変えないと直し忘れが型エラーにならない) |
| 5-3 | ★総清掃面積の集計は lib/db/clean-area-source.ts の loadCleanAreaFacilityStats() / countDuplicatedTimetables() を必ず経由する★。lib/db/index.ts に groupBy を直書きしない |
★重複検知の番人に clean_timetable_id IS NOT NULL の除外が入っている★。直書きすると除外が落ち、★NULL が1グループにまとまって毎回偽陽性★になる(担当E 申し送り) |
|
| 5-4 | ★シードは dwatch_local 以外に書けない★ことを確認済み(lib/db/local-guard.ts:19 / scripts/seed-local-db.ts:89) |
★.env.local は本番DB(133.125.238.144)を指している★ため、実行前に必ずガードが効くことを監督が確認した |
| 担当 | 所有ファイル | 内容 |
|---|---|---|
| ★G★ | lib/db/index.ts |
8経路の置換 + 年次除外3箇所の削除 + :2191 の fail-loud 見直し + ★5-3 の関数経由化★ |
| ★K★ | d-watch-api.yaml / lib/types/index.ts |
★5-2 の改名★ + ★型の docstring に残る旧取得元(clean_status_histories)と面積比の定義(5-1)の書き換え★ |
§5-1 は総清掃面積(F-08)だけを名指ししていたが、★理由(同じ「清掃完了率」が画面ごとに別の式になるのを防ぐ)は全画面に当てはまる★。次をすべて ★clean_task_reports.clean_ratio の単純平均(清掃1回=1票。lib/judge/kpi.ts の meanCleanRatio())★ に揃える。
| 画面 / フィールド | 旧 | 新 |
|---|---|---|
レポートKPI completion_rate |
面積比 | ★単純平均★(担当D で済) |
総清掃面積 F-08 completion_rate |
面積比 | ★単純平均★ |
★エリア別完了率モーダル overall_completion_rate★ |
面積比 | ★単純平均★ |
★要レスキュー R-3・RescueRequiredItem.completion_rate★ |
面積加重 | ★単純平均★ |
| 清掃詳細ログ(1行=1清掃) | clean_ratio |
変更なし(平均する対象が1件) |
★面積の合計フィールドは、表示用として残す(完了率の分子・分母ではない)★。
担当L の所有範囲に ★lib/types/index.ts の CleanAreaFacilityStats / CleanAreaRow / CleanAreaTotal / AreaCompletionsResponse / RescueRequiredItem と、d-watch-api.yaml の対応スキーマ★ を追加する(担当K は完了済みなので衝突しない)。