v1.1 rev3  |  CEO 再承認待ち  |  Freee 自動同期実装完了(2026-05-28) 担当: トラジ(社内開発)・うーぱん(経理)

A10 立替管理表スプシ 21列再設計 + 双方向書込 + 三段ガード dedup v1.1 rev3

バージョンv1.1 rev3(2026-05-28 Freee 自動同期追加)
前バージョンv1.0 — A10 証憑フォルダ構造刷新
担当うーぱん(A10 経理)/ トラジ(技術実装)
スプシA10_立替管理表_2026年度
対象ファイル sheet_writer_v3.py / freee_reconciler_v3.py / dedup_index_manager_v3.py / migrate_to_21col.py / test_sheet_redesign.py

変更概要(v1.0 → v1.1 rev3)

項目v1.0v1.1 rev3
スプシ列数 23 列(A〜W) 21 列(A〜U)
書込み方向 アップロード起点のみ 双方向(アップロード + Freee MCP 起点)
重複防止 SHA256 + OCR 3項(二段) SHA256 + OCR 3項 + Freee deal_id(三段)
証憑有無 なし B 列: ◎/○/⚫/△/❌ の 5 状態
要確認 B 列: ○ のみ D 列: テキスト判定(9 種 / 区切り)
E 列「Freee 転記済」 スタッフ手動 ✓(廃止) reconciler 自動同期(rev3): details[].account_item_id 有無で ✓ / 空欄を自動判定
LaunchAgent 2 件(pipeline 夜次 / poller 5 分) 4 件(+ reconcile_weekly 月曜 / sort_weekly 月曜)
段階導入 Phase 1/2/3 ロードマップ

新 21 列構造(A〜U)

左ブロック: 人間視点(5 列)

ヘッダー旧列データ源備考
A 発生日 旧 C OCR ソート主軸(A 列を発生日に移動)
B 証憑有無 reconciler 計算 ◎/○/⚫/△/❌
C 状態/信頼 旧 S+R 統合 パイプライン 「ok / 0.95」形式
D 要確認 改善 旧 B 拡張 自動判定 何を確認かをテキストで(複数 / 区切り)
E Freee 転記済 旧 O reconciler 自動同期 rev3 deal の details[].account_item_id 有無を判定。✓=仕訳登録済み、空欄=未完。スタッフ手動 ✓ は廃止。

中ブロック: 取引内容(12 列)

ヘッダー旧列データ源備考
F支払区分旧 GUI会社支払/代表立替
G 証憑種別 旧 H 拡張 UI 電子証憑/紙証憑/クレカ明細/通信費(月次)/公租公課(5 大分類)
H 証憑形式 renamer 自動付与 電子領/電子請/電子その他 / 紙領/紙請/紙その他 / クレカ明細 / 通信費(月次) / 公租公課(9 細分)
I金額(税込)旧 DOCR + MCP 補完外貨は reconciler が JPY 換算値を埋める
J外貨(合計)旧 FOCR外貨時のみ "$11.51 USD" 形式
K 勘定科目(ID) 旧 L+M 統合 OCR+マスタ照合 「交際費 (#232703272)」形式
L品目メモ旧 JOCR
M店舗・発行者名旧 IOCR
N備考旧 KUI/クレカ理由
O取引先 ID旧 Vreconciler
P Freee 連携 旧 P+Q+W 統合 reconciler 「deal_id (score 1.0)」形式
Q Drive 証憑 旧 T+U 統合 パイプライン =HYPERLINK 関数でファイル名→Drive URL

右ブロック: システムメタ・税務(4 列)

ヘッダー旧列データ源備考
R税区分旧 Nマスタ照合
S消費税額旧 EOCR
T消費税額(外貨)OCR外貨時のみ
U処理日時旧 AシステムA 列から U 列に移動

証憑形式 H 列: 9 細分(renamer 自動付与)

G 証憑種別(UI 選択)→ 自動付与される H 証憑形式判定条件
電子証憑 電子領 OCR テキストに「領収書/Receipt/領収印」を検出
電子請 OCR テキストに「請求書/Invoice/INV」を検出
クレカ明細 OCR テキストにクレカキーワード(VISA/MasterCard/JCB/AMEX 等)を検出
電子その他 上記いずれも検出不能の場合
紙証憑 紙領 OCR テキストに「領収書/Receipt/領収印」を検出
紙請 OCR テキストに「請求書/Invoice/INV」を検出
紙その他 上記いずれも検出不能の場合
クレカ明細クレカ明細固定(UI 選択と同値)
通信費(月次)通信費(月次)固定(UI 選択と同値)
公租公課公租公課固定(UI 選択と同値)

旧データ移行時: 旧 H 列(電子領/電子請/紙領/紙請/クレカ明細/通信費(月次)/公租公課)をそのまま新 H 列に引き継ぎ、 新 G 列(5 大分類)は旧 H 値から逆引きして自動設定する。

証憑有無 B 列: 5 状態

表示意味判定条件
完全証憑 Drive ファイルあり かつ Freee deal の receipts[] が非空
Drive のみ Drive ファイルあり(Freee receipts なし)
Freee のみ Drive ファイルなし、Freee receipts あり
クレカ明細 証憑種別 = クレカ明細(実物証憑の代替)
なし Drive もなし / Freee receipts もなし

Freee receipts チェックは reconciler が /api/1/deals/{deal_id} を GET して確認。全行再計算は --update-coverage フラグで実行。

要確認 D 列: 9 種の判定

フラグ発火条件
金額不一致OCR 金額と Freee 金額が ±100 円超
日付差大OCR 日付と Freee 日付が ±7 日超
OCR 信頼度低confidence < 0.7
Freee 未連携reconciler 後も deal_id 未確定
Freee 未処理 rev3Freee deal あり(P 列 deal_id 確定)+ E 列「Freee 転記済」が空欄(=Freee UI で仕訳登録がまだ)。CEO が D 列フィルタで「やるべき仕訳作業」一覧が見える。
Drive リンク切れQ 列 ID で files.get が 404(週次チェック)
クレカ明細・追記要証憑種別=クレカ明細 + 備考(N 列)が空欄
公租公課要照合公租公課で対応 Freee deal 未確定
外貨換算未補完外貨ケースで I 列が空欄かつ Freee 連携あり

複数フラグが同時発火した場合は「金額不一致 / OCR 信頼度低」のように " / " で連結して D 列に入る。

双方向書込み + 三段ガード dedup

アップロード起点フロー

ファイル受信 → SHA256 計算 ├─ dedup 段 1(SHA256) ヒット → SKIP(既存行に Drive 情報追記のみ) ├─ OCR 実行 → dedup 段 2(date+amount+store) │ ├─ 既存行と (日付±3日 + 金額一致) → 既存行に P 列追記、新規行追加せず │ └─ マッチなし → 新規行追加(証憑有無=○)

Freee MCP 起点フロー(reconciler --create-missing)

全 Freee deals 取得 → 各 deal について: ├─ dedup 段 3(freee_deal_id) ヒット → SKIP ├─ スプシ O 列に同 deal_id → SKIP ├─ (日付±3日 + 金額一致) の既存行あり → 既存行に O 列追記(マージ) └─ マッチなし → 新規行追加(証憑有無=⚫ or ❌)

三段ガード dedup_index

1
段 1: SHA256 — ファイルバイトハッシュ完全一致。同一ファイルの再投入を確実にブロック。
2
段 2: OCR 3項 — (日付 ± 3日) + (金額一致) + (店舗名部分一致) でファイルの中身が同じかチェック。スキャン再送等をブロック。
3
段 3: Freee deal_id ★新 — deal_id が既に dedup_index に登録されていれば SKIP。Freee 起点での同 deal 二重行作成をブロック。

dedup_index.json スキーマ(v1.1)

{ "schema_version": "1.1", "entries": [ { "sha256": "abc123...", // 段 1 "amount_total": 1100, // 段 2 "date": "2026-05-21", // 段 2 "store_name": "テスト店舗", // 段 2 "store_name_normalized": "...", "freee_deal_id": "12345678", // 段 3 ★新 "drive_file_id": "1TDn5-...", "sheet_row": 9, "processed_at": "2026-05-28T09:00:00+09:00", "freee_attached": false, "source": "upload" | "freee" | "merged" // ★新 } ] }

段階導入ロードマップ

Phase期間内容コマンド例
Phase 1 2026/5 分のみ 双方向書込の動作実証(5 月分約 XX 件) python3 freee_reconciler_v3.py --backfill-period 2026-05-01 2026-05-31 --create-missing --update-coverage
Phase 2 Phase 1 OK 後 今期バックフィル(2025/7/1〜2026/4/30)全件スプシ反映 python3 freee_reconciler_v3.py --backfill-period 2025-07-01 2026-04-30 --create-missing
Phase 3 2026/7/1〜 来期完全運用(週次 LaunchAgent で自動化) LaunchAgent: reconcile_weekly(月曜 09:00)

Phase 1 実験の確認シナリオ

#シナリオ期待する B 列
1アップロード → OCR → スプシ追加 → reconciler で Freee 紐付け
2Freee 自動連携 → reconciler で空スプシ行作成 → 後日アップロードでマージ
3クレカ明細のみ
4Drive 証憑だけで Freee 未連携(現金等)
5Freee も Drive もなし(理論上 ❌ が出たらエラー検知)

バックフィル進捗の確認方法

バックフィル中は 5 分おきに Discord #finance-report に進捗投稿:

バックフィル進捗: 327/800 件処理 (40.9%) 内訳: Freee 起点 新規 280 / 既存マージ 47 / SKIP (重複) 0

整合性チェック

python3 freee_reconciler_v3.py \ --backfill-period 2026-05-01 2026-05-31 \ --verify-integrity

出力: Freee deals 件数 / スプシ行数 / dedup_index エントリ数 の三者比較。不一致時は Discord 通知。

マイグレーション手順(23列 → 21列)

# 1. dry-run(バックアップ + プレビュー) python3 migrate_to_21col.py dry-run # 2. CEO に dry-run 結果を提示・承認取得 # 3. execute(承認後) python3 migrate_to_21col.py execute # → 確認プロンプトで "yes" を入力 # 4. B 列(証憑有無)を補完 python3 freee_reconciler_v3.py --days 90 --update-coverage # 5. A 列(発生日)でソート python3 -c "from sheet_writer_v3 import sort_by_date_desc_v3; sort_by_date_desc_v3()" # ロールバック(問題が起きた場合) python3 migrate_to_21col.py rollback

バックアップ: _backups/<timestamp>_pre_21col_migration.json に自動保存。

LaunchAgent 4 件(稼働・追加)

Label実行タイミング内容状態
com.connect8.upan.run_pipeline 毎日 23:59 夜次パイプライン(全件 OCR + スプシ追記) 稼働中
com.connect8.upan.poller 5 分おき INBOX 監視(スタッフ投入ファイルを即時処理) 稼働中
com.connect8.upan.reconcile_weekly 月曜 09:00 週次 reconcile(--create-missing --update-coverage) 追加(load 要)
com.connect8.upan.sheet_sort_weekly 月曜 09:30 A 列(発生日)降順ソート(reconcile の 30 分後) 追加(load 要)

新規 LaunchAgent のインストール

# reconcile_weekly cp ~/claude/2_Areas/A10_corporate_finance/phase_b_reimbursement/com.connect8.upan.reconcile_weekly.plist \ ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/com.connect8.upan.reconcile_weekly.plist # sheet_sort_weekly cp ~/claude/2_Areas/A10_corporate_finance/phase_b_reimbursement/com.connect8.upan.sheet_sort_weekly.plist \ ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/com.connect8.upan.sheet_sort_weekly.plist # 稼働確認 launchctl list | grep upan

テストスイート

ファイル: test_sheet_redesign.py

cd ~/claude/2_Areas/A10_corporate_finance/phase_b_reimbursement python3 -m pytest test_sheet_redesign.py -v 79+ passed in 0.05s

テストカバレッジ

関連ファイル一覧

ファイル役割v3 対応
sheet_writer_v3.py21 列スプシ書込み(アップロード + Freee 起点)新規
freee_reconciler_v3.py照合 + --create-missing + --backfill-period + --verify-integrity新規
dedup_index_manager_v3.py三段 dedup(段 3: freee_deal_id 追加)新規
migrate_to_21col.py23 列 → 21 列マイグレーション(dry-run/execute/rollback)新規
test_sheet_redesign.py79+ 件テストスイート(H 列証憑形式 9 パターン + G/H 分割ロジック追加)新規
sheet_writer.py旧 23 列版(互換維持・非推奨)旧版
freee_reconciler.py旧 23 列照合(互換維持・非推奨)旧版
dedup_index_manager.py旧 二段 dedup(互換維持・非推奨)旧版

厳守ルール