← 一覧に戻る

MoneyForward → Zaim データ移行 設計 v2 (Zaim自動連携1年との重複整理)

2026年5月7日 21:52 更新

一言でいうと

直近1年は Zaim 自動連携、それ以前は MF データ。時間軸で完全分離して dedup 不要にする (案A)

v1 から何が変わったか

v1 (j-20260507-002 初稿) では「MFの過去データを丸ごと Zaim に引っ越す」前提で設計してた。健人 msg 5810 で本論点が追加:

v1 の前提 (見落とし)
MF全期間 → Zaim へ片方向移行。Zaim自動連携の遡及取得は意識せず
v2 の本論点
Zaim自動連携 (クレカ・銀行) は過去1年分を後追い取得できる。同じ1年分が MF にも蓄積されてる → 重複が発生する。これをどう捌く?

つまり「移行元」が MF だけじゃなく、Zaim 自身も別ルートで過去1年を取りに行く。この二重供給をどう設計するかが本丸だった。

論点1: 重複期間1年の取得先 — 3案比較

仕組みdedup必要?判定
案A: Zaim自動連携 1年 + MF 1年超 1年以内は Zaim 連携にお任せ、1年超だけ MF から変換投入。時間軸で完全分離 不要 推奨
案B: MF全期間 + Zaim自動連携停止 Zaim 連携を切って MF データのみ使う 不要 (連携停止のため) 却下
案C: ハイブリッド + SHA-256 dedup 1年以内も両方からデータ取得、ハッシュで重複弾き 必須 却下

なぜ案A 推奨か (根拠4点)

  1. 連携元の一次情報を信頼: Zaim 自動連携が記録する「お店」「金額」「日付」はクレカ会社/銀行のAPIから直接取った一次情報。MF 経由は MF が二次加工 (店名表記の正規化、カテゴリ推論等) を入れたもの。同じ取引でも表記が違う。一次情報の方が正確で新鮮
  2. SHA-256 dedup が実用上機能しない: v1 で重複防止に使ってた SHA-256 は [日付, 方法, 金額, 品目, メモ, お店] をハッシュする。Zaim自動連携と MF で「品目」「お店」の表記が違えば別ハッシュになり、重複として弾けない。案C は理論上きれいだが実運用で破綻する
  3. 境界管理が1点で済む: 案A なら「直近 T 日は Zaim 自動」「それ以前は MF」と1点で切れる (T = 連携先の遡及範囲)。案C は両方からデータ取って都度照合、運用が複雑
  4. 移行後の運用がそのまま続く: 移行完了後も Zaim 自動連携は止めないわけだから、案A の構造 (Zaim自動 + 必要に応じて MF データ) は移行後にも継承できる。案B は移行後に連携を再開する必要があり、運用切替が発生

案A の絵

時間軸: 過去 ―――――――――― [T日前] ―――――――― 今日
データ源: ── MF からCSV変換投入 ── | ── Zaim 自動連携 ──
dedup: 不要 (時間軸で完全分離。同じ取引が両方から来ない)

論点2: 期間境界 T の決め方

Zaim 自動連携の遡及範囲は 連携先 (クレカ会社・銀行) ごとに違う。たとえば:

連携先の例典型的な遡及範囲
クレカA社過去12ヶ月
クレカB社過去6ヶ月
銀行X過去3ヶ月
銀行Y過去13ヶ月

連携先ごとに別々の境界を持つこともできるけど、運用が複雑になる。推奨は T_min 統一方式:

T_min 統一方式 (推奨)

  1. Zaim 連携を全先 (クレカ・銀行) で設定
  2. 各連携先で取得できた「最古取引日」を確認
  3. その中で最も新しい (= 遡及が最短) 日T_min として確定
  4. MFカット日 D = T_min の前日
  5. MF データ取込は D 以前のみ

これで「全連携先が確実にカバーする期間」を Zaim 自動連携が、「それより前」を MF が担当する形になる。連携先によっては Zaim 自動が遡及範囲をオーバーランしてMFと重なる場合もあるけど、MF データを D でカットするから問題ない。

連携先別境界方式 (非推奨だが選択肢として)

連携先ごとに最古取引日を記録して、MF からの取込時に「クレカA関連は12ヶ月超だけ」「銀行Xは3ヶ月超だけ」と細かく切る方法。MF移行範囲が最大化されるが、変換スクリプトが連携先別ロジックを持つ必要があり、開発コストが跳ねる。健人が「過去1年弱の MF データはあきらめていい」なら T_min 統一で十分。

論点3: Suica取込 (j-507-001) との優先順位

Zaim 側のデータ流入経路は 3系統あり、これらが重複しないことを確認する必要がある:

系統担当範囲重複源
① Zaim 自動連携 (クレカ)直近 T_min 日のクレカ取引すべて。Suicaチャージも記録されるSuicaチャージ ⇔ Suica取込のチャージ行
② Zaim Suica 取込 (j-507-001)Suica 利用記録 (改札タッチ等) と現金チャージクレカチャージは ① と重複 → j-507-001 推奨案で「電子マネー入金」行を skip
③ MF 過去データ取込 (本ジョブ)D 以前の MF データ全て (Suica関連含む)① ② とは時間軸分離 (案A) で重複なし

三者の関係を時間軸で見ると

過去 ―――――――――――――――― [D=T_min前日] ――――――――― 今日

   ③ MF取込のみ                      ① Zaim自動連携(クレカ)
   (Suica関連も全部MF経由)            ② Zaim Suica取込
                                       (①との重複は j-507-001 で skip)

優先順位ルール (3系統の役割固定)

  1. D 以前 → ③ MF取込のみ。① ② は届かない範囲なので競合なし
  2. D 以降 → ① + ② の併用 (j-507-001 設計どおり)。③ は触らない
  3. 境界 D 当日 → MF データに含めない (前日まで)。Zaim 自動連携が当日分を拾う

これで Suica チャージが二重登録されるパスは閉じられる。健人の MF が Suica 連携してても、その記録は D 以前のみが Zaim に流れ込み、D 以降は Zaim 自動 + Suica取込の組合せで担当する。

論点4: 銀行口座連携も同じ問題か

同じ。整理は完全に揃う:

つまり論点1〜4 は単一フレームワーク (案A + T_min) で全てカバーできる。設計の追加複雑度はほぼゼロ。

v1 設計への影響 (差分)

v1 の MFカット日 D の定義
D = MF の最終取引日 (= 移行直前の今日付近)。MF 全期間が Zaim に入る
v2 の MFカット日 D の定義
D = (Zaim 自動連携の T_min) の前日。MF データは D 以前のみ取込。Zaim 自動連携が D+1 以降を担当 (これは v1 と同じ運用構造)

変換スクリプト (mf-to-zaim-csv.ts) には「日付 ≤ D の行のみ出力」という条件を1つ追加するだけ。importCsvHandler の重複防止3層 (運用カットオーバー / SHA-256 / 計算対象=0除外) はそのまま機能する。コード差分は最小限。

新しい移行手順 (v2)

事前準備 (健人手作業・30分)

  1. Zaim 連携を全先 (クレカ・銀行・電子マネー) で設定する。これがないと T_min が確定しない
  2. 連携完了後、各連携先で取得できた最古取引日を確認しスクショ (これが各連携先の遡及範囲)
  3. 全連携先で最も新しい最古取引日T_min として確定 → D = T_min の前日
  4. MF Web版にログイン → カットオーバー後のMF直近取引日が D 以降にあれば、Zaim自動連携でカバーされるからMFから移行不要
  5. プレミアム会員かどうか確認 (v1 と同じ。CSV取得手段の判断)

実装ジョブ (別建てで起票・2〜3時間、v1 から微増)

  1. v1 と同じく scripts/mf-to-zaim-csv.ts + src/lib/mfFallbackMap.ts + importCsvHandler 拡張 + テスト
  2. v2 追加: 変換スクリプトに --cutoff D オプションを追加。D 以前の行のみ出力 (それ以降はスキップ件数として表示)
  3. 1ヶ月分試験投入 → 全期間バルク投入

実投入 (健人手動・チバ伴走・1〜2時間、v1と同じ)

  1. MF から月別CSVをまとめて DL
  2. --cutoff D 付きで変換スクリプト実行 → D 以降の行は自動でスキップ
  3. 200行ずつ分割して /api/zaim/import-csv に POST
  4. レスポンスで件数確認、エラーがあれば再投入

統合チェックリスト (実装ジョブ起票前)

健人に確認したい計8点 (v1 の4点 + v2 の4点):

v1 から継続:

1. MFプレミアム会員か (未加入なら 500円課金 / Tampermonkey 判断)

2. 移行対象期間は何年分か (5年想定だが実データの古さで件数変わる)

3. 振替(口座間移動) は移行対象に含めるか (現状 importCsvHandler は振替を一律スキップ)

4. 重複検知キーの名前空間を Suica と MF で分けるか統合するか

v2 で追加:

5. Zaim 自動連携で連携する先のリスト (クレカ・銀行・電子マネー、何社あるか)

6. 各連携先の遡及範囲 (= T_min を決めるため。連携完了後にスクショ)

7. 案A で問題ないか (1年以内 Zaim自動 + 1年超 MF)。それとも B (連携停止) や C (ハイブリッド+dedup) を希望?

8. 境界方式: T_min 統一 (シンプル) と 連携先別 (移行範囲最大化、複雑) のどちらにするか

完了条件チェック (v2 dispatch)

#項目状態
1v1 設計を保ちつつ4論点追加で plan-viewer 更新完了 — 本ページ (v2 別ファイル並存)
2推奨案 (重複期間1年取得先) 選定 + 根拠完了 — 案A、根拠4点を §論点1 に
3期間境界の運用手順完了 — T_min 統一方式、§論点2 + §事前準備
4Suica取込 (j-507-001) 優先順位完了 — 三者の時間軸分離、§論点3
5金融機関連携の扱い完了 — クレカと同フレーム、§論点4
6v1 4点 + v2 4点 統合チェックリスト完了 — §統合チェックリスト
7verification_summary.result_summary v2 上書き完了 — /tmp/verification-j-20260507-002.txt

next_action: 健人が統合チェックリスト8点を回答 → 設計OK判定 → 実装ジョブ起票 (v1 範囲 + --cutoff D オプション追加)

← v1 (初稿) を見る

📝 質問モード — テキストを選択してね
✓ 質問を送信しました