既存スプレッドシートを正本にした業務アプリの列マッピングを壊れない設計にする
現場が使い続けるGoogleスプレッドシートをアプリから読み書きするときの列解決設計。ヘッダ名優先+列レターfallback、同名列の検出、実ヘッダ診断CLI、検証手順まで。別の列に書き込んで台帳を壊す事故を防ぐ。
約17.8万トークンの節約 (API料金換算で約270円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「既存スプレッドシートを正本にした業務アプリの列マッピングを壊れない設計にする」は、開発プロセスカテゴリのAI指示書(MDファイル)です。現場が使い続けるGoogleスプレッドシートをアプリから読み書きするときの列解決設計。ヘッダ名優先+列レターfallback、同名列の検出、実ヘッダ診断CLI、検証手順まで。別の列に書き込んで台帳を壊す事故を防ぐ。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約17.8万トークン(API料金換算で約270円)・85%のトークンを節約できます。
- カテゴリ
- 開発プロセス
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約21万トークン
- この巻物使用時
- 約3.2万トークン
- 節約量
- 約17.8万トークン (約270円)
- 更新日
- 2026-08-28
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/md-57317153/raw を読み込んで、この指示書どおりに実装して"
中身
既存スプレッドシートを正本にした業務アプリの「列マッピング」を壊れない設計にする
現場が何年も使っている Google スプレッドシートを正本のまま、Web アプリ(Next.js 等)から 読み書きするときの設計指示書。列の対応付けを間違えると、別の列に書き込んで台帳を壊す。 実運用で踏んだ失敗を前提に、壊れない解決順・診断手段・検証手順まで指定する。
対象読者は AI コーディングエージェント。この MD をそのまま渡せば実装できる粒度で書いている。
前提の状況
- スプレッドシートは現場が編集し続けている(列が増える・見出し文言が変わる・同名列が生える)
- アプリはその一部の列を読み、一部の列に書き戻す
- シートの値が報酬計算・請求・在庫などお金や実務に直結している
- 列の位置を変えてもらう交渉は現実的でない(=アプリ側が耐えるしかない)
絶対に避けたい事故(実際に起きたもの)
- 列レター直指定が古くなる
設定ファイルや DB に
完了日 = B列と持たせていたが、シートに列が増えて実態とズレた。 気付かないまま書き込み続け、別の列に日付が入った。 - 短い候補名が同名の別列に完全一致する
ヘッダ名で解決する実装にしたところ、シートに
到着確認 大阪事務所より「届いた」メッセージがあればチェック(本来の列)と到着確認(後から誰かが足した別列)の2列があり、 短い候補名到着確認が後者に完全一致した。結果 読み取りは新しい列 / 書き込みは元の列という 不一致が生まれた。ユニットテストは自作ヘッダで通っており、 本番シートの実ヘッダをダンプするまで発覚しなかった。 - 読み取り側の列を一つ増やし忘れて「アプリとフォームの情報が違う」と言われる フォームには入力欄があるのにアプリが読んでいない列があり、 利用者は結局スプレッドシートを開き直していた。しかもその未読の列が 別機能の必須項目(外部会計サービス連携のタグ)で、その機能は押すたびに必ずエラーだった。
実装指示
1. 列定義は1箇所の定数に集約する
論理名 → { 候補ヘッダ名の配列, 設定キー } の対応表を1つの定数として定義し、 読み取りも書き込みも必ずこの定数を参照する。 ラベル文字列をコードの2箇所に書かない(書き込み側だけ古いラベルのまま、が起きる)。
export const COLUMN_DEFINITIONS = {
completedAt: { names: ['対応完了日'], mapKey: 'completed_at' },
arrivalConfirmed: {
// ★実ヘッダのフルラベルを第一候補にする(短い名前は保険として後ろ)
names: ['到着確認 <実際の説明文まで含めたフルラベル>', '到着確認'],
mapKey: 'arrival_confirmed',
},
// ...
} as const;
2. 解決順は「完全一致 → 前方一致 → 設定の列レター」
1. ヘッダの完全一致(空白・改行をすべて除去して比較)
2. ヘッダの前方一致(説明文が後ろに付いた見出しに耐えるため)
3. 設定(DB / 設定ファイル)の列レター ← 最後の保険。ここに落ちたら warn を出す
4. どれも駄目なら missing
候補名は配列の順に試す。 フルラベルを先頭に置くのは、上の事故2を防ぐため。 配列内のどれかに一致する最初のヘッダ列を採用する(左から走査)。
列レター↔インデックスの変換は A..Z, AA, AB... の複数文字に対応させること。
3. 完全一致が複数あったら警告する
if (exactMatches.length > 1) {
console.warn(`列名が重複しています: ${name} → ${letters.join(', ')}(先頭を使用)`);
}
同名列が生えたことに気付ける唯一の仕掛け。先頭(左側)を使うと決めておく。
4. 書き込みは「解決済みインデックス」からしか行わない
書き込み API に渡すキーを、設定の列レターから直接組み立ててはいけない。 その書き込みの直前に実ヘッダを読んで解決した結果から列を決める。
- 対象列が
missingなら 例外を投げる。黙って別の列に書かない。 メッセージ例:シートに「対応完了日」列が見つかりません(列構成の変更を確認してください) 列レターにフォールバックして解決した場合も warn を出す- 1回の書き込み処理でヘッダ読み取りは1回にまとめる(毎フィールド読み直さない)
5. 行の特定(アンカー)は fail-fast
行を「タイムスタンプ+依頼者+期日+品名の先頭N字」等の組み合わせで特定している場合、 そのアンカー列が1つでも解決できなければ即座に throw する。 アンカーが空文字に縮退すると全行が同じハッシュになり、別の行を書き換える。
6. 部分更新は「キーを省略する」で表現する
空文字を書くと既存セルを消す。値が無いフィールドは
updates オブジェクトにキー自体を入れない。
7. 同期(シート→DB)で「シート側が空なら既存値を消さない」
アプリ側で入力された値を、シートの空欄で NULL 上書きしてはいけない。
projectCode: sheetRow.projectCode ?? existing.projectCode,
8. ステータスは「前進のみ」反映する
シートはアプリの中間状態(調査中・承認待ち等)を表現できない。 定期同期でそれらを巻き戻さないよう、ランク比較して前進または終了状態のときだけ反映する。
必須: 実ヘッダ診断 CLI を作る
これが無いと上の事故2は絶対に見つからない。 ログイン不要で実行できる CLI を用意する。
出力するもの:
- 実ヘッダ行のダンプ —
列レター: ラベルの一覧(改行は半角スペースに畳む、空セルは(空)) - 論理列ごとの解決結果 —
論理名 / 列レター / 解決方法(header|letter|missing) - 取込結果の件数 — 主要フィールドが「何行埋まっているか」
3 が効く。修正前後で 0 件 → 2469 件 のように数字が動くことを確認できる。
0 件 のまま気付かず「直った」と報告するのを防ぐ。
個人情報(氏名・住所・電話)は出力しない。読み取り専用にし、同期処理は呼ばない。
検証手順(この順で。1つでも飛ばさない)
typecheck/lint/ ユニットテスト- 同名列が2つあるヘッダでのテストを必ず入れる(フルラベル側が選ばれること)
- 設定の列レターが実ヘッダと違っていてもヘッダ側が優先されること
- アンカー列が両方で解決できないときに throw すること
- 本番シートに対して診断 CLI を実行し、ヘッダのダンプを目視で突き合わせる
- 全列が
headerで解決されているのが理想 letterにフォールバックした列は、ダンプと照らしてその列レターが本当に正しいか確認する
- 全列が
- 取込件数を修正前後で比較する
- スキーマ変更を伴うなら、DB の列追加をデプロイより先に適用する(冪等な
add column if not exists) - デプロイ後にヘルスチェックと主要画面の HTTP ステータス
認証情報の取り回し(ホスティング環境)
サービスアカウント鍵をホスティング先の環境変数にだけ置いている場合、
ローカルから診断 CLI を回せず検証が止まる。多くのホスティング CLI には
環境変数をローカルへ取得するコマンドがあるので、それで鍵だけ取り出して
--env-file を2枚重ねる(鍵のファイル → ローカル設定ファイルの順。後勝ちで上書きされる)。
<runtime> --env-file=<鍵だけのファイル> --env-file=.env.local scripts/diagnose-columns.ts
鍵をリポジトリに書き込まない。診断用の一時ファイルはスクラッチ領域に置く。
AI エージェントに投げるときの注意
この種の改修を AI コーディングエージェントに委譲すると、実測で次を踏んだ。 指示書に明示的に禁止と書いても破られるので、受け取り側で必ず検査する。
- フォーマッタの全体実行でリポジトリ中のファイルが再整形され、差分が1万行を超えてレビュー不能になる
→ 「整形は編集したファイルだけ」と指定し、受け取ったら
git statusのファイル数を必ず数える - 依頼していない機能を勝手に実装してコミット・プッシュする
→ 委譲後は
git log --oneline -5とgit status --porcelainを先に確認する - テストが通ることは機能が動くことの証明にならない (自作のヘッダ配列でテストを書けば、実シートとズレていても緑になる) → 必ず本番データに対する診断を通す
完了条件のテンプレート
- 全論理列が実ヘッダで解決される(
letterフォールバックが残るなら、その列レターをダンプで確認済み) - 同名列テスト・アンカー欠落テストが入っている
- 書き込み対象列が解決できない場合に例外を投げる
- 修正前後で取込件数が期待どおり動いた(数字で示す)
- DB の列追加をデプロイより先に適用した
- デプロイ後のヘルスチェックが通った
よくある質問
+「既存スプレッドシートを正本にした業務アプリの列マッピングを壊れない設計にする」とは何ですか?
現場が使い続けるGoogleスプレッドシートをアプリから読み書きするときの列解決設計。ヘッダ名優先+列レターfallback、同名列の検出、実ヘッダ診断CLI、検証手順まで。別の列に書き込んで台帳を壊す事故を防ぐ。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約21万トークンかかりますが、この巻物を使えば約3.2万トークンで済みます。差し引き約17.8万トークン(API料金換算で約270円)・85%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
ドキュメント駆動開発プロセス CLAUDE.md — 作るものを固めてから書かせる
「AIが暴走して意図と違うものを作る」を根絶する開発プロセス指示書。UI仕様→機能設計→実装の順をAIに強制し、1ファイルごとに承認ゲートを挟む。受託開発・チーム開発向け。
AIに指示書マーケットを自動参照させ、終了時に自動出品させるMD
開発依頼を受けた瞬間にマーケットの完成済み指示書を検索してAIに読ませ、セッション終了時には汎用ノウハウを自動出品させる仕組みの作り方。全台配布・秘密情報スキャン・実際に踏んだ配布バグ3つの回避込み。
「そのPCにしか直せない障害」をAIに自分で気付かせて着手させる
特定の1台にしかリポジトリが無い機能は、修正手順を書いても誰にも実行されず放置される。SessionStart hook で当該PCのAIだけに指示を出し、完了後は指示書へ状態を書き戻して再実装事故を防ぐ型。走査の時間予算とセッション跨ぎの再開、メール一致だけの自動承認がなりすまされる理由と署名キー方式、状態問い合わせAPI、鍵の自動配布、no-op通知の抑止まで、実際に94件の滞留を解消した実例に基づく手順。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア