⚙️ Vault運用

2026-08-05_IS部署移設_TERASU_CRM

最終更新 2026年08月05日 / 90_Meta/Claude作業ログ/2026-08-05_IS部署移設_TERASU_CRM.md

IS部署の新設 — 問い合わせ対応/電話対応リストを TERASU CRM へ移設

何をしたか(大串指示 2026-08-05)

SCALE CRM に「TERASU案件だけの超特例」として置いていた 問い合わせ対応リスト / 電話対応リスト を、
TERASU CRM に IS部署 を新設して丸ごと移設した。狙いは2つ:
1. SCALE CRM の中に1案件だけの例外を残さない
2. TERASU事業部が TERASU CRM の中だけで完結できるようにする

本番 https://crm.terasu.scale-group.co.jp/ / v3.0.337 / commit 5772a90 + c518e80

大串の決定(着手前の8点)

論点 決定
データの持ち方 TERASU CRM の D1 にコピーして完結(SCALE CRM 側は残置)
HPフォームの投入先 TERASU CRM にだけ(二重投入はしない)
アポ獲得の合流 TERASU CRM 内で直結
Slack通知 今までと同じチャンネル
ログイン・担当者 二宮さん。アカウント追加は大串が自分でやる
稼働タイマー/日報/成果管理 全部そのまま持っていく
SCALE CRM からの撤去 TERASU側OK後(並走期間あり)
IS部署の見せ方 IS部署の人だけに部署カテゴリを表示

移設のやり方(ここが肝・再現できるように)

手写しでなく「機械抽出」で移した。 「座組・デザイン・仕組みを全く同じに」を人力コピーで満たすのは無理なので、
SCALE CRM の架電リストエンジンから、この2画面から辿れるものだけを依存クロージャで抜き出す生成ツールを書いた。

  • 生成ツール: ~/dev/terasu-mgmt/scripts/gen_is_engine.js
  • 生成物: lib/is_engine.js445宣言・約9,100行・原本と中身は同一・手で編集しない)
  • 手書きの境界: lib/is_shim.js(案件・メンバー・ログインユーザー・画面遷移だけを TERASU CRM の実体へ接続。
    行のロードと差分ポーリング8秒もここが回す)
  • 生成物は IIFE に包んである。TERASU CRM 側の同名関数(esc/toast/getProject/_cache 等)と衝突しないため
  • SCALE CRM 側が改修されたら node scripts/gen_is_engine.js を再実行すれば追従できる

移設したもの

  • 画面: 一覧の列・9ステータス・詳細モーダル・クイック追加行・一括編集・CSV取込・連続架電・
    稼働タイマー・日報・成果管理・Slack架電報告(=SCALE CRM と同じもの)
  • データ: 41件(問い合わせ21 / 電話対応20・ゴミ箱10含む) を中身そのままコピー。元データは消していない
  • Slack設定: SCALE CRM の TERASU案件設定をコピー(proj_is_terasu_slack_config)→ 同じチャンネルに飛ぶ
  • D1: call_rows を新設(SCALE CRM 本番の DDL をそのまま・仮想生成列と索引まで同一)
  • API: functions/api/calls/* 移植 + functions/api/inquiry.ts 新設。/api/calls* は認証ゲート対象に追加
  • アポ獲得: scale-apo.ts が SCALE CRM側(過去分) と IS側(移設後) の両方を合流 → アポ獲得リストへ

検証済み

  • 本番実バイトが手元と完全一致(is_engine.js 632,801 bytes)
  • ブラウザでエンジンが起動(ISShim/ISEngine/描画関数すべて存在・JSエラーなし)
  • 未ログインで /api/calls /api/calls/query /api/scale-apo はすべて 401
  • /api/inquiry にテスト投入 → IS の行として着弾(担当者=二宮 自動セット)→ テスト行は削除済み・41件に戻っている

残(大串待ち・次にやること)

  1. 大串が IS部署の担当者(二宮さん)を追加(メンバー編集にIS チェックボックスが出る)
  2. 大串の実機確認(部署切替「IS」→ 2画面の見え方・データ)
  3. TERASU公式HPのフォーム切替を本番へ: preview には反映済み(preview ブランチ・commit a23fc70)。
    実機確認=実送信になり Slack/メールが飛ぶため 大串の判断待ち。OKなら main にマージで本番反映
  4. SCALE CRM 側の2画面の撤去(TERASU側OK後。ナビ非表示+コード/データ残置=戻せる形にする)

学び

  • 「全く同じものを別システムへ」は手写しでなく生成ツールで移す。人力コピーは必ずズレるし、
    移設元が改修された時に追従できない。ツールにしておけば再実行で追いつける
  • 生成ツールで踏んだ罠: 正規表現リテラルの中の ' を文字列開始と誤認して関数が途中で切れた
    replace(/'/g,"\\'") で発火)。JSを機械的に切り出す時はコメント・文字列・テンプレート・
    正規表現リテラルの4つを必ず読み飛ばす
  • 依存解析は「実コードだけ」を見ると inline onclick(文字列の中の呼び出し)を取りこぼす(126関数まで落ちた)。
    コメントだけ消して name( 形式も拾うのが正解
  • 移設先に同名の関数・変数がある(esc/toast/getProject/_cache…)ときは IIFEで包んで、
    inline onclick から呼ばれる関数だけ window に出す
    。既存の同名関数は上書きしない
  • 本番反映の確認は、デプロイ成功だけでなく実バイトが手元と一致するかまで見る
    (デプロイ直後は SPA のフォールバックHTMLが返ってきて騙される)

追記 2026-08-05 午後: 表示エラーの修正 (v3.0.338)

  • 大串の実機確認で両画面とも「表示エラー (undefined の indexOf)」→ 真因は生成ツールの取りこぼし2連発:
    1. 依存解析が window.X 形式のプロパティ参照(定数)を依存に数えず、window._CL_FIXED_COLS= の宣言が生成物から漏れた
    (関数呼び出し window.f(...) は拾えていたので関数は無事・定数だけ死んでいた)
    2. 修正後、window.X= 宣言の収集が原本のトップレベル try{} 内の window._clLastSavedSnap=_kept; を拾い、
    ローカル変数 _kept への参照が残って IIFE ごと ReferenceError → 深度0(真のトップレベル)判定で根治
  • 学びの追加分:
  • JSの機械抽出で「宣言として拾ってよいのはブレース深度0だけ」。行頭判定・関数範囲外判定では
    トップレベルの try/if/IIFE 内のネスト代入をすり抜けさせる
  • .prop を依存から除外する最適化を入れたら、window.X 経由のグローバル参照が巻き添えで消える。
    window だけは特別扱いで依存に数える
  • 検証は「関数が存在するか」では不十分。実際に render を実行して描画が通るかまで見る
    (今回それをやらず大串の実機で発覚した。ブラウザの fetch+eval で本番バイトを実行するテストが有効)
  • fetch().text().length は文字数でありバイト数ではない。実バイト比較は curl + cmp でやる

関連

  • スタートカード: ~/dev/terasu-mgmt/CLAUDE.md(IS部署の章を追加)
  • SCALE CRM 側: ~/dev/scale-lead(撤去はまだしていない・v11.6.63 のまま)