💻 システム開発

2026-05-25_設計提案_作業報告_PC-スマホ連動

最終更新 2026年05月25日 / 31_システム開発部/SCALE_Base/2026-05-25_設計提案_作業報告_PC-スマホ連動.md

作業報告 PC⇔スマホ 連動 設計提案

課題(大串 FB 2026-05-25)

「PCと連動してなさそうだから連動させて。スマホで開始して、PCで終了みたいな場面も結構ありそう」

現状の問題

  • 作業報告データは localStorage 完結 → 端末ごとに完全独立
  • scale-worklog-sessions / scale-worklog-active-progress / scale-worklog-reports
  • PC で計測 ON にした session がスマホからは見えない
  • スマホで作業開始 → PC では「進行中のセッションがありません」
  • 累計時間が端末ごとに別計算
  • メンバーの実際の働き方とミスマッチ: 合間作業のメンバー / PC 触っていない時間の作業 / スマホで会議中サクッとタスクON → デスクで OFF 等が記録されない

現状アーキテクチャ

PC (Browser A)              スマホ (Browser B)
   │                            │
   ├─ localStorage              ├─ localStorage
   │  ├─ sessions               │  ├─ sessions       ← 別物
   │  ├─ active-progress        │  ├─ active-progress ← 別物
   │  └─ reports                │  └─ reports        ← 別物
   │
   └─ scale-task-cron KV (API)
      ├─ tasks                  ← 既に同期済み(useTasks)
      ├─ bottom_tasks           ← 既に同期済み
      ├─ projects               ← 既に同期済み
      ├─ members
      └─ audit_log

タスクシート / 定例 / メンバー は既に KV 同期されているが、work-log(セッション + 進捗)だけ localStorage 完結。これを KV 化すれば一気通貫で連動する。


提案アーキテクチャ

PC (Browser A)              スマホ (Browser B)
   │                            │
   ├─ localStorage (cache)      ├─ localStorage (cache)
   │  └─ 同じデータの読み取りキャッシュ      │
   │
   └────────┬───────────────────┘
            ▼
   scale-task-cron KV (API)
   ├─ tasks (既存)
   ├─ bottom_tasks (既存)
   └─ work_log:{userId} ← 新規(ユーザー別キー)
      ├─ sessions[]
      ├─ progress: { [sessionId]: ActiveTaskProgress[] }
      └─ reports[]

キー設計

キー 備考
work_log_sessions:{userId} WorkSession[] ユーザー別
work_log_progress:{userId} Record<sessionId, ActiveTaskProgress[]> ユーザー別
work_log_reports:{userId} AnyReport[] ユーザー別

ユーザー別にキー分離 → 1人のセッション/進捗が他人に影響しない。

同期戦略

操作 PC/スマホでの動き
読み取り 起動時 + 30秒ごとポーリング + focus/visibilitychange で KV から pull → localStorage に書き戻し(オフライン耐性 cache)
書き込み localStorage 即時更新(楽観的 UI) → 直後に KV に PUT。失敗時は localStorage に「未同期」フラグ持ちで再送キュー
競合解決 last-write-wins ベース(厳密性が必要なら version 番号付き楽観的ロック)。同セッション内では時系列で interruptions 配列を merge

移行ステップ

  1. lib/work-log-api.ts 新規lib/tasks-api.tsx の構造を踏襲)
    - loadFromAPI('work_log_sessions:'+userId)
    - saveToAPI(...) PUT
    - localStorage を cache 層として保持
  2. 既存 work-log.ts の互換性維持 (loadSessions/getActiveProgress 等の signature 変えない)
    - 内部実装を「KV pull → localStorage cache → 返却」に変える
  3. WorkLogProvider Context 新設 (TasksProvider と同居)
    - ポーリング + state 配信
  4. ActiveBoard / morning / start / end / WorkLogDock を Provider 経由に切替
  5. 既存 localStorage データの初回 KV push (マイグレーション 1度きり)

リスク・落とし穴(事前洗い出し)

リスク 対策
KV 書き込み失敗で operate 中の進捗が消える localStorage cache + 未同期フラグでリトライキュー / SCALE CRM v10 の楽観的ロック方式(If-Match: version)参考
複数デバイス同時編集で last-write-wins だと片方の編集が消える session id ベースで「同セッションは1デバイスのみ active 表示」or version 番号で competition 検出 → アラート表示
KV のレート制限 / コスト Cloudflare Workers KV は十分余裕(10M req/月)。プロード書き込みも問題なし
既存 localStorage 過去データの扱い 初回 push でユーザーに「既存データを KV に同期するか」確認モーダル → 同意で push
timezone / clock skew KV 上の startedAt/endedAt は全部 ISO 8601 UTC を保ち、表示時のみ JST 変換

工数見積もり

Phase 内容 工数目安
設計確定 キー設計 + Provider 構造 + 競合解決方針 0.5d
lib/work-log-api 新規 + Provider KV 読み書き + ポーリング 1d
既存呼び出し箇所の置き換え ActiveBoard / morning / start / end / WorkLogDock 1d
マイグレーション localStorage → KV 初回 push UI 0.5d
E2E 検証 PC↔スマホ 同時操作シナリオ 5-10 個 1d
合計 約 4 営業日

SCALE CRM v10 の Supabase 移行(Day 1 で v10.0-alpha 構築・Day 2 で本格化)と同じ難易度感。並走運用(feature flag)で安全に切替可能。


推奨進め方

  1. 本提案にユーザー OK もらう(キー設計 + 同期戦略 + 工数の合意)
  2. feature flag localStorage.scale_base_work_log_sync='1' で並走運用設計
  3. Day 1: lib/work-log-api + Provider + マイグレーション UI
  4. Day 2: ActiveBoard / morning / start / end / WorkLogDock 切替
  5. Day 3: E2E 検証 + 全員 flag ON
  6. Day 4: 旧 localStorage 完結コードを deprecated にして 1ヶ月後 archive

着手の合図

次の ce 着手時、本提案をベースに Day 1 から実装 開始します。

着手前に確認したいポイント:
- ☐ キー分離(ユーザー別)で OK か? それとも全社共有キー(admin が他人の進捗も見れる)?
- ☐ 競合解決は last-write-wins で良いか? それとも厳密性重視(version 番号 + 409 Conflict)?
- ☐ 既存 localStorage の過去データ KV push は全員一律? 個別同意モーダル?
- ☐ feature flag で並走 vs 一気に全員切替?