Newer
Older
client_dwatch / docs / spec.md

spec.md — D-Watch 機能仕様とマイルストーン

本書は「何を作るか(機能一覧)」と「どの順で作るか(開発フェーズ)」の正です。 仕様の詳細は CLAUDE.md(確定仕様)と d-watch-api.yaml(API契約)を参照してください。


1. 画面一覧(全10画面)

# 画面 ID 種別 概要
1 ダッシュボード dashboard 参照 ログイン後の最初の画面。昨夜の清掃結果を10分で把握(★数値カードと表は各清掃エリアの直近の清掃・7日以内。D-159★)
2 清掃詳細ログ detailLog 参照 1行=1ロボット×1スケジュール実行。△×行を展開してアドバイス表示
3 アラート(事前チェック) alert 参照+更新 清掃前の異常検知。対応状況を更新できる
4 レポート report 参照 KPI4指標+前期比、施設別パフォーマンス、連続問題施設、エラー種別内訳
5 点検記録 inspection 参照+登録 現場訪問時のBefore/After写真と申し送り。独自ストア
6 D-Secログ dsecurity 参照 D-S制御盤の稼働状況一覧
7 D-Secアラート dsalert 参照+更新 制御盤の通信断(D-S_CONTROL_FAILURE)の検知。対応状況・備考を更新できる(編集モード。D-180)(種別「セキュリティ無効」はコードに残る — U6 — が DB からは出ない)
8 施設ロボットマスタ robot 参照のみ 施設情報+ロボット情報。登録更新はD-Security側画面
9 スケジュール schedule 参照のみ Pudu Cloud由来の清掃スケジュール
10 システム管理 system 設定 表示設定・運用設定(閾値等)。P1は限定スコープ(下記2.3)

2. 機能仕様

2.1 モニタリング系

F-01 ダッシュボード

  • 数値カード: 成功 / 失敗 / 未実施 / ★結果待ち★ / 成功率(★結果待ちは D-173 で追加。成功率の分母に入れない★)
    • ★母集団は「清掃エリアごとに、予定が終了した本清掃のうち一番新しい1件(7日以内・出発失敗と結果待ちを含む)」★(D-159 / D-173。旧: 当日の日付の清掃。★D-173 以前は「終了+30分(settleMinutes)」を待っていた★)。?date= を指定したときはその日の清掃
    • ★結果待ち★ = 本清掃のレポートが無く、予定の開始 ≤ 今 < 予定の終了+RESULT_WAIT_MINUTES(120分。設定値)。★失敗・未実施に数えない★(D-173)
    • ★スケジュール進捗・要レスキュー・セキュリティバナーは当日のまま★
  • D-Secアラートバナー(セキュリティ無効施設の赤警告)(★DB のデータでは出ない — D-Sec アラートに security_off を作らないため。コードは残す。D-180 項7・U7★)
  • 清掃詳細ログ(コンパクト版。機種・シリアル列を省略)
  • スケジュール進捗(完了数/予定数+プログレスバー)
  • 失敗の内訳(未実施 / セキュリティ有効 / D-S制御盤異常 / ロボット異常)
  • 各ブロックは表示設定でON/OFF可能
  • ★削除済み(deleted_at が NULL でない)の施設・清掃エリアの行は、数値カード・コンパクト版ログ・予定件数・要レスキューのどれにも出さない(D-182)★
  • API: GET /dashboard の1本(★コンパクト版ログはレスポンスの problem_logs。数値カードと同じ母集団の △×(★結果待ちの行は出さない。D-173★)。画面は先頭5件★。D-159 / 指示書AV D7。旧: GET /clean-logs?result=problem を再利用)

F-02 清掃詳細ログ

  • カラム: 施設名 / 機種 / シリアル / 日付 / 予定時刻 / 事前チェック1回目 / 事前チェック2回目 / 出発 / 完了率 / 判定
    • ★事前チェックの2列は分数ではなく順番で割り当てる(早い方が1回目。何分前かはセルの中に出す)★(D-178。旧見出し 1h前ST / 30分前ST)。API は status_1h / status_30m(名前は互換のため据え置き)と status_1h_minutes / status_30m_minutes
    • ★事前チェック1回目 / 2回目は、その回の事前チェックの予定が無いときは「-」★(API は null、CSV は空のセル。予定があって異常なしは "Standby.")。★判定には使わない★(D-171 / D-170)
    • ★結果待ちの行(result_pending。予定の終了から RESULT_WAIT_MINUTES 以内でレポートが無い)は、出発「…」・清掃結果「結果待ち」・判定なしで、行を開けない★。★△×のみ/×のみの絞り込みからは外す★(D-173)
  • フィルタ: 判定(△×のみ=デフォルト / 全件 / ×のみ)、グループ、会社、日付範囲(★最大731日=2年★。★2026-09-15 に31日から拡大。D-136★。★既定は期間を指定しない(全期間)。D-159 追記★)
  • 検索: 施設名・機種・シリアル
  • ★削除済み(deleted_at が NULL でない)の施設・清掃エリアの行は出さない(件数・CSV・行を開いた先も。見えない行の {id} は404。施設名で検索すると0件。D-182)★
  • ★清掃エリアに有効なロボットがいない行は、機種・シリアルが「-」(API は null、CSV は空のセル。D-182)★
  • CSVエクスポート(★日付は年つき(YYYY/MM/DD。D-182)★。★値が無い率は空のセル(D-164)。事前チェックは「事前チェック1回目 / 1回目(分前) / 事前チェック2回目 / 2回目(分前)」の4列で、予定が無い回は空(D-171 / D-178)。結果待ちの行は出発・清掃結果が「結果待ち」、完了率・判定は空(D-173)★)
  • 行展開アドバイス(Phase A): △×行クリックで R1〜R4 の推定原因とアクションを表示
  • エリア別完了率グラフ: ★結果待ちのエリア(result_pending)は問題エリアに数えない(D-182)★。同じ施設・同じ日のエリア(=清掃ロボット)一覧を出す(TeamWorks 第8回 A9-2 で「1エリア=1ロボットにつき1つの完了率」が取得可能と確定。データ元は clean_status_histories)。★1回の清掃の中の区域別内訳(確認事項#10 の本来の問い)は依然として未解決★
  • データ量: ★約30〜45行/日、年間約1.1〜1.6万行★、保持2年(★★いずれも実測ではなく 見積もりです★★)
    • ★根拠★: ★ロボット30台未満(DFA把握。2026-09-17 ユーザー申告)★ × ★1台1日あたり1〜1.5回(★仮置き★)★
    • ★★注意: 1台1日あたりの回数は実測値ではありません★★ — ★2026-09-17 の旧記載は テストDB(133.125.238.144)の clean_timetables WHERE precheck=0 を数えたものだったが、 ★その行は当方(DFA)が scripts/seed-local-db.ts で投入したダミーデータ★だった。 ★本番の清掃回数は不明★。出典: docs/handoff/テストDBのデータ出所_20260917.md
    • ★旧記載「約360行/日、年間約13万行」は施設200件を前提にした外挿★で、実態と大きく違っていた。 ★この数字を根拠にしたコメントが lib/ と app/ に14か所残っている★(★未修正★)。 ★書き換えるときは、新しい数字も「見積もり」であることを明記すること★。 出典: docs/handoff/規模前提の見直し_20260917.md
  • API: GET /clean-logs, /clean-logs/{id}/advice, /clean-logs/unscheduled/{report_id}/advice, /clean-logs/{id}/areas, /clean-logs/export

F-03 アラート(事前チェック)

  • サマリーカウント(未解消 / 解消 / 合計)
  • 種別: 1h前異常 / 30分前異常 / 出発失敗(★結果待ちの清掃は出発失敗に出さない。D-173★)
  • ★本清掃が成功した(親の本清掃が ◎○)事前チェック異常のカードは、薄く表示して「本清掃は成功」の Pill を出す★(main_run_succeeded。★対応状況・未解消の件数は変えない★。D-171)
  • 対応状況: 未解消 / 対応中 / 解消を ★プルダウンで選ぶ★(responded_at / resolved_at を記録)。★D-161。旧: 押すたびに 未解消 → 対応中 → 解消 と巡回するボタン★
  • ★対応状況と備考は「編集モード」でだけ変えられ、「保存」で変えた行をまとめて送る★(即時保存はしない。D-165)
  • フィルタ: 日付範囲、グループ、会社、対応状況(★開始日が終了日より後なら422。D-182★)
  • ★削除済み(deleted_at が NULL でない)の施設・清掃エリアの行は出さない(件数にも数えない。その行への PATCH /prechecks/{id}/status は404。D-182)★。★robot_error_reports.status が 0/1/2 以外の行も出さない(PATCH は404。D-182)★
  • API: GET /prechecks, PATCH /prechecks/{id}/status

F-03 補足 — エラー一覧(/errors)★2026-10-06 追加。番号は振らない★

  • ★robot_error_reports の全行★(ロボット・制御盤・セキュリティ・清掃開始失敗。事前チェックかどうかを問わない)を一覧する。★削除済み(deleted_at が NULL でない)の施設・清掃エリアの行は出さず(件数にも数えない)、その行への PATCH /errors/{error_id}/status は404(U8。D-180 項11)★。既定は未解消・対応中、「解消済みも表示」で解消も(D-160)
  • カラム: 検知時刻 / 施設名 / シリアル / 種類 / レベル / 紐づく予定 / 対応状況 / ★詳細★ / 備考。★種類・レベル・シリアルは DB の値のまま★(区分を作らない。D-077 / D-160 項3)。★エラー内容は「詳細」の列に出す★(未選択 / 詳細 / その他は大分類名 / 選べない行は -。2026-10-27 のユーザー指示で、指示書BE の「種類の2行目」から列に変えた。BE §12・D-185)。編集モードではボタンから窓(キーワード・分類・件数・クリア)で error_list_id を選ぶ。その他(note_required)は備考必須。分類名・詳細は t() に通さない(D-185 / 指示書BE)
  • 対応状況と備考は F-03 と同じ規則(プルダウン・編集モードと保存。responded_at / resolved_at を記録。D-161 / D-165)。★エラー一覧の PATCH だけ error_list_id も書く★(アラートと D-Sec は4カラムのまま。D-184)
  • フィルタ: 日付範囲(検知時刻)、グループ、会社、施設名、種類(部分一致)
  • ★モックに無い画面★。F-03 のアラート画面は事前チェック+出発失敗のまま
  • API: GET /errors, PATCH /errors/{error_id}/status

F-04 レポート

  • 週次/月次トグル(KPIカード・列見出しが「前週比」「前月比」に連動)
  • KPI4列+前期比: 稼働率 / 出発成功率 / 清掃完了率 / エラー発生率
  • 連続問題施設(2日以上連続、上位10件+もっと表示)
  • エラー種別内訳(7分類、件数降順)
  • 施設別パフォーマンス(稼働率ワースト順、上位10件+もっと表示、良好/注意/要改善フィルタ)
  • ★施設別パフォーマンスの CSV エクスポート★(表と同じ条件・同じ並びで、件数の上限なしに全施設。値が無い率は空欄。D-163 / D-164)
  • データソース切替: 確定期間=サマリテーブル / 当期=詳細テーブルからその場集計(API内部で吸収しフロントには見せない)
  • ★削除済みの施設・清掃エリアの行は出さない(当期の集計・連続日数にも入れない。D-182)★。★確定期間はサマリ(TeamWorks の集計値)なので外せる範囲だけ — customer_summaries(KPI)は何も外せず、facility_summaries・facility_error_summaries は施設の削除だけ外す(清掃エリアの削除は施設の値に含まれうる。D-182)★
  • ★その月に無い週(例 2026年9月の第6週)は422。KPI の顧客とグループは AND(傘下でなければ 200・空)。D-182★
  • API: GET /reports/kpi, /reports/facility-performance, /reports/facility-performance/export, /reports/continuous-problems, /reports/error-breakdown

F-05 点検記録 ★独自ストア★

  • 一覧+サマリ(総点検数 / 点検施設数 / 申し送りあり)
  • 詳細: Before/After × 7項目の写真グリッド(ブラシ / ダストボックス / フィルター / スクイジー / 吸引ホース / 汚水タンク / ブラシ裏面)+申し送り事項
  • 新規登録: 訪問日・施設・記入者・所属会社・ロボット+写真アップロード(最大14枚、1枚10MBまで)
  • 削除(論理削除)
  • メインDBとは別のDFA独自ストア(SQLite + オブジェクトストレージ)に保存する
  • API: GET /inspections, GET/DELETE /inspections/{id}, POST /inspections

2.2 D-Security系

F-06 D-Secログ

  • サマリカード(合計 / 正常 / 異常)
  • 一覧: シリアル / 施設名 / 接続状態 / 最終通信 / 備考
  • 備考は編集モード(編集 → 保存(N件)/ キャンセル)で変えた行をまとめて保存(★即時保存はしない★。保存先はファイル data/settings/ds-device-notes.json。D-183)
  • 自動ソート: 異常 → 通信断 → 正常(サーバ側)
  • ★まだ一度も通信が無い制御盤は最終通信「-」(API は null)。controls.status が 0/1 以外の制御盤は出さない(備考の保存も404)。D-182★
  • ステータスフィルタ
  • ※トークン期限/残日数は仕様から除外済み(実装しない)
  • API: GET /ds-devices

F-07 D-Secアラート

  • サマリーカウント(未解消 / 対応中 / 解消済み。★アラート画面と同じラベル。D-181★)
  • 状態の絞り込み: 未解消のみ(★対応中も含む★)/ 全件 / 解消済み(★アラート画面と同じ文言。D-181★)
  • 種別: セキュリティ無効 / 通信断(★DB からは通信断だけ。セレクトは残す — U6★)
  • 対応状況の遷移: 未解消 → 対応中 → 解消(編集モードでまとめて保存。D-161 / D-165)
  • API: GET /ds-alerts, PATCH /errors/{error_id}/status(エラー一覧と同じ書き込み。編集モード。D-180)

2.3 マスタ・設定系

F-08 施設ロボットマスタ(参照のみ)

  • 施設情報(名称 / 都道府県 / 住所 / 電話 / 責任者 / 担当者 / メール)
  • 契約フラグ表示(D-Watch ○/ー、D-Sec ○/ー)← facilities.contract が正
  • ロボット情報(メーカー / 機種 / シリアル)
  • 検索: 施設名 / シリアル / 住所
  • 登録・更新はD-Security側の画面で行うため、D-WatchはGETのみ
  • API: GET /facilities

F-09 スケジュール(参照のみ)

  • シリアル / 施設名 / 曜日 / 開始 / 終了 / 有効
  • Pudu Cloud由来。変更はPudu Cloud管理画面で行う
  • ★削除済みの施設・清掃エリアのスケジュールは出さない。清掃エリアに有効なロボットがいない行のシリアルは「-」(API は null)。D-182★
  • API: GET /schedules

F-10 システム管理(P1限定スコープ)

サブタブ P1での扱い
表示設定 実装する(ダッシュボードの表示項目ON/OFF)。設定ファイル管理
運用設定 実装する(事前チェックのタイミング、完了率閾値、エスカレーション閾値)
通知設定 / 顧客管理 / グループ管理 実装しない(D-Security側の画面を流用)
ユーザー管理 / 権限管理 / 監査ログ スコープ外(ユーザー管理未実装のため。P2以降)

3. 開発フェーズとマイルストーン

P0 環境準備 ──> P1 基盤 ──┬──> P2 コア画面 ──> P3 アラート系 ──> P4 レポート ──> P5 マスタ ──> P7 仕上げ
                          └──> P6 点検記録(独立・並走可)

M0 — 環境準備 P0

ゴール: 2人がコードを書き始められる状態

  • GitHubプライベートリポジトリ作成、Next.js + TypeScript + Prisma 初期化
  • CLAUDE.md / .cursorrules / docs/ 配置
  • lib/fixtures/ のサンプルデータ作成(docs/fixtures.md のケースを網羅)
    • モックJSXの LOG / PRECHK / DSA_INIT / RANK / ROBOTS / SCHED / DSDEV / INSPECTIONS を型付きで移植
    • 実在の店舗名・住所・電話番号をダミー値に置換(バリューマート等)
    • 判定の境界値10ケース、L1〜L3、契約フラグ4パターン、空配列、11件以上を追加
  • lib/db/index.ts に USE_FIXTURES の切替を実装
  • CI(Lint + テスト自動実行)
  • Cursorの Privacy Mode を両名ON(会社コードのため必須)

依存: なし(今すぐ着手可) 担当: 環境


M1 — 基盤 P1

ゴール: 全画面が乗る土台と、絶対に間違えられない判定ロジックの完成

  • 共通レイアウト(サイドバー10画面ナビ、ダーク/ライト、JP/EN切替の器。★選んだ値はブラウザに保存し、再読み込み・再ログインのあとも保つ(D-183)★)
  • API共通実装(★認証(proxy.ts + cookie + IP制限。指示書I / D-101)★、エラー形式、ページネーション)
  • 判定ロジック + 期待値表テスト ★最重要・先行実装★
    • ◎○△×判定(境界値: 90.0 / 90.1 / 70.0 / 10.0 / 未実施)
    • L1〜L3エスカレーション(スケジュール存在日の連続カウント)
    • KPI4指標の計算式
    • 整数丸め(判定は生値、表示は丸め値)
  • Prisma接続とスキーマ取り込み(db pull)、テーブル定義書との突き合わせ
    • 取り込みと突き合わせだけ早めに実施する(カラム名の食い違いが後から見つかると全画面に波及するため)
    • 画面開発は引き続き fixture で進める

依存: スキーマ取り込みのみステージングDB待ち。判定ロジック・画面開発はfixtureで先行可 担当: 両名(判定ロジックは特に慎重に)


M2 — コア画面 P2

ゴール: 毎朝の運用(STEP1〜2)が回る

  • ダッシュボード(F-01)
  • 清掃詳細ログ(F-02): 一覧・フィルタ・検索・CSV
  • 行展開アドバイス(R1〜R4)
  • エリア別完了率(施設×日付のエリア一覧。TeamWorks 第8回 A9-2 で取得可能と確定)

依存: なし(fixtureで開発) 担当: ダッシュボード


M3 — アラート系 P3

ゴール: 検知から対応記録までが完結する

  • アラート(F-03): 一覧 + 対応状況PATCH
  • D-Secログ(F-06): 自動ソート込み
  • D-Secアラート(F-07): 一覧 + 対応状況PATCH(2026-10-19 実装。PATCH は /errors/{error_id}/status。D-180)

依存: 更新系はDB更新用アカウントと responded_at/resolved_at カラム反映待ち 担当: ダッシュボード


M4 — レポート P4

ゴール: 週次・月次の振り返りとInsight Assistレポートの素材が出せる

  • KPI4指標+前期比(F-04)
  • 施設別パフォーマンス / 連続問題施設 / エラー種別内訳
  • サマリテーブル参照と当期その場集計の切替

依存: サマリ集計バッチ(TeamWorks)の完成とスキーマ確定待ち。当期集計部分は先行可 担当: 両名


M5 — マスタViewer P5

ゴール: 契約状態とスケジュールが画面から確認できる

  • 施設ロボットマスタ(F-08、GET専用)
  • スケジュール(F-09、GET専用)
  • システム管理の表示設定・運用設定(F-10)

依存: facilities.contract 反映済みDB待ち。実装は単純なので後回し可 担当: ダッシュボード


M6 — 点検記録 P6 ※他フェーズと並走可

ゴール: 現場訪問記録がシステムに残る

  • 独自データストア構築(SQLite + オブジェクトストレージ)
  • 一覧・詳細(Before/After×7項目)・新規登録(写真アップロード)・削除
  • 過去のGフォームデータのCSVインポート(任意)

依存: メインDBと独立のため、いつでも着手可能 担当: 環境


M7 — 仕上げ P7

ゴール: 本番稼働

  • さくらクラウドVMへのデプロイ、IP制限設定
  • USE_FIXTURES=false に切替、1画面ずつ実データで確認
  • 実データでの数値検証(サマリテーブルの値と画面表示の一致確認、判定結果がfixture時と同ロジックで出ているか)
  • fixtures は削除せず残す(テスト・デモ・障害切り分け用)
  • JP/EN翻訳の適用
  • 運用ドキュメント(デプロイ手順・障害時対応)

依存: 本番DB・VM設置(TeamWorks)待ち 担当: 環境


4. TeamWorks待ち項目の一覧

実装をブロックしないため、以下はスタブ/モックで先行し、解消後に差し替えます。

項目 影響機能 暫定対応
DBアカウント発行(参照用/更新用) 全画面 lib/fixtures/ のサンプルデータで開発
ステージングDB M1のスキーマ取込以降 Prismaスキーマを定義書ベースで手書きし、db pull で答え合わせ
facility_id の主要テーブル追加(依頼3-1) 全画面のクエリ 多段JOINで暫定実装 → 追加後に単純化
responded_at / resolved_at の2カラム化(依頼3-2) F-03, F-07 APIスキーマは2カラム前提で先行
サマリ集計バッチ F-04 fixtureのサマリ値で開発。当期集計ロジックで全期間を暫定計算
月跨ぎ週の帰属ルール回答(依頼3-4)回答受領・確定済み F-04 ★週を月境界で分割する(D-071。TeamWorks 方式)。週の長さは1〜7日、週番号は1〜6★
Pudu Cloud エリア別完了率(確認事項#10)A9-2 受領・エリア単位は確定 F-02のエリア別グラフ ★エリア(=ロボット)単位の完了率は clean_status_histories から本実装する★。★1回の清掃の中の区域別内訳は依然として未解決(第9回で聞き直し)★

開発とDB接続の関係

M0 ──────────────────────────────────────────> M7
   fixtures で全画面を開発 ────────────> USE_FIXTURES=false
                    ↑
        M1でdb pullによるスキーマ突き合わせだけ先に済ませる
        (画面開発はfixtureのまま継続)

DB接続は「ある程度画面ができてから」。 ただしスキーマの答え合わせ(db pull)だけはM1で早めに行い、 カラム名の食い違いを早期に潰します。


5. Phase B / C(P1スコープ外・将来)

機能 内容
Phase B エラーコード別アドバイスルール(ハンドルアップ/ブラシ/LostLocation/オフライン等)、★1回の清掃の中の区域別完了率(売り場・通路・レジ前などの内訳。確認事項#10 の本来の問い。エリア=ロボット単位はP1で実装済み)★
Phase C 自動検出・予兆検知
P2 顧客アカウント開放(顧客管理者・施設運用者)、ユーザー管理・権限管理・監査ログ、Keenon対応