2026年3月23日の開発日記
朝6時台から夜まで、マネーフォワード連携Chrome拡張に張り付いた一日。テーブルデータ取得のバグ修正から始まり、UIの全面リファクタリング、事業者CTI管理の仕組み解明、仕訳帳エクスポート機能の新規実装まで、9セッションを費やした。
今日やったこと
1. テーブルスクレイピングのバグ修正
MFの明細テーブルを取得する際に3つのバグが連鎖して発覚。cleanServiceNameの正規表現が「Square」をサービス名ごと消してしまう問題、offsetHeight === 0で非表示テーブル配下の行まで除外してしまう問題、フィルタ未適用時に全明細がマージされる問題を順に潰した。
主な成果:
cleanServiceNameに(?=.*[\d\*])条件を追加し、英字のみの名前を誤除去しない対策findDataTable関数を新設し、標準テーブルが非表示なら代替テーブルを自動検出- MF_明細全取得側だけ修正して、MF_スプレッドシートインポート側を忘れて30分ロスした教訓
2. ミラーカラムズUIリファクタリング
タブUIで実装したら「ミラーカラムズにして」と即座に却下され、左ナビ+右コンテンツの2カラム構成に書き直した。デザインシステム(/design-principles/a/1)に準拠し、エクスポート/インポートを1パネルに統合、パネル切替時のリサイズを固定高さで抑制。
主な成果:
- ミラーカラムズレイアウトへの変換(左130px固定ナビ + 右コンテンツ)
- サービス選択チップの展開表示(5件以下なのでスクロール不要)
- URL自動保存(一括保存ボタン廃止→入力即保存)
- OAuthクライアントIDの差し替え(bad client idエラー対応)
詳細: Chrome拡張のMF連携UIをミラーカラムズに書き直した記録
3. 事業者管理とCTI年度切替の仕組み解明
Chrome DevTools MCPでMFの内部構造を調査し、CTI(事業者ID)とTID(年度ID)の関係を発見。officesページの切替リンクにあるtidがそのまま切替先のctiになるため、1回のfetchで全事業者の情報を取得できる。年度切替はRails UJSのPATCHリクエスト方式。
主な成果:
- 全13事業者のCTI一括取得機能をChrome拡張に実装
- chrome.storage.localでの事業者設定管理(JSON形式エクスポート/インポート対応)
- 年度切替PATCHの正しい送信方式(POST +
_method=patch+ authenticity_token)
詳細: 事業者管理とCTI年度切替の仕組みを解析して実装した
4. 仕訳帳エクスポートAPI調査と実装
REST API → MF形式CSV → ハイブリッド方式と方針が3回変わった。REST APIでは作成者が取れず、MF形式CSVでは開始仕訳が含まれない。結局、MF形式CSVをメインにしてREST APIで開始仕訳だけ補完するハイブリッド方式に落ち着いた。
主な成果:
- MF形式CSVエクスポートAPIのフロー解明(POST→302→/storage/files/{fid})
- ハイブリッド方式の実装(CSV + REST API開始仕訳補完)
- 純粋関数をlib.jsに分離し、39件のテストを追加
- 年度別一括エクスポート対応
詳細: MoneyForward仕訳帳エクスポートのAPI調査と実装
今日の試行錯誤
| # | テーマ | 試したこと | 結果 | 気づき |
|---|---|---|---|---|
| 1 | Squareの名前が消える | cleanServiceNameの正規表現を確認 | 英字6文字がマッチ | 口座番号除去は数字含有チェックが必須 |
| 2 | 非表示行の除外 | offsetHeight === 0で除外 | 非表示テーブル配下の行まで消える | DOMツリーの祖先要素の影響を忘れがち |
| 3 | UIレイアウト | タブUIで実装 | 即却下 | デザインシステムを先に確認すべきだった |
| 4 | 年度切替 | fetchでPATCH送信 | 422エラー | Rails UJSはPOST + _method=patch方式 |
| 5 | CDP接続 | port 9222でChrome起動 | ポート開かず | Workspace管理ポリシーがブロック |
| 6 | 仕訳帳API | REST API方式で実装 | 作成者が取れない | サーバーサイドCSVのみに含まれる情報がある |
| 7 | MF形式CSV | エクスポートAPIを叩く | 開始仕訳が含まれない | MFの仕様。REST APIで補完が必要 |
| 8 | CSVパース | Shift-JISでデコード | 文字化け | UTF-8だった。先入観で決めつけない |
| 9 | 修正先の取り違え | MF_明細全取得側を修正 | スプレッドシート側は直ってない | 拡張が2つある時は両方チェック |
今日の学び
- MFの内部構造: CTIが事業者×年度の一意キー、officesページの
tidがそのままctiになる - Rails UJSの年度切替: 通常のPATCHではなくPOST +
_method=patch+ CSRFトークンが必要 - Chrome拡張の制約: バンドルファイル(defaults.json)にはランタイムで書き込めない。chrome.storage.localを使う
- ハイブリッドAPI: 1つのAPIで全データが取れない時は、複数APIを組み合わせて補完する設計が有効
- CSSの非表示判定:
offsetHeight === 0は祖先要素のdisplay:noneも拾ってしまう。可視性判定は慎重に