💻 システム開発
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 |
移行ステップ
- lib/work-log-api.ts 新規 (
lib/tasks-api.tsxの構造を踏襲)
-loadFromAPI('work_log_sessions:'+userId)等
-saveToAPI(...)PUT
- localStorage を cache 層として保持 - 既存 work-log.ts の互換性維持 (loadSessions/getActiveProgress 等の signature 変えない)
- 内部実装を「KV pull → localStorage cache → 返却」に変える - WorkLogProvider Context 新設 (TasksProvider と同居)
- ポーリング + state 配信 - ActiveBoard / morning / start / end / WorkLogDock を Provider 経由に切替
- 既存 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)で安全に切替可能。
推奨進め方
- 本提案にユーザー OK もらう(キー設計 + 同期戦略 + 工数の合意)
- feature flag
localStorage.scale_base_work_log_sync='1'で並走運用設計 - Day 1: lib/work-log-api + Provider + マイグレーション UI
- Day 2: ActiveBoard / morning / start / end / WorkLogDock 切替
- Day 3: E2E 検証 + 全員 flag ON
- Day 4: 旧 localStorage 完結コードを deprecated にして 1ヶ月後 archive
着手の合図
次の ce 着手時、本提案をベースに Day 1 から実装 開始します。
着手前に確認したいポイント:
- ☐ キー分離(ユーザー別)で OK か? それとも全社共有キー(admin が他人の進捗も見れる)?
- ☐ 競合解決は last-write-wins で良いか? それとも厳密性重視(version 番号 + 409 Conflict)?
- ☐ 既存 localStorage の過去データ KV push は全員一律? 個別同意モーダル?
- ☐ feature flag で並走 vs 一気に全員切替?