Newer
Older
client_dwatch / docs / handoff / TeamWorks待ちで止まっていること_20260930.md

TeamWorks の回答待ちで止まっていること(2026-09-30 時点)

作成: 2026-09-30 / ブランチ: develop / HEAD: 7fdd822 / 読み手: daichi(DFA)

★本書は調査と文書化だけです。コードは1行も変更していません。★ ★lib/ app/ components/ prisma/ d-watch-api.yaml d-watch-mock.jsx は読んだだけ★。 ★docs/decisions.md docs/handoff.md CLAUDE.md も読んだだけ★。★本番DBには接続していません★(D-148)。

0. 本書の目的と読み方

★「回答が来ないと何が作れず、何が困るのか」を、画面の見え方で書いたもの★です。 抽象的な「〜が確認できません」では催促の主語が決まらないため、★1件ごとに 「いま画面がどう見えているか」「回答が来たら画面がどう変わるか」まで書いています★。

元になっているのは次の3つです。

材料 何が書いてある
docs/handoff/TeamWorks確認事項_第9回_20260915.md(1,197行) ★2026-09-17 に送付した本文★。★質問25問 / お願い5件 / 参考情報1章★
docs/decisions.md D-147(:11950-12000) ★回答待ちの一覧と、それが何をブロックしているかの表★
docs/データの流れ_画面1-5_20260917.md / docs/データの流れ_画面6-10_20260917.md(計3,065行) ★DBの列 → 関数 → 画面の縦線★

0-1. ★★本書に出てくる数字の出所★★(CLAUDE.md §6-6)

表記 意味
★シード由来★ ★本番DB(133.125.238.144 / clean_watch)に入っている★が、★**中身は当方が投入した

ダミー★(scripts/seed-local-db.ts 由来・17テーブル 1,787行。D-145 / D-148)。 ★TeamWorks のバッチや収集処理の挙動を示すものではない★ | | ★構造由来★ | SHOW CREATE TABLE / information_schema / EXPLAIN の type・possible_keys / サーバー変数 / 権限。★行数に左右されない★ | | ★画面実測★ | ★2026-09-17 に監督がブラウザで確認した表示★。★表示されている値の出所はシード由来**★ |

★「本番の実データで測った数字は、本書に1つもありません」★ — ★本番DBにはまだ実データが 入っていないためです★(D-148 項1)。


1. ★★1枚で分かる要約表★★

★困り方は4分類★: ★機能が作れない★(実装に着手できない)/ ★数字が出ない★(画面に出るが 値が欠ける・段差になる)/ ★検証できない★(作れてはいるが正しさを確かめる材料が無い)/ ★期限がある★(過ぎると作り直しになる)。

# 待っている番号 何が止まっているか(★画面で言うと★) 困り方 重さ
★1★ ★Q11-1★(started_at) ★★要レスキュー店舗の4条件目「出発失敗」が存在しない★★。★遅延出発が画面のどこにも出ない★ ★機能が作れない★ ★★大★★
2 Q11-2 / Q11-3 / Q11-4 「指示すら出ていない」と「指示は出たが動かなかった」を区別できない。出発成功率の式が不明。リアルタイム表示の余地が分からない 機能が作れない 中
★3★ ★Q6-1 / Q6-2★(実施回数の列) ★★レポート画面の確定期間KPIは「顧客が1社に定まるとき」しか出ない★★。★2社目が入った瞬間に 422 エラー画面★ ★数字が出ない★ ★★大★★
4 Q2-1 / Q2-3 清掃総面積をサマリから取れない。★1清掃に履歴が2行あると面積が黙って倍になる★ 数字が出ない / 検証できない 中
5 3章(第8回Q4の再掲)/ Q4-1〜Q4-3 ★確定期間と当期でエラー発生率の定義が食い違い、グラフが段差になる恐れ★。検算できない 数字が出ない / 検証できない 中
★6★ ★7章マスタ投入 + Q7-1〜Q7-5★ ★★分類セレクトが5画面すべてで実質「2択」★★(「全ホールディングス / テストグループ001」)。★絞り込みが機能として確かめられていない★ 機能が作れない / 検証できない ★大★
7 Q8-3(報告間隔) control_reports の行数見積もりが ★1,100万行〜7,000万行★ で6倍ぶれる。D-Sログ画面の設計を決められない 検証できない 中
8 Q9-1 / Q9-2 + DDL未反映2件 区域別(売り場・通路・レジ前)の内訳が作れない。★「できない」の一言でも前に進む★ 機能が作れない(小) 小
★9★ ★12章 お願い3件 + Q12-1〜Q12-6★ ★★本番DBが平文・どこからでも接続可のまま★★。★実データが入った後は「止める調整」なしに直せない★ ★★期限がある★★ ★★大★★
★10★ 索引(★依頼は取り下げ済み★) ★★依頼7本のうち本番DBに入っているのは 0本★★(2026-09-17 構造由来)。★清掃詳細ログの2年表示が構造的に全表走査★ 検証できない / 期限がある 中

★内訳★: ★機能が作れない 4件★ / ★数字が出ない 3件★ / ★検証できない 5件★ / ★期限がある 2件★ (★重複あり。項目総数は10件★)。


2. 1件ずつの詳細

★★2-1. Q11-1 — started_at を実際の清掃開始時刻として使ってよいか★★

【いま何が起きているか】

★要レスキュー店舗は3条件でしか判定していません★(lib/judge/rescue.ts:12-21)。

# 条件 実装
R-1 未実施が3日以上連続 ★あり★
R-2 連続問題レベル3(L3) ★あり★
R-3 完了率が前回比20%以上の急落 ★あり★
★R-4★ ★出発失敗(予定時刻+猶予30分を過ぎても出発しない)★ ★★無い★★(lib/judge/rescue.ts:20-22)

コードのコメントがそのまま状況を説明しています(lib/judge/rescue.ts:20-22):

★★4つ目の条件(出発失敗を未実施と別に数える)は落としてある★★ — 実開始時刻がDBに無く、猶予30分の計算をする材料が無いため。

★いま「出発失敗」と呼んでいるものは、実際には「未実施」です★ — 判定は clean_status_histories.clean_error === 1 の1点だけで、時刻を1秒も見ていません (lib/db/clean-log-mapping.ts:105-156)。

★ダッシュボードの要レスキュー店舗は 6件表示★(★画面実測 2026-09-17★。「もっと表示」で 5→6。初期表示5件は lib/config/index.ts:102 の RESCUE_INITIAL_VISIBLE = 5)。 ★この6件は、いずれも「未実施」「L3」「急落」のどれかで拾われたものです★。 ★★「時間どおりに出発しなかった店舗」は、この6件の選出根拠に1件も入っていません★★。

★clean_error の分布(★シード由来。100件の画面実測 2026-09-17★)★: ★0(正常)= 83 / 1(未実施)= 12 / 2(セキュリティ有効)= 1 / 3(D-S制御盤異常)= 2 / 4 = 2★。★null は0件★。 ★つまり「未実施」として拾えているのは12%ぶんだけで、残る83%の中に遅延出発が混ざっていても 見えません★。

【なぜ止まっているか】

★テーブル定義書の clean_status_histories.started_at の備考が 「清掃スケジュールの清掃開始日時を格納する」と書かれており、★予定時刻の写しとも読める★★ (第9回 11-1)。

  • ★prisma/schema.prisma:498 の started_at DateTime @db.DateTime(0) には、それが実時刻か 予定時刻かを示すものが何もありません★
  • ★シードは started_at に予定時刻をそのまま入れていた★ため、★当方のデータで差を取っても 必ず0分になります★(lib/db/report-mapping.ts:213-215)。★シードで検証できない種類の問い★です

★推測で実装すると、失敗が「例外もテスト失敗も出さずに」消えます★ — ★仮に started_at が予定時刻の写しだった場合、「予定+30分を過ぎても started_at が入らない」は 永久に0件になり、画面は「全件が時間どおりに出発した」と表示し続けます★(第9回 11-1)。 ★CLAUDE.md §7「仕様が不明な箇所を推測で実装すること」の禁止に真正面から当たるため、着手していません★。

【回答が来たら何ができるか】

★A(その理解でよい)の一言で足ります★。手順は既に書いてあります(docs/handoff.md:4426-4440)。

  • ★要レスキュー店舗に4条件目が足され、★「予定22:00 / 実際22:47 出発」のように遅れた店舗が リストに乗る★★
  • ★清掃詳細ログの「清掃結果」列で、いまは「正常」に混じっている遅延出発を別扱いにできる★ (lib/clean-logs/csv.ts:103 / lib/config/index.ts:302 の cleanErrorLabel())
  • ★対応アドバイス R1「出発失敗(初回)」(lib/judge/advice.ts:60-63)が、★本来の意味で発火する★★ — 現状の departed は「未実施でない」の意味でしか動いていません

【来ないと何が困るか】

★D-Watch は「夜間に自動実行された清掃を、翌朝DFA運用担当が確認する」運用★です(CLAUDE.md §1)。 ★翌朝の担当者が見落とすのは「動いたけれど遅れた店舗」★です。

  • ★30分遅れて出発した店舗は、完了率が90%以上なら ◎ が付いて正常な店舗と同じ見た目になります★
  • ★遅れの原因(充電が戻っていない / 障害物 / セキュリティ解除の遅れ)は、翌日以降に 「未実施」へ悪化してから初めて画面に出ます★。★★1日遅れて気づく運用になります★★
  • ★R1 は「初回の出発失敗」を捕まえて現場へ連絡するためのルール★(CLAUDE.md §4.5)ですが、 ★初回が見えないので、L2(2日連続)になって初めて気づく★という、エスカレーション設計の 意図と逆の動きになります

2-2. Q11-2 / Q11-3 / Q11-4 — 出発判定の精度とリアルタイム性

【いま何が起きているか】

★「出発失敗」と「未実施」を同じものとして扱っています★(第9回 11-3 に明記して送付済み)。

  • ★Q11-2★: clean_statuses.clean_status_trans が 1(清掃指示)で止まったケース= ★「指示は出したが動き出さなかった」★は、★過去に遡れません★。 clean_statuses は清掃ごとに上書きされ、clean_status_histories にこの列がありません (prisma/schema.prisma:470-506 に clean_status_trans 相当の列が無い)
  • ★Q11-3★: サマリには launch_count / launch_ratio が★実在します★ (prisma/schema.prisma:721 / :734)が、★計算式を受領していません★ (定義書の備考は「補足を参照.」のみで、補足の本文が未受領)
  • ★Q11-4★: 当方は clean_status_histories だけを読んでいます。★より短い間隔で更新される テーブルがあるかを知りません★

【なぜ止まっているか】

★当期(進行中の週・月)のKPIで、★稼働率と出発成功率が同じ分子を使う近似★になっています★ (lib/db/report-mapping.ts:213-225):

★このプロジェクトの清掃詳細データは「出発したか(executed)」の1ビットしか持たない★ (…)そのため 稼働率(実施回数/予定回数)と出発成功率(定刻出発回数/予定回数)は ★同じ executed を分子に使う★。

実装は lib/db/report-mapping.ts:396-405(operationRate(executed, planned) と launchRate(executed, planned) に★同じ2値★を渡している)。

★画面実測(2026-09-17): レポート画面の当期KPIは 稼働率94% / 出発成功率94%★ (★シード由来★)。★この2枚のカードは、当期では構造上必ず同じ値になります★。

【回答が来たら何ができるか】

  • ★Q11-3(式)が来れば★ — ★★確定期間と当期で「出発成功」の定義を揃えられます★★。 ★いまは確定期間が TeamWorks の launch_ratio、当期が当方の近似なので、 週が変わった瞬間にグラフが段差になる可能性があります★
  • ★Q11-2 が「残る」なら★ — 要レスキューの理由を ★「指示が出ていない(制御側の問題)」と「指示は出たが動かない(機体側の問題)」に 割れます★。★翌朝の担当者が、現場に電話するか制御盤を見るかを画面だけで判断できる★
  • ★Q11-4 に候補があれば★ — ★清掃の進捗を「終わってから」ではなく途中で出せます★。 ★無いなら「無い」で確定し、現在の形のまま進めます★

【来ないと何が困るか】

  • ★レポート画面のKPIカード2枚が、当期では必ず同じ数字になる★のに、★画面に説明がありません★ (追記59 §4 #4 でも危険箇所として挙げています)。★見た人は「なぜ同じ?」と思うか、 気づかずに2つの別の指標として読みます★
  • ★確定期間(TeamWorks のサマリ)と当期(当方の近似)の段差は、★バッチが走った翌週の月曜に 初めて現れます★★。★数字が動いた理由が「実態」なのか「定義の違い」なのか、 その場では判別できません★

★★2-3. Q6-1 / Q6-2 — サマリに「清掃実施回数」の列が無い★★

【いま何が起きているか】

★レポート画面の確定期間KPIは、「顧客が1社に定まるとき」しか出ません★。 定まらないときは ★★422 を返して画面にエラーが出ます★★。

決定表は lib/reports/target-customer.ts:20-30 にあります。

入力 結果
customer_id が指定されている その顧客
group_id 指定・傘下1社 その顧客
★group_id 指定・傘下2社以上★ ★★422★★
どちらも未指定・顧客が1社だけ その顧客(★P1 はいまここ★)
★どちらも未指定・顧客が2社以上★ ★★422★★

422 の文言は lib/reports/target-customer.ts:65-66: ★「顧客またはグループを指定してください。複数の顧客のデータを合算した数値は出せません。」★

★いまこれが表に出ていないのは、本番DBに顧客が1行しか無いから★です (★シード由来。customers 1行 / groups 1行★。docs/handoff/規模前提の見直し_20260917.md:57)。 ★★2社目が入った瞬間に、絞り込まずにレポートを開いた全員がこのエラーを見ます★★。

【なぜ止まっているか】

★サマリの列と、当方の4つの計算式(CLAUDE.md §4.2)を突き合わせると2つ足りません★ (prisma/schema.prisma:686-702 / :720-736。★構造由来★)。

率 分子 分母 合算
清掃完了率 clean_area task_area ★できる★
出発成功率 launch_count task_count? ★式が未確認(Q11-3)★
★稼働率★ ★清掃実施回数の列が無い★ task_count? ★★できない★★
★エラー発生率★ error_count ★清掃実施回数の列が無い★ ★★できない★★

★率の平均を取るのは誤り(施設数の違いが消える)★ので、★合算せず 422 で止める★という 設計にしてあります(lib/reports/target-customer.ts:31-33。 ★D-133「静かに1社を選ぶことは絶対にしない」★)。

【回答が来たら何ができるか】

  • ★Q6-2 が A(列を追加できる)なら★ — ★★ホールディングス単位・全社単位のKPIが出せます★★。 ★422 が消え、「全ホールディングス / 全屋号」のままレポートを開いて数字が出ます★
  • ★Q6-1 が A(当方が customer_summaries を合算する)★なら、合算は ★「率の平均」ではなく「Σ分子 ÷ Σ分母」★で実装します(材料が揃えば、という前提)
  • ★C(追加は難しい)なら★ — ★確定期間は清掃完了率と総清掃面積だけを出し、 稼働率とエラー発生率は当期のときだけ表示する形に切り替えます★。 ★決まれば「出ない」ことを画面で説明できます★

【来ないと何が困るか】

  • ★★屋号が増えた日に、レポート画面が突然エラーになります★★。 ★機能追加ではなくマスタ投入が引き金なので、DFA の誰も「変更した」認識がありません★
  • ★ドン・キホーテ1社の中で屋号を分ける(Q7-1 の A)だけでも2社以上になりえます★ — ★7章の回答が先に来ると、こちらが即座に問題になる★という順番の危うさがあります
  • ★★確定期間の数字を検算できません★★ — 率だけがあって分子・分母が無いため、 ★TeamWorks のバッチと当方の当期集計がズレていても、どちらが正しいか言えません★

2-4. Q2-1 / Q2-3 — サマリの面積と、1清掃あたりの履歴行数

【いま何が起きているか】

★清掃総面積の画面は、サマリを使わず clean_status_histories を毎回その場集計しています★ (lib/db/index.ts:1761-1843 の cleanArea())。

★画面実測(2026-09-17): 清掃面積 341,635㎡ / 対象面積 494,000㎡ / 完了率69% / 実施回数538★ (★いずれもシード由来★)。

★同じファイルに「番人」が置いてあります★(lib/db/index.ts:1779-1787):

★1つの clean_timetable_id に履歴が2行以上あると SUM() が同じ清掃を2回数える★。 ★例外もテスト失敗も出ず、数字が大きくなるだけ★なので、件数だけ数えて返します。

★つまり「面積が倍になっても画面は何も言わない」ことが分かっていて、監視だけ置いてある状態★です。

【なぜ止まっているか】

  • ★Q2-1★: サマリの task_area / clean_area が★期間内の合計なのか、1回ぶんの代表値なのか★が 未確認。★合計でなければ、サマリから総面積を作ると黙って間違った数字が出ます★
  • ★Q2-3★: ★1つの clean_timetable_id に clean_status_histories が何行できるか★が未確認。 ★テーブル名(「清掃状態履歴」)は複数行を示唆しますが、状態を表す列が無く1行にも読めます★ (prisma/schema.prisma:470-506)
  • ★シードでは 本清掃538行 : 履歴538行 で 1:1 でした★が、★これは当方が1:1で入れたから★です (docs/handoff/規模前提の見直し_20260917.md:56-57。★シード由来★)。★仕様の証拠になりません★

【回答が来たら何ができるか】

  • ★Q2-3 が A(必ず1行)なら★ — ★SUM() のまま確定でき、番人を「念のため」から 「もう要らない」に落とせます★。★クエリも速くなります★
  • ★Q2-3 が B(複数行)なら★ — ★最新の1行に畳んでから足す実装に差し替えます★。 ★いまの実装は畳んでいないので、実データが B だった場合、★清掃面積が実際の2倍〜3倍で 表示されます★★
  • ★Q2-1 が A(期間内の合計)なら★ — ★確定期間の総面積をサマリから取れるようになり、 索引の無い started_at の全表走査(2-10 参照)を避けられます★

【来ないと何が困るか】

★★総清掃面積は「顧客に見せる数字」になる性質のもの★★です。

  • ★間違っていても、画面は正常に見えます★。★例外も出ず、桁も自然です★
  • ★★気づけるのは「実績報告を受け取った顧客が、自社の店舗面積と照らして違和感を持ったとき」★★ という、★いちばん遅くていちばん痛い気づき方★になります
  • ★いまは番人が件数を返すだけ★(lib/clean-area/anomaly.ts 経由でログに出る)なので、 ★ログを見る人がいなければ誰も気づきません★

2-5. 3章(第8回 Q4 の再掲)/ Q4-1〜Q4-3 — サマリの集計仕様

【いま何が起きているか】

★確定期間のKPIは customer_summaries / facility_summaries の率をそのまま読んでいます★ (lib/db/report-mapping.ts:195-206 の kpiFromSummaryRatios()。呼び出しは lib/db/index.ts:1931 と :2201)。

★★つまり「TeamWorks が何をどう数えたか分からない数字を、そのまま画面に出しています」★★。

★当期のエラー発生回数は、当方が自前で定義しています★(lib/db/report-mapping.ts:226-250):

  • ★本清掃行(precheck = 0)を指す robot_error_reports の件数だけ★(第8回 A7)
  • ★clean_timetable_id が null の行 / dangling の行は含めない★
  • ★clean_error が 2(セキュリティ有効)/ 3(D-S制御盤異常)の清掃は robot_error_reports が作られないため入らない★(第8回 A6-1)

★同じファイルのコメントが帰結を書いています★(lib/db/report-mapping.ts:248-250): ★★「したがって『エラー発生率』は実質『ロボット異常の発生率』になる」★★。

【なぜ止まっているか】

★第8回 A7 の回答が、★「バッチが実際にそうしている」のか「当方への助言」なのか読み取れませんでした★★ (第9回 4章)。★当方は助言として受け取って当期側に実装しましたが、バッチ側が同じとは限りません★。

★3章(第8回 Q4)は「多いので後で回答」という留保のまま★で、★★率の計算式・分子分母の対応・ task_count が予定か実施か★★が全部未確定です。

【回答が来たら何ができるか】

  • ★Q4-1〜Q4-3 が揃えば★ — ★確定期間と当期のエラー発生率が同じ定義だと言えるようになります★。 ★違うなら、当期側を合わせにいけます★(直すのは lib/db/report-mapping.ts の1箇所)
  • ★3章が来れば★ — ★★サマリの数字を検算できるようになります★★。 ★CLAUDE.md §4.7 は「サマリには丸め前の小数と分子・分母が格納される(検算可能にするため)」と 書いていますが、★その検算ができる状態になっていません★★

【来ないと何が困るか】

  • ★★グラフが「段差」になっても、原因を特定できません★★ — ★当期(当方集計)から確定期間(TeamWorks 集計)に切り替わる境目で数字が跳ねたとき、 実態が変わったのか定義が違うのかを、画面からもログからも判別できません★
  • ★事前チェック(precheck = 30 / 60)のエラーがバッチ側に含まれていた場合★ — ★確定期間のエラー発生率だけが当期の2〜3倍になります★。 ★事前チェックは1清掃につき2回走るためです★(clean_timetables の実測比 538 : 253 : 253。★シード由来★)

★★2-6. 7章(マスタ投入)+ Q7-1〜Q7-5 — 分類の実データが無い★★

【いま何が起きているか】

★★分類セレクトが、5画面すべてで実質「2択」です★★(★画面実測 2026-09-17★)。

セレクト 選択肢
ホールディングス ★「全ホールディングス」「テストグループ001」の2つだけ★
屋号 ★「全屋号」「テスト顧客001」の2つだけ★

★選択肢の中身はシード由来★(groups 1行 / customers 1行 / facilities 12行・全行が同じ customer_id。docs/handoff/規模前提の見直し_20260917.md:55-57)。

★この2つのセレクトは、★清掃詳細ログ / アラート / レポート / D-Secログ / D-Secアラート の 5画面が共有しています★★(lib/masters/options.ts:5-8)。 ★★つまり5画面ぶんの絞り込み機能が、実データで一度も動いていません★★。

★★カスケード(ホールディングスを選ぶと屋号が絞られる)も、動いているように見えるだけ★★です — ★1グループ1顧客なので、どちらを選んでも結果が変わりません★。

【なぜ止まっているか】

★構造(groups → customers.group_id → facilities.customer_id)は3階層になっており、 テーブルの追加は要りません★。★足りないのは中身だけ★です。

さらに、★投入する前に決めないといけないことが2つ★あります。

  • ★Q7-1★: customers は★法人(株式会社ドン・キホーテ)★と★屋号(ドン・キホーテ / MEGA / アピタ / ピアゴ)★のどちらの粒度か。★当方は屋号の前提で作っています★
  • ★★Q7-4★★: ★customers.group_id = 0(グループなし)が、★現状のDDLでは投入できません★★。 group_id は NOT NULL DEFAULT 0 で groups(id) への外部キーがあり、 @@foreign_key_checks = 1 / sql_mode に NO_AUTO_VALUE_ON_ZERO が無い(★2026-09-13 構造由来★)。 ★groups に id = 0 の行が要りますが、AUTO_INCREMENT のため入れられません★
  • ★Q7-5★: 「屋号を持たない顧客」が★3階層のどの段が空くという意味か★が未確定。 ★真ん中(屋号)が空く解釈は、facilities.customer_id が NOT NULL なので表現できません★

★当方側のセンチネル処理(0 → null)は既に1箇所に閉じてあります★ (lib/format/group-id.ts:77-79 / lib/db/index.ts:1607 / :1636)。★受け皿はできています★。

【回答が来たら何ができるか】

  • ★マスタが入れば★ — ★★「MEGAドン・キホーテだけの稼働率」「アピタだけのアラート」が 画面で選べるようになります★★。★いまは選択肢が存在しません★
  • ★カスケードの正しさを初めて検証できます★ — ★ホールディングスを切り替えたとき屋号セレクトが 正しく絞られるか / 選択が残ったままにならないか★は、★1グループ1顧客では絶対に再現しません★
  • ★Q7-1 が A(屋号粒度)と確定すれば★ — ★施設マスタ画面のブランド列(lib/db/index.ts:1636-1646)が 意味を持ちます。いまは全行が同じ値です★
  • ★Q7-4 に結論が出れば★ — ★「グループなし」の表示を作るか作らないかを決められます★ (★D(グループなしの顧客は存在しない)なら作りません★)

【来ないと何が困るか】

  • ★★翌朝の運用で、担当者が見たい単位で絞れません★★ — ★「今朝おかしいのはMEGAだけなのか、全屋号なのか」が画面で出せない★
  • ★★実データ投入日が「機能の初日」になります★★ — ★絞り込みの不具合は、実データが入るまで1つも見つかりません★。 ★見つかるのは、運用が始まった後です★
  • ★2-3(Q6-2)と連鎖します★ — ★屋号が2社以上になった瞬間、レポート画面の確定期間KPIが 422 になります★。★マスタ投入が先に来て Q6-2 の回答が後だと、機能が一時的に壊れます★

2-7. Q8-3 — 制御盤の報告間隔

【いま何が起きているか】

★D-Sログ画面は、制御盤ごとの「最終通信時刻」を MAX(reported_at) で取っています★ (lib/db/index.ts:1440。★以前は control_reports を全行取り寄せてJSで1件に切っていた★)。

★reported_at に索引が無いため、EXPLAIN は type=index(フルスキャン)★(★構造由来★)。 ★MAX(id) なら Using index for group-by が効くことも実測済み★ですが、 ★id の順序と reported_at の順序が一致する保証が無い★ため採っていません (lib/db/index.ts:1416-1426)。

★画面実測(2026-09-17): D-Secアラートは5件すべて「通信断」。赤が1色も出ていません★ (★シード由来★)。★通信断はアンバー(components/features/ds-alerts/DsAlertsScreen.tsx:36-38 の typeColor() が disconnected → c.wn)、赤になるのは「セキュリティ無効」だけ★です。

【なぜ止まっているか】

★link_schedules が 0行★(★2026-09-17 実測。docs/handoff/規模前提の見直し_20260917.md:58★) なので、★intervals の実運用値はDBからも取れません★。

★行数の見積もりが6倍ぶれます★(★制御盤11台という当方の置き値での試算★):

報告間隔 2年間の行数
60秒(定義書の例) 約 1,100万行
★10秒(第2回の回答の例)★ ★約 7,000万行★

★ロボット30台という規模の置き直しは、ここには効きません★ — ★control_reports の行数は台数ではなく報告間隔で決まるためです★。

【回答が来たら何ができるか】

  • ★上限・下限が分かれば★ — ★★「最大でどこまで積み上がるか」を押さえて、D-Sログ画面の 作り方(ページング / 期間上限 / 集計テーブルの要否)を決められます★★
  • ★変更の頻度が分かれば★ — ★その前提がいつまで持つかを判断できます★
  • ★索引⑥((control_id, reported_at))を強く依頼すべきかどうかも、ここで決まります★

【来ないと何が困るか】

  • ★★D-Sログ画面が「ある日突然開かなくなる」形の壊れ方をします★★ — ★7,000万行を全表走査するようになれば、タイムアウトするまで画面が返りません★
  • ★★そしてそれは、運用が始まって数か月経ってから起きます★★ — ★いま(control_reports 14行・★シード由来★)は一瞬で返るので、テストで捕まえられません★
  • ★D-Security はセキュリティ解除→清掃→復帰の自動化を監視する画面★です。 ★ここが開けないと、セキュリティが解除されたまま戻っていない状態に気づけません★

2-8. Q9-1 / Q9-2 + DDL未反映2件

【いま何が起きているか】

  • ★Q9-2(区域別内訳)★: 実装できているのは★「1清掃エリア(=1ロボット)につき1つの完了率」★までで、 ★売り場・通路・レジ前といった内訳ではありません★(app/api/clean-logs/[id]/areas/route.ts:1-17)。 ★清掃詳細ログの行を開くモーダルには、エリア単位の行だけが並びます★
  • ★Q9-1(robot_task_reports の表記)★: ★当方は clean_task_reports を1箇所も読んでいません★ (cleanTaskReport の参照 0件。実測)。★影響はありません★
  • ★DDL未反映2件★(★4回目のお願い★): clean_status_histories.id の AUTO_INCREMENT(prisma/schema.prisma:471-474 に 「id は AUTO_INCREMENT ではない。採番はアプリ側」とコメント済み)/ security_status_histories.reported_at の DEFAULT(prisma/schema.prisma:420)

【なぜ止まっているか】

★第8回 A9-2 で「1エリアにつき1つの完了率が取れる」と確定したため、501 の仮実装をやめて 本実装にしました★が、★本来の問い(1回の清掃の中の区域別内訳)は未解決のまま★です (app/api/clean-logs/[id]/areas/route.ts:14-16)。

【回答が来たら何ができるか】

  • ★取れるなら★ — ★モーダルが「売り場 92% / 通路 71% / レジ前 45%」のように割れます★。 ★★翌朝の担当者が「どこに障害物があったか」を画面だけで推測できます★★
  • ★★取れないなら「できない」の一言で十分です★★ — ★機能を諦めて、 docs/decisions.md に「やらない」と記録して閉じられます★。 ★いまは「いつか来るかもしれない」状態で開いたままです★
  • ★DDL2件は、当方の prisma/schema.prisma のコメントを1行消せるだけ★です

【来ないと何が困るか】

★★困り方は小さいですが、「閉じられない」こと自体がコストです★★ — ★引き継ぎのたびに未解決項目として持ち越され、読む人が毎回「これは何だったか」を追い直します★。 ★docs/decisions.md の確認事項#10 は第8回から生き残っています★。


★★2-9. 12章 — お願い3件 + Q12-1〜Q12-6(★期限があります★)★★

【いま何が起きているか】

★本番DB(133.125.238.144 / clean_watch)は、平文で、どこからでも接続できます★ (★2026-09-13 実測。構造由来=サーバー変数と SHOW GRANTS★)。

変数/設定 実測値 意味
have_ssl ★DISABLED★ ★サーバーが TLS を提供していない★
require_secure_transport ★OFF★ ★暗号化されていない接続を受け付ける★
参照用アカウントの接続元 ★参照用アカウント@%★ ★% = どこからでも★

★★この3つが重なると、DB接続の資格情報は必ず経路上に平文で出ます★★。 ★そして経路は公開IP上にあります★。

★★さらに、これは「テスト環境」ではなく 本番DBそのもの です★★(D-148 項1。2026-09-17 ユーザー確認)。 ★当方の文書が長らく「テストDB」と書いてきたのは誤りでした★。

【なぜ止まっているか】

★★解き方が、本番の構成次第で変わるためです★★(第9回 12-6)。

  • ★VM と DB が同一の閉域ネットワークに入れるなら★ → ★TLS も接続元制限も「初めから起きない」★
  • ★公開IP越しに接続する構成なら★ → ★いまの状態がそのまま本番に持ち越されます★

★そして、その構成を当方は確認していません★。 ★D-143 は「サーバー・ネットワークの用意と構築保守は TeamWorks」と書いていますが、 ★TeamWorks 側の明示確認は未取得★です★(CLAUDE.md §2)。 ★Q12-1〜Q12-6 は、まさにそれを確かめる6問です★。

★お願い3件★: ★12-3 接続元IPの制限(最優先)★ / ★12-4 TLS の有効化★ / ★12-5 本番用DBアカウントの新規発行★(★過去に実在のDBユーザー名がコミットに含まれ、 Git 履歴に残っています★)。

【★★期限★★】

★日付ではなく「イベント」で切っています★ — ★★本番に実データが入る前★★。

時点 作り直しのコスト
★いま(ダミーのみ)★ ★★ほぼゼロ★★。アカウントを作り直しても失うものがない
★実データが入った後★ ★★「止める調整」が必要になります★★

★過ぎたら必要になること★:

  1. ★DBアカウントの再発行★ → ★接続している側(当方のアプリ / TeamWorks の収集処理 / 集計バッチ)を★いったん全部止めて★差し替える★
  2. ★TLS の有効化★ → ★サーバ再起動を伴う可能性があり、★夜間の清掃データ収集を止められません★★
  3. ★接続元IPの制限★ → ★実データが流れている状態で絞ると、漏れた接続元から収集が止まります★

★★D-Watch は夜間に自動実行された清掃を翌朝確認する運用★★なので、 ★止められる時間帯が構造的にありません★。

【回答が来たら何ができるか】

  • ★Q12-1〜Q12-6 だけでも先に来れば★ — ★★12-3〜12-5 のお願いの内容を確定できます★★ (★閉域で結べるなら、TLS の依頼は取り下げられます★)
  • ★Q12-1 の回答で、D-143(責任分界)の未確認部分が埋まります★ — ★CLAUDE.md §2 に「TeamWorks 側の明示確認は未取得」と書いてある箇所が消せます★

【来ないと何が困るか】

  • ★★実データが入った後は、直すのに「全部止める」という調整が要ります★★。 ★その調整は、夜間清掃を止めるという意味です★
  • ★★顧客(ドン・キホーテ)の店舗の稼働データが、平文で公開IPを流れます★★
  • ★12-5 は TeamWorks にしか頼めません★ — ★アカウントの発行元が TeamWorks だからです★

★申し添え(D-148 項4)★: ★送付済みの第9回 12-1 は期限を「ステージングに実データが 入る前」と書いています★。★正しくは「本番に実データが入る前」★です。 ★訂正は出さない判断★(D-148 項6 の追記。意図は伝わっているため)ですが、 ★先方が「ステージングの話」と読んで優先度を下げている可能性があります★。 ★催促するときは「本番の話です」と添えるほうが確実です★。


2-10. 索引(★依頼は取り下げ済み。ただし1本も入っていない★)

【いま何が起きているか】

★第9回1章で挙げた7本は、本番DBに1本も入っていません★ (★2026-09-17 実測。information_schema.STATISTICS。構造由来★。 docs/handoff/規模前提の見直し_20260917.md:2-5節)。

★依頼としては取り下げ済み★です(★「ご対応中と伺った」ため。D-144 / 第9回 1-0★)が、 ★★対応完了の連絡も来ていません★★。

★いちばん重いのは①②★(clean_status_histories.clean_timetable_id と robot_error_reports.clean_timetable_id。★索引が1本も無く possible_keys = null★)。 ★これは統計に基づくコスト判断ではなく構造的な全表走査で、行数が増えても索引を選ぶようには なりません★。

★当方のアプリはこの2表を clean_timetable_id IN (…) の形でしか引きません★。 ★IN が1000を超えると1000件ずつに割りますが、★塊ごとに全表走査が起きます★★。

【なぜ止まっているか】

★★索引が入ったかどうかを当方が知る手段が「TeamWorks からの連絡」しかありません★★。 ★EXPLAIN を測り直すこと自体は当方でできます★が、★入る前に測っても意味がなく、 入ったタイミングが分かりません★。

★測り直す項目は12件、既に一覧にしてあります★(docs/handoff/規模前提の見直し_20260917.md:550-590)。

【回答(=完了連絡)が来たら何ができるか】

  • ★EXPLAIN を測り直し、★残っているものがあるかを突き合わせられます★★
  • ★★清掃詳細ログの期間上限(MAX_DATE_RANGE_DAYS = 731)とCSV行数上限 (MAX_CSV_ROWS = 20,000)を、根拠つきで確定できます★★。 ★いまは「規模の前提が変わったので測り直す」と書いたまま保留です★
  • ★control_reports の⑥が入れば、D-Sログ画面の最終通信時刻が type=index から抜けます★

【来ないと何が困るか】

  • ★★劣化は「運用が始まって2年目」に現れます★★ — ★当方のシード(31日ぶん)では絶対に再現しません★
  • ★走査行数は台数と回数に対して二乗で効きます★(★塊の数と1塊あたりの行数が両方とも 比例するため★)。★ロボットが倍になれば走査は4倍★
  • ★索引を足すと TeamWorks 側の書き込みがわずかに遅くなります★ — ★判断は TeamWorks のもの★ですが、★判断した結果(入れた / 入れない)を知らないと、 当方は画面の作り方を決められません★

3. ★★催促するなら、どれを主語にすべきか★★

★「25問まとめて」では動きません★。★主語を1つに絞って、理由と期限を添えるのが効きます★。

★第1優先 — ★★12章(Q12-1〜Q12-6 と、お願い3件)★★★

★理由: これだけが「過ぎると作り直しになる」性質のものだからです★。

  • ★他の9件は、回答が遅れても「作れない / 数字が出ない」で止まるだけで、★後から作れます★★
  • ★12章は、★実データが入った後は「夜間の収集を止める調整」なしには直せません★★
  • ★★聞き方★★: ★「Q12-1〜Q12-6 の YES / NO だけ先に」★と限定する。 ★6問中5問は YES/NO で答えられます★(第9回 12-6)。★お願い3件は、その回答が来てから内容を 組み直すと伝えてあるので、先に6問だけ取りにいくのが筋です★
  • ★★添えるべき一言★★: ★「ステージングではなく本番DBの話です」★ (★送付した本文が「ステージング」と書いてしまっているため。D-148 項4★)

★第2優先 — ★★Q11-1(started_at を使ってよいか)★★★

★理由: A / B の一言で、止まっている機能が1つ動き出すからです★。

  • ★★回答コストが最小で、効果が最大★★ — ★「A. その理解で問題ない」の5文字で、 要レスキューの4条件目が作れます★
  • ★実装手順は既にあります★(docs/handoff.md:4426-4440)
  • ★★聞き方★★: ★「第9回 11章の Q11-1 だけ、A か B かをお教えください」★と、 ★1問だけ切り出す★。★11章の他の3問(Q11-2 / Q11-3 / Q11-4)は「急ぎません」と 本文に書いてあるので、混ぜないほうが答えやすくなります★

★第3優先 — ★★Q6-2(サマリに「清掃実施回数」の列を足せるか)★★★

★理由: 屋号が2社になった瞬間にレポート画面が 422 になるからです★。

  • ★★7章(マスタ投入)が先に来ると、こちらが即座に問題になります★★。 ★順番が逆になると、機能が一時的に壊れた状態で運用が始まります★
  • ★A / B / C の3択で、★C(難しい)でも当方は前に進めます★★(表示を減らす形に切り替える)。 ★「決めてもらえれば、どちらでもよい」と伝えるのが効きます★
  • ★★聞き方★★: ★「7章のマスタ投入より前に、Q6-2 の方針だけ決めさせてください」★と、 ★順番の話として持ち出す★

★第4優先(同時でよい) — ★★7章のマスタ投入(時期の目安だけでも)★★★

  • ★★「入れてください」ではなく「いつ頃になりそうか」を聞くのが効きます★★ — ★当方はそれまで検証用の複数グループ・複数顧客を自前で用意して進められます★
  • ★Q7-4(group_id = 0 が入らない件)は★DDL の矛盾の報告★なので、 ★投入作業の前に必ずぶつかります★。★セットで持ち出すのが自然です★

★待てるもの(急かさない)★

項目 待てる理由
Q11-2 / Q11-3 / Q11-4 ★本文に「急ぎません」と書いて送付済み★。★無ければ現状の形のまま進める、と回答パターンも書いてある★
Q2-1 / Q2-3 ★安全側(B の前提)で実装する方針を本文に書いてある★。★★ただし現在の実装は畳んでいないので、B だった場合の面積は倍になります(2-4 参照)★★
3章 / Q4-1〜Q4-3 ★数字は出ている★。★正しさが確かめられないだけ★
Q8-3 ★いま壊れない★。★積み上がってから効く★
Q9-1 / Q9-2 / DDL2件 ★★「できない」の一言でも前に進む★★。★4回目のお願いだが実害が小さい★
索引 ★依頼は取り下げ済み★。★★催促ではなく「完了しましたらご一報ください」の形★★が筋

★まとめ(1行)★

★★まず 12-6 の6問。次に Q11-1 の1問。この2つだけを、別々に、短く聞く。★★


4. ★TeamWorks 待ちではないのに止まっているもの★(★混同しないため★)

★ここに挙げた3件は、TeamWorks に催促しても動きません★。

4-1. ★PR #6 のレビュー★(★人待ち。DFA 内部★)

  • https://github.com/DFARobotics/d-watch/pull/6(`main` ← develop)
  • ★CI 緑(Lint / Test / Build すべて pass)/ MERGEABLE / CLEAN★
  • ★★残っているのは「レビュアー1名の承認」だけ★★(docs/handoff.md:5236-5240)
  • ★CLAUDE.md §6-5「PRは必ずもう1人がレビューしてから main にマージする」★ が待ちの理由

4-2. ★点検記録(F-05)の未決4件★(★DFA の意思決定待ち★)

★B1「サービスとして出すか」は解決(★出す★。D-150)★。★残る4件★:

# 論点 決まらないとどうなるか
B2 オブジェクトストレージの実体(S3互換 / さくら / VMのローカルディスク) ★実装量が桁で違う★。★ローカルディスクだと写真配信が IP制限の内側に入り、社外から見えない★
B3 誰が用意し、費用を払い、保守するか ★D-143 が名指ししたのは「アプリVM / DB / テスト環境」の3つだけで、ストレージは入っていない★
★B4★ ★点検記録に「点検結果」を持たせるか★ ★★契約にもモックにも項目別の OK/NG もコメント欄も1つも無い★★。★記録できるのは写真と申し送り1本だけで、点検の合否がどこにも残らない★。★後から足すと既存レコードが全部「結果なし」になる★
B5 誰がどこから入力するか(現場スタッフ / DFA運用担当 / スマホ) ★スマホなら、レイアウト新設・IP制限の設計変更・トークン配布の3決定が連鎖する★

★B4 が設計上いちばん重い★(D-150 項2)。★「点検記録」という名前なのに点検の結果が残らない構造★。

4-3. ★4カラムの UPDATE★(★環境待ち。本番DBなので書き込めない★)

  • ★robot_error_reports / control_error_histories の status / comment / responded_at / resolved_at の更新★
  • ★★SHOW GRANTS で UPDATE 権限があることは確認済み★★(2026-09-17。★構造由来★)。 ★それでも実行しません★
  • ★理由: ★接続先が本番DBそのものだから★★(D-148 項5。ユーザー指示 2026-09-17)
  • ★★つまり「権限はあるが、書いてよい環境が無い」★★。 ★書き込みを検証できる環境をどう用意するかは未定のまま★(D-148 項6 の #3)
  • ★これは TeamWorks への質問ではなく、★DFA 側で環境を決める話★です★

5. ★調べていて気づいた、D-147 の記載と実態の食い違い★

★★5-1. 「確定期間の稼働率・エラー発生率が出せない」は、言い過ぎです★★

★D-147 項2 の表★(docs/decisions.md:11979)と★第9回 6-2 の本文★は、次のように書いています。

★確定期間の稼働率とエラー発生率が出せない(分母=実施回数が無い)★ ★「1社であっても確定期間の2つの率が出せませんので、訂正いたします」★(第9回 6-2)

★これは実態と違います★。

事実 出所
★operation_ratio / error_ratio の列は実在します★ prisma/schema.prisma:699-702(customer)/ :733-736(facility)。★構造由来★
★アプリはそれを読んで画面に出しています★ lib/db/report-mapping.ts:195-206(kpiFromSummaryRatios())。呼び出しは lib/db/index.ts:1931 / :2201

★正しくは次の3つです★:

  1. ★合算できない★(複数顧客・ホールディングス単位)— ★率の平均は誤りで、Σ分子÷Σ分母の 材料が無い★。★これが lib/reports/target-customer.ts の 422 の理由★
  2. ★検算できない★ — ★率だけあって分子・分母が無い★
  3. ★式が分からない★ — ★3章(第8回 Q4)が未回答なので、その率が当方の定義と同じか不明★

★送付済みの本文に「訂正いたします」と書いて強めてしまった箇所なので、次回のやり取りで さらに訂正するのは得策ではありません★。★ただし、社内で「確定期間の数字が出ていない」と 誤解したまま設計判断をすると危ないので、本書に記録しておきます★。

5-2. 「サマリ由来の面積を使えない」の書き方

★D-147 項2 は Q2-1 / Q2-3 について「サマリ由来の面積を使えない(現在は clean_status_histories から集計)」★ と書いています。★これは正確★ですが、★★より危ないのは Q2-3 のほう★★です — ★回答が B(複数行できる)だった場合、いまの実装は面積を二重に数えます★ (lib/db/index.ts:1779-1787 が番人を置いているのは、まさにそのため)。 ★D-147 の表からはこの危険度が読み取れません★。

5-3. 索引は「対応中」と聞いたまま、1本も入っていません

★D-147 は「1章(索引)は依頼を取り下げ済み(対応中と伺ったため)」と書いています★。 ★★ただし 2026-09-17 の実測で、7本すべてが未投入でした★★ (docs/handoff/規模前提の見直し_20260917.md:2-5節。★構造由来★)。 ★取り下げた依頼なので催促はできませんが、★「対応中」と「未投入」が2週間以上並走している★ ことは押さえておくべきです★。


6. ★回答が来ても、それだけでは解けないもの★

★催促の期待値を正しく持つために書いておきます★。

# 項目 回答が来ても残ること
★1★ ★Q11-1(started_at)★ ★★A が来ても、「猶予30分」の値そのものは DFA が決める★★。★CLAUDE.md §4.4 は「暫定値。設定値として外出しする」と書いており、実運用の値は未確定★。★30分のままでよいかは、実データの遅延分布を見てからでないと判断できない★
★2★ ★Q6-2(実施回数の列)★ ★A(追加できる)でも、★バッチが再実行されて過去のサマリ行に値が入るまで、確定期間の合算は出せません★★。★既存行の埋め戻しをするかどうかは別の話★
★3★ ★7章(マスタ投入)★ ★投入されても、★当方のダミー1,787行がまだ本番DBに残っています★(D-148 項3)。★TeamWorks が本番前に削除する予定だが、削除された確認が要る★。★削除されると D-141 / D-144 / D-145 の実測記録が全部無効になる★
★4★ ★12章(お願い3件)★ ★★接続元IP制限が入っても、当方側のライブラリの既知問題(TLS を有効にしても条件により資格情報が平文で出る)は残ります★★(第9回 12-3)。★これは DFA 側で解く話★
★5★ ★索引★ ★入っても、★本番の実データ量でしか本当の効果は測れません★★。★D-111 項7(docs/decisions.md:6683-6689)が「テストDBでは判定できない: 本番のデータ量 / サマリバッチの実挙動 / 本番の time_zone 設定」と予告済み★
★6★ ★Q4-1〜Q4-3(error_count)★ ★定義が揃っても、★clean_error が 2 / 3 の清掃は robot_error_reports が作られない★(第8回 A6-1)ため、★「エラー発生率」は実質「ロボット異常の発生率」のまま★★(lib/db/report-mapping.ts:248-250)。★画面のラベルをどうするかは DFA の判断★
★7★ ★全般★ ★★エラー種別は7分類に変換しない方針(D-077 / CLAUDE.md §4.8)なので、画面には EmergencyStop のような英語識別子がそのまま出ます★★。★lib/theme-status.ts の色分けは日本語6文字列の完全一致なので、生値では全部グレーにフォールバックします★。★これは TeamWorks の回答では解けません★

以上。

★本書は決定ではありません★。★決めるのは daichi です★。 ★次に更新するとき★: ★回答を受領したら docs/decisions.md に受領日を記録すること★ (D-147 項3。★送付と受領の両方を記録する作法★ — ★過去に2回、回答済みなのに 「送付待ち」のまま引き継いだ事故があります★)。