SF改修 → BQ / ダッシュボード
影響事前検知システム 設計提案
Salesforceの宣言的なスキーマ変更が、後続のBigQuery・経営コクピットのダッシュボードを「壊れてから気づく」状態を解消する。依存関係の地図(辞書)と自動スキーマ差分検知を土台に、データチーム側だけで完結して動かす。
読み方・凡例
- 結論ファースト: 各章は「要は何か(So What)」を先に置き、根拠は小さく添える
- 確信度: ★★★A 一次情報(コード/データ実体) / ★★B 二次情報(本人回答・部分確認)
- 2つの依存経路: Path A=SF→SQL→…→ダッシュボード(SQL経由) / Path B=ダッシュボードのGASがSFを直読み(SQLを通らない近道)
課題:要は何が問題なのか(結論ファースト)
根因は依存と整合性が地図化されておらず、変更・不整合を捕まえる自動の仕組みが無いこと。
問題は2クラスある(重要)
| 観点 | クラス① スキーマ変更 | クラス② データ品質・同期 |
|---|---|---|
| 中身 | 項目リネーム/型/選択肢値の変更が後続BQ・ダッシュを沈黙破壊 | SFへのデータ同期漏れ・件数不整合(例: VISION申込10件が ReboostData__c に来ない/SF・スプシ・BQで件数バラバラ) |
| 根因 | 依存の不可視 + 検知不在 | テストフロー不在・属人化・リリース前の差分照合プロセス無し |
| 直接効く打ち手 | 依存の地図 + スキーマ差分検知(本設計の中核) | リリース前のデータ差分照合ゲート + 脱属人化(本設計の検知エンジンを"データ照合"に拡張) |
| 出典 | 2026-04-16 事故 ★★★A | SYSDEVREQ-1714 / Slack(西川「移行時に差分チェックするプロセスを必ずリリース前に」) ★★★A |
根拠(確認済みファクト・補足)
| スキーマ事故 | 2026-04-16 SurveyLpCurrentGoal__c→SurveyLpConcerns__c のリネームを integrated_customer_analytics.sql 等でCOALESCEで事後対応した痕跡 ★★★A |
| データ事故 | THE VISION:申込19件中SFに9件しか同期されず10件欠落、SF/スプシ/BQで件数不整合→スコアカード集計を一時停止(SYSDEVREQ-1714) ★★★A |
| テスト不在・属人化 | 福原「テストというより項目作成とインポートをこちらで実施」/「このシート触るの怖いのでそのまま」=SF側にQA・差分照合プロセス無し、特定個人依存 ★★★A |
| 2系統の依存 | Path A: SF→staging_*(毎時)→…→ダッシュボード。Path B: org-coaching.gs が OrganizationalCoaching__c を直読み ★★★A |
| 土台は揃う | sf_utils.py でSFスキーマ全取得可、Slack/Backlog即通知可、コクピットGASはパース可能 ★★★A |
| 変更手段 | SF変更は基本「管理画面の宣言的UI変更」=デプロイ・履歴・レビューが存在しない ★★B |
推奨アーキテクチャ(理想形)
設計の核は 依存関係の地図(辞書)を土台に置き、2方向の入口(事後の自動検知/事前の人間起点)から同じ1つの出口(影響の提示+通知)へ繋ぐこと。
flowchart TB
classDef core fill:#e8eef7,stroke:#1A365D,color:#1A365D
classDef auto fill:#dcfce7,stroke:#15803d,color:#14532d
classDef human fill:#ede9fe,stroke:#7c3aed,color:#4c1d95
subgraph BASE["土台:依存関係の地図(辞書)"]
psql["SQLを読み解いて依存を抜き出す"]:::core
pgas["コクピットGASを読み解いて依存を抜き出す"]:::core
dg["依存の地図(辞書)
『この項目を変えたら、どのBQ表・SQL・
ダッシュボードのKPIが倒れるか』を引ける"]:::core
psql --> dg
pgas --> dg
end
subgraph AUTO["事後(自動・必須):SF変更を毎時みはる"]
snap["describe で SFの設計図
(項目・型・選択肢値)を読み取る"]:::auto
diff["前回と差分をとる
(消えた / 増えた / 型変更 / 選択肢値変更)"]:::auto
snap --> diff
end
subgraph PRE["事前(人間):既存の依頼フローを拡張"]
form["既存:依頼フォーム→Backlog→Slack→Claude要件Q&A"]:::human
lookup["変更前に影響を引く /sf-impact (Slack)"]:::human
end
engine["影響を照合する
変更 × 依存の地図"]:::auto
act["影響と直し方をまとめて知らせる
Claude修正案 + Slack通知 + Backlog起票"]:::auto
dg --> engine
diff --> engine
form --> engine
lookup --> engine
engine --> act
業務フローとシーケンス
運用は2つの流れ。事後(安全網)=SF変更が起きたら自動で検知して通知。事前(上流)=開発依頼フォームでSF項目変更の意図を検知したら、影響を要件Q&Aにインライン提示してBQチームへ事前連携。
フロー① 事後(自動の安全網)
sequenceDiagram
autonumber
actor admin as SF変更者
participant sf as Salesforce
participant sys as 検知システム(raftel)
participant dg as 依存の地図
participant slack as Slack(西川/稲川)
participant bl as Backlog
admin->>sf: 項目/選択肢値をUI変更
loop 毎時
sys->>sf: describe で設計図を読み取る
sys->>sys: 前回スナップと差分をとる
end
sys->>dg: 変更項目/値を照合
alt 後続に影響あり
dg-->>sys: 影響先(SQL・ダッシュボード・KPI)
sys->>slack: 影響 + Claude修正案を通知
sys->>bl: SYSDEVREQ に自動起票
else 影響なし
sys->>sys: 記録のみ(通知しない=ノイズ抑制)
end
フロー② 事前(依頼インテイク拡張)
sequenceDiagram
autonumber
actor req as 依頼者
participant form as 開発依頼フォーム
participant claude as ClaudeCode(要件Q&A)
participant dg as 依存の地図
participant slack as Slack(西川/稲川)
req->>form: 開発依頼を送信
form->>claude: Backlog起票 + 要件整理を開始
claude->>claude: SF項目変更の意図を検知
alt SF項目変更を含む
claude->>dg: 変更前に影響を引く
dg-->>claude: 影響先一覧
claude->>req: 要件Q&Aに影響をインライン提示
claude->>slack: 西川/稲川へ事前連携
else 通常依頼
claude->>req: 通常の要件Q&A
end
仕組みの具体例(describe / 依存の地図)
① describe=「SFの設計図を読み取る」
あるオブジェクト(テーブル相当)の全項目の仕様(設計図)を一発で取るSFの機能。sf_utils.py が裏で SF CLI を叩いて返す。これを毎時取って前回と比べる=検知の心臓。
# describe("OrganizationalCoaching__c") が返す1項目の例 { "name": "StageName__c", // API名(リネーム検知の主キー) "label": "商談フェーズ", // 画面表示名 "type": "picklist", // 型(変更を検知) "custom": true, "nillable": true, "picklistValues": [ // ← 選択肢値(StageName__c問題の検知) {"label": "担当者ビジネスMTG", "active": true}, {"label": "フロント受注", "active": true}, ... ] }
② 依存の地図(dependency-graph.json)=「何が倒れるかを引ける辞書」
「SFのこの項目を変えたら、どのBQテーブル・SQL・ダッシュボードのどのKPIが倒れるか」を機械が引ける地図(辞書)。SQL/GASをパースして自動生成し、手では持たない(CIで再生成=腐らせない)。
// 変更項目をキーに引くと、影響先(consumed_by)が一覧で返る { "OrganizationalCoaching__c.StageName__c": { "type": "picklist", "使われている選択肢値": ["担当者ビジネスMTG", "フロント受注", "本契約受注"], "consumed_by": [ { "経路": "B(GAS直結)", "資産": "management-cockpit/org-coaching.gs", "KPI": ["組織コーチング_ファネル各段階"] } ] }, "Lead__c.SurveyLpConcerns__c": { "type": "picklist", "consumed_by": [ { "経路": "A(SQL経由)", "資産": "sql/staging/staging_Lead__c.sql" }, { "経路": "A(SQL経由)", "資産": "sql/analytics/integrated_customer_analytics.sql" }, { "経路": "A(SQL経由)", "資産": "management-cockpit/carispi.gs", "KPI": ["キャリスピ商談フェーズ"] } ] } }
consumed_by が影響先一覧。これが「何をどう直すか提案」の事実の源。LLMはこの事実を文章化するだけで、依存を推測させない。実装論点:現状から理想形への差分
「当初の2ポイント案(①依頼フォーム連携 ②デプロイ前テスト)」で既に実現できている点も含め、理想形に対して何が足りないか=何を実装するかを差分で整理する。
| 論点 | 現状(当初2点で実現済み含む) | 理想形への差分=実装すること |
|---|---|---|
| ① 依存の地図(土台) | 無い。依存の地図そのものが存在しない。当初案の「事前用意の辞書」は着想として◎ | SQL+GASをパースして自動生成。Path A/B・選択肢値もカバー。これが全部の土台 |
| ② 自動差分検知(事後) | 無い。当初Point2は「デプロイ前テスト」を意図したが、SFはUI変更中心でデプロイが存在しない | describe 毎時スナップ→差分に作り替え。人手非依存の安全網。リネームは「旧消滅+新出現」、選択肢値も差分 |
| ③ 事前トリガ(依頼拡張) | フォーム→Backlog→Slack→Claude要件Q&Aは稼働中(当初Point1で実現済み・SYSDEVREQ-1679) | SF項目変更を検知→影響をQ&Aにインライン提示+事前連携。Slack /sf-impact 追加 |
| ④ アクション層 | Slack/Backlog即実行可(西川/稲川ID既知) | 決定論の影響+Claude修正案を生成し自動起票・通知(LLMは提案文に限定) |
/sf-impactで即答。BQチームには「影響+修正案+課題ワンクリック」、依頼者の体験は劣化させない。
段階導入ロードマップ
Phase 0(土台): 依存の地図 + 検知エンジン
- raftel SQL/コクピットGAS(CIでclone)をパース→ SF項目・選択肢値・Path A/B を抽出
Phase 1(安全網・クラス①): 自動スキーマ差分検知+通知
describe毎時スナップ→差分→照合→Slack通知。死蔵473項目は除外、BQ失敗監視も併設
Phase 1+(安全網・クラス②): データ差分照合
- 同じエンジンで SF ↔ スプシ ↔ BQ の件数・主キーを毎時照合。ズレたら通知。リリース前検証ゲートにも転用
Phase 2(提案+起票): アクション層
- 影響先(決定論)+Claude修正案→Backlog自動起票・担当割当
Phase 3(上流): 既存依頼インテイク拡張
- フォームのClaude Q&AにSF影響ブランチ+Slack
/sf-impact(前提: インテイク基盤リポ確立)
Phase 4(構造の本丸・段階導入): SFDX/GitHub化 + 契約ビュー層
- SFを段階的にSFDX化し、検知をデプロイ前ゲートへ昇格+設定の属人化を解消(最終章参照)。安定列名の契約ビューで結合を1箇所に集約
SFDX / GitHub化 — 必要性が実証された構造の本丸(段階導入)
SFDXは、SFの設定(項目・フロー等)をコード化してGitHubで管理するやり方。直近のVISION事故は「テストフロー不在・属人化・レビュー無し」が根因で、SFDXはその根因の構造的な解。検知システムはSFDX無しで完結するが、SFDX化すると検知が「事後の網」→「デプロイ前ゲート」に昇格する。
SFDXとは何か(SF CLIとの違い・3層構造)
SF CLI(sfコマンド)は"道具"、SFDXはそれを使った"設定をコード化してGit管理する開発方法論"。今 sf_utils.py で sf sobject describe を叩いてるのは"CLIの一機能を使ってる"だけで、まだSFDXの運用には入ってない。
[SFDXの3層構造] 道具層 : SF CLI(sf project deploy / sobject describe / apex run ...) 方法論層 : force-app/main/default/{objects, flows, classes, validationRules}/ ← Git管理 統制層 : Git + PR + CI + Scratch Org + ロールバック
sfdx-project.json + force-app/ フォルダ) ④ Gitリポ+運用ルール(retrieve→commit→PR→deploy) ⑤ 任意: Scratch Org
何ができて、何は人がやるか(1402結論の更新)
| 種類 | CLI/AI完結 | 実情 |
|---|---|---|
| Apexクラス/トリガー | ✅ 完全可 | コード生成→test→deploy を end-to-end。1402で「16h→5h」と試算済 |
| バリデーション/カスタム項目/レイアウト | △〜◯ | XMLで管理可。AI生成可だが複雑なものはUIが速い場合あり |
| 宣言的Flow(Flow Builder) | ❌ 作成は人 | retrieve/deployはCLI可だがXML編集は事実上非現実。1402結論「Flow Builder組立は人がやる」は変わらん。SFDXが解放するのは"版管理・デプロイ・レビュー"で、"作る"ではない |
| 業務ルール/UX/ステークホルダー合意 | ❌ | 人 |
| 変更の履歴・レビュー・CI・ロールバック | ✅ SFDX最大価値 | ここが"統制"として追加される |
BQ連携以外に、どんな恩恵があるか
UIのまま続けるリスク
- 誰が・いつ・何を変えたか履歴が残らない
- レビュー・承認なしで即本番反映
- 変更前に影響もテストも確認できない
- ロールバックが手作業・属人化
SFDX+GitHub管理の恩恵
- 変更がコード化→履歴・差分・レビューが効く
- デプロイ時にCIゲート=検知が事前ゲートに昇格
- ロールバック・複数人並行が安全に
- AIが差分を読んで自動レビュー・修正できる
業務プロセス・品質 Before / After
| 観点 | Before(今) | After(SFDX+AI/本提案) |
|---|---|---|
| 変更の見え方 | UI操作→履歴ゼロ。誰が何変えたか追えん | Gitにdiff+作者+理由が残る |
| レビュー | 無し。一人で本番反映 | PRレビュー必須。第三者チェック |
| テスト | 手動・属人 | CI自動(Apexテスト/メタデータ妥当性/差分検証) |
| 環境 | 本番直接 or Sandbox手動 | Scratch Orgで隔離テスト |
| デプロイ | UI/Change Set | sf project deploy 1コマンド |
| ロールバック | 手作業・属人 | 前バージョンに1コマンドで戻す |
| インシデント調査 | 福原・浜田に依存・数日 | Gitログ+AIで分単位 |
| 新規メンバー参入 | 暗黙知が必要 | コードを読めば理解可 |
| データ整合性(VISION型) | 無検証=事故 | SFDX単体では直接解けない → データ差分照合ゲート(Phase 1+)で別途解決 |
UI → SFDX へ移行するステップ(ざっくり)
| ステップ | 内容 | 工数感 |
|---|---|---|
| 1. 環境準備 | SF CLI + GitHubリポ + 接続認証 | 数日(技術) |
| 2. 現状をコード化 | 既存の項目・フロー等を取り出してGit管理に載せる | 1〜2週(技術) |
| 3. 運用切替+CI | UI直変更をやめ「ブランチ→レビュー→デプロイ」へ。GitHub Actionsで自動チェック。+SFチームのトレーニング(最大の山) | 数週〜数ヶ月 |
| 4. 段階移行 | 一部のオブジェクト/フローから試して拡大 | 継続 |
体制と運用(VISION事故・台帳ふまえた再設計)
SFDX化やデータ整合ゲートはあくまで"道具と仕組み"。それを動かす体制と運用が伴わなければ事故は再発する。直近のSlack(5/22-23)・SF管理台帳・1402の証拠を踏まえて、現状を正直に評価する。
現状ファクト(証拠ベース)
| 福原のリーダーシップ | 5/23 西川「SFチームの仕事の進め方や品質管理にMOREを感じる」→ 武田「チーム解体OK、ドラスティックにやろう」と即応。5/23 西川が福原の調査アプローチを公然と否定し「自分で確認します」=信頼喪失 ★★★A |
| 浜田の属人化集中 | SF管理台帳で11+フローを主担当(Community Session 50ver等、累計最大)。VISIONインシデント中の週末不在で対応停止 ★★★A |
| 60+フローのオーナー未割当 | 台帳で構造的に責任が不明確(P1優先度のものを含む) ★★★A |
| 台帳の腐敗 | 「最終更新」が2026/02-03止まり=手動メンテの限界。検知システムの依存グラフで自動化すべき領域 ★★★A |
| 体制 | 福原(リーダー・フル) + 浜田・村松(業務委託 60h/月) ★★B |
| フロー総量 | 182アクティブフロー/89カスタムオブジェクト/23 Apexトリガー(1402調査時点) ★★★A |
体制再編 3案(トレードオフで提示)
| 案 | 内容 | メリット / リスク | 推奨 |
|---|---|---|---|
| A. 段階移行 (推奨) | (1) 福原をSFリーダーから降ろし企画開発に統合、2〜3ヶ月のナレッジ移管期間を並走 (2) 同時にSFDX土台+台帳機械可読化で属人化を物理解消 (3) 浜田・村松は当面継続でフロー所有を分散+移管 (4) AI/SFDX化が回ったら業務委託契約を縮小/横断化/解除を再評価 | 信頼喪失と知識ロスの両方に対処。順番が現実的。 リスク: 移行期間に福原の協力が得られないと頓挫 → ナレッジ移管成果のKPI設定が必須 | ◎ |
| B. 即時再編 | 福原を即座に異動、浜田を主担当に昇格、村松維持 | スピード。 リスク: 福原暗黙知のロス、浜田にさらに集中=属人化悪化 | △ |
| C. 安全先行 | 整合ゲート+台帳整備で属人化を物理解消してから福原を動かす | 知識ロス最小。 リスク: 信頼喪失問題の対応が遅れ、Slack Aの「チーム解体OK」の機を逃す | △ |
90日アクション順
| 期間 | やること | 効く論点 |
|---|---|---|
| 0-30日 | 検知システム Phase 0→1→1+(依存の地図+スキーマdiff+データ差分照合)/インシデントRunbook化/福原に「企画開発統合」を打診+移管計画策定 | 安全網即時/信頼喪失への着手 |
| 30-60日 | フロー版エッセンシャル化スキャン→廃止候補リスト/オーナー再割当(60+空欄解消)/Claude Codeスキル群実装(/sf-impact, /sf-recon, /sf-incident-runbook) | 属人化の物理解消/スリム化 |
| 60-90日 | SFDX土台導入(Dev Hub有効化+プロジェクト構造+小スコープから retrieve→Git管理)/福原ナレッジ移管完了/業務委託契約の再評価 | 統制の構造化/体制最適化 |
Claude Codeスキル化で工夫できる内容
SFのベテラン暗黙知をAIスキルに閉じ込めて、横断者・新規メンバーでも踏み外せん仕組みを作る。これが脱属人化の本丸ツール。
| スキル | 役割 | 状態 |
|---|---|---|
/sf-impact <項目> | 「この項目を変えたら何が倒れるか」を即答(依存の地図に問合せ) | 本提案で新規(Phase 3で完成) |
/sf-recon | SF ↔ スプシ ↔ BQ の件数・主キー照合。リリース前検証ゲートにも転用 | 本提案で新規(Phase 1+) |
/sf-flow-doc | フロー仕様書/影響調査/NULL率スキャン | 既存・拡張(管理台帳と連動して自動更新へ) |
/sf-flow-essentialize | 全フローの利用率/更新頻度/依存度スキャン→廃止候補リスト | 新規(スリム化の本命) |
/sf-incident-runbook | インシデント初動→調査→正データ照合→対応の標準型(VISION対応の仕組み化) | 新規 |
/sf-deploy-review | SFDX移行後、PRメタデータ差分のAIレビュー(変更の意味・影響・テスト推奨を解説) | SFDX化と連動 |
/sf-onboard | 新規メンバー向け「SF暗黙知ガイド付きチャット」。福原・浜田の知識をAIに移植 | 新規(脱属人化のメイン武器) |
付録:再利用資産・検証・リスク
再利用する既存資産
| SFスキーマ取得/picklist | scripts/sf_utils.py |
| Slack/Backlog通知・起票 | scripts/slack_utils.py, scripts/backlog_utils.py |
| BQ SQL(パース対象) | bq_schedule_query/sql/{staging,marts,analytics}/*.sql |
| ダッシュボードGAS(パース対象) | mizukara-corp/management-cockpit/scripts/*.gs |
| 既存インテイク参照 | Backlog SYSDEVREQ-1679、Slack C0851DE6QEB |
| CF/CI雛形・死蔵項目 | cloud_functions/slack_engagement_ingest/, docs/GitHubActions構築.md, docs/sf-null-rate-scan.md |
検証方法
| 1 | ゴールデン再現: SurveyLpCurrentGoal__c/StageName__c値 投入→影響SQL・4ダッシュボードが正しく出るか |
| 2 | picklist差分: サンドボックスで選択肢値を1つリネーム→検知されるか |
| 3 | describe差分: SFテスト項目変更の前後スナップ差分検知(Phase1 Exit) |
| 4 | 腐敗テスト: SQL/GASに新列追加PR→CIで地図が自動再生成されるか |
未解決リスク・要確認
- SF接続認証(Connected App/JWT)の整備可否=自動検知の前提(これだけはデータチーム側で要設定)
- リポ配置の合意: 検知コア=raftel_gcp、インテイク拡張=新設リポ の境界でよいか
- インテイク基盤リポ(琴哉さん)の確立タイミング=事前トリガ(Phase3)の前提
- 未カバー消費先: clasp外Connected Sheets・KUZEN・n8n のカバー要否と優先度
- SFDX化(おまけ): 着手するかは全社DX文脈での別途意思決定