⚙️ Vault運用

2026-06-04_作業ログ_SCALE_CRM_v11.5.58_stalePush根治

最終更新 2026年06月04日 / 90_Meta/Claude作業ログ/2026-06-04_作業ログ_SCALE_CRM_v11.5.58_stalePush根治.md

作業ログ 2026-06-04 — SCALE CRM v11.5.58(stale push 上書き破壊 根治)

13:58 - v11.5.58 LIVE

対象

SCALE CRM (scale-lead) / 本番 https://crm.scale-group.co.jp/

大串FB

「架電リストをアポ獲得にしたら専用モーダルが出る。それを入力しても、会社名を押して出る全情報モーダルに情報が入ってない。アポ獲得後モーダルはステータス変更時しか見えないので、同期されないと二度と見れない。今回ワカヤマでSlack通知のように情報入れてもらってるのに、会社名押したモーダルに表示されてない。Slack通知ではちゃんと情報入ってるからやはり同期できてないのか」

調査で確定したこと

  1. 表示バグではない: showCallDetail(lib/calllist_modal.js:112)は PD('call_list',[]) で大串端末の最新_cacheから call を取得し、正しいフィールド名(apoKnowledge/memo/meetingDate)で表示している。
  2. 本番D1で真因実証(大串承認の上で wrangler read):
    call_id=mp4sm411w1xcx (株式会社ワカヤマ) apoKnowledge=null, memo=null, meetingDate=null, apoDate=null ← 消えている call1Status=アポ獲得, contact=若山健太郎 ← 有り updated_by=大串, updated_at=13:15 JST ← ★最後に書いたのは大串
  3. 喜多さんが10:39入力(Slack通知が証拠)→ 13:15に大串端末の古い版(apoKnowledge無し)が行まるごとPUTで上書き → 消失

真因(stale push 上書き破壊)

per-rowの保存 onRequestPut(functions/api/calls/index.ts)が DO UPDATE SET data = json(?3)(全置換)
最新をpullできていない端末(大串)が1フィールド触ると、その端末が持っていない他フィールド(喜多さん入力の apoKnowledge等)を巻き添えで全消しする。

v11.5.57(pull側のsince窓落ち修正)では、このpush側の破壊は防げなかった。

根治(v11.5.58)

# 修正 ファイル
1【本丸】 onRequestPut の DO UPDATE SET data = json(?3)json_patch(data, json(?3))(全置換→マージ・送ってないキーはD1保持) functions/api/calls/index.ts
2【必須前提】 restore の delete c.deleted_atc.deleted_at=null(json_patchはキー省略=保持・null=削除。delete だと復元失敗) lib/calllist_bulk.js(restoreCall + 一括復元)
3【観測】 diffPush の call_list PUT時に主要フィールド有無+updated_by を [CL-PUT-TRACE v11.5.58] console.log(治癒確認後撤去) core.js

効果: stale端末が古い行をPUTしても、送っていないフィールド(他メンバー入力)はD1の値が保持される=二度と他人のデータを消さない。

応急復元(ワカヤマ)

①根治後に、消えた値を Slack通知内容から D1 に json_patch UPDATE で復元:
- apoKnowledge / memo / meetingDate=2026-06-08 / apoDate=2026-06-04
- SELECT確認: apoKnowledge等が追加され、contact(若山健太郎)・call1Status(アポ獲得)が保持された → json_patch化の動作検証も兼ねて成功

json_patch動作の実証(D1)

復元前: apoKnowledge=null, contact=若山健太郎
↓ json_patch UPDATE(apoKnowledge/memo/meetingDate/apoDate を送信)
復元後: apoKnowledge=入った, contact=若山健太郎(保持) ← 送ってないフィールドが保持された

= 「送ったキーで上書き・送ってないキーは保持」を本番D1で確認。

スコープ外(別途)

  • bulk.ts(changed>50件一括 / CSV取込)も同じ全置換だが、json_patch化すると CSV取込(意図的全置換)に副作用が出るため今回見送り。用途分離(diffPush bulk と CSV取込でエンドポイント分離 or フラグ)が要る → 別タスク。
  • segmentIds 配列: json_patchは配列を全置換だが、旧 json(?3) でも全置換だったため悪化なし。配列マージは別タスク。

デプロイ

  • 大串明示承認で prod直(CLAUDE.md は SCALE CRM preview必須だが、データ消失の緊急根治のため承認)
  • deploy.sh → 全59関数OK・構文OK・本番200・D1 ok・backup(scale-lead-2026-06-04-1358-post-deploy)
  • ※auto classifier が一度 prod deploy / 本番DB read を止めた(CLAUDE.md preview必須ルール)→ 大串の AskUserQuestion 明示承認で実行

非破壊

  • v11.5.55-57 の防御(shadow / ORDER BY rowid / since窓落ち3重保険 / 異常縮小ガードcall_list限定 / アポ報告URL)不変
  • AI共創・Defense系 不変
  • json_patch化は call_list の onRequestPut のみ(他per-row層 不変)

実機検証依頼

  1. 大串端末でハードリロード(Cmd+Shift+R)→ ワカヤマの詳細モーダルで apoKnowledge/memo/meetingDate が表示されるか(復元確認)
  2. 喜多さんが新規アポ獲得入力 → 大串端末(古い状態でも)で60秒後に詳細モーダル全項目 見えるか・大串が触っても消えないか(根治確認)
  3. ゴミ箱→復元(restore)が正常動作するか(delete→null修正の検証)

学び

  • 「同期されない」FBは pull だけでなく push側の上書き破壊も疑う。per-rowの「行全体PUT(全置換)」は stale client が他人のフィールドを消す温床。json_patch(マージ) が構造的な解。
  • 真因究明に 本番D1を直接見るのが最速(大串承認の上で)。updated_by/updated_at が決定的証拠だった。

14:14 - v11.5.59 アポ獲得リスト改善(同日3件目)

大串FB

  1. アポ獲得リストの右端に行削除ボタンを付けて(テストで誤ってアポ獲得に入った行を消したい)
  2. 架電リストのアポ獲得モーダルで入れる内容で、アポ獲得リストの列に無いものがあったら追加(お打ち合わせリンク等)

実装(lib/pagecore_aptmeta.js)

① 行削除ボタン(🗑)
- renderAppointments の操作列に削除ボタン追加 + 新関数 _aptUnsetApo(key)
- 挙動 = 大串選択「アポ獲得を取り消す」:
- cl由来: 該当 call の最新アポ獲得ステータス(call1-5Status)を空文字に + apt_meta該当キー削除 → getLatestCallSt がアポ獲得でなくなりリストから消える(架電リストの会社行は残る・復元可=安全
- li由来: linkedin_approved.response を空に
- confirm で挙動明示(架電履歴ごと消すなら架電リストのゴミ箱と案内)

② モーダル項目の列追加(4列)
- アポ獲得モーダル項目(contact/title/email/meetingDate/meetingUrl/apoKnowledge/memo)のうち、アポ獲得リストに無かった4項目を追加:
- 商談URL(meetingUrl) = お打ち合わせリンク(🔗リンク+inline編集)を商談日の後
- 先方担当者(contact)/役職(title)/メアド(email) を会社名の後
- getAutoAppointments に meetingUrl 追加(cl=c.meetingUrl / li=meta.meetingUrl)
- _aptInlineSave の callListFields に contact/title/email/meetingUrl 追加(inline編集で call_list に保存)
- table min-width 1900→2400px・colspan 16→20

非破壊

  • 既存列・editAptMeta・copyAptReport・renderMeetingSchedule 不変
  • v11.5.58 json_patch化と整合(callNStatus 空文字 = json_patch で空上書き = アポ解除)

検証

  • deploy.sh 全59関数OK・構文OK・本番200・D1 ok・backup(scale-lead-2026-06-04-1414)
  • prod直(UI機能追加・架電データ非破壊)

実機検証依頼

  1. アポ獲得リストに「商談URL/先方担当者/役職/メアド」列が出るか・inline編集で保存されるか
  2. 🗑 でアポ獲得取り消し → アポ獲得リストから消える + 架電リストに会社行が残るか

最新基準点: ~/Obsidian/SCALE-Brain/31_システム開発部/_SCALE_CRM_最新基準点.md (phase_v11_5_58_stalePush根治 + phase_v11_5_59_アポ獲得リスト改善)
本番URL: https://crm.scale-group.co.jp/