[{"data":1,"prerenderedAt":483},["ShallowReactive",2],{"content-/2026-03-23-diary":3,"all-pages-for-dir":481,"og-image-/2026-03-23-diary":482},{"id":4,"title":5,"body":6,"category":462,"description":463,"extension":464,"meta":465,"navigation":466,"path":467,"project_name":468,"published":469,"publishedAt":470,"seo":471,"stem":472,"tags":473,"todo":479,"updatedAt":479,"__hash__":480},"pages/2026-03/2026-03-23/diary-2026-03-23.md","2026年3月23日の開発日記 - 会計Chrome拡張を一日かけて全面改修した",{"type":7,"value":8,"toc":448},"minimark",[9,14,18,22,27,39,45,67,78,81,85,88,92,106,114,116,120,131,135,150,158,160,164,167,171,185,193,195,198,387,389,392,425,427,430],[10,11,13],"h1",{"id":12},"_2026年3月23日の開発日記","2026年3月23日の開発日記",[15,16,17],"p",{},"朝6時台から夜まで、会計サービス連携Chrome拡張に張り付いた一日。テーブルデータ取得のバグ修正から始まり、UIの全面リファクタリング、事業者CTI管理の仕組み解明、仕訳帳エクスポート機能の新規実装まで、9セッションを費やした。",[19,20,21],"h2",{"id":21},"今日やったこと",[23,24,26],"h3",{"id":25},"_1-テーブルスクレイピングのバグ修正","1. テーブルスクレイピングのバグ修正",[15,28,29,30,34,35,38],{},"会計サービスの明細テーブルを取得する際に3つのバグが連鎖して発覚。",[31,32,33],"code",{},"cleanServiceName","の正規表現が「Square」をサービス名ごと消してしまう問題、",[31,36,37],{},"offsetHeight === 0","で非表示テーブル配下の行まで除外してしまう問題、フィルタ未適用時に全明細がマージされる問題を順に潰した。",[15,40,41],{},[42,43,44],"strong",{},"主な成果:",[46,47,48,58,64],"ul",{},[49,50,51,53,54,57],"li",{},[31,52,33],{},"に",[31,55,56],{},"(?=.*[\\d\\*])","条件を追加し、英字のみの名前を誤除去しない対策",[49,59,60,63],{},[31,61,62],{},"findDataTable","関数を新設し、標準テーブルが非表示なら代替テーブルを自動検出",[49,65,66],{},"明細全取得側だけ修正して、スプレッドシートインポート側を忘れて30分ロスした教訓",[15,68,69,72,73],{},[42,70,71],{},"詳細:"," ",[74,75,77],"a",{"href":76},"/mf-table-scraping-bug-fix","テーブルスクレイピングのバグ修正",[79,80],"hr",{},[23,82,84],{"id":83},"_2-ミラーカラムズuiリファクタリング","2. ミラーカラムズUIリファクタリング",[15,86,87],{},"タブUIで実装したら「ミラーカラムズにして」と即座に却下され、左ナビ+右コンテンツの2カラム構成に書き直した。デザインシステム（/design-principles/a/1）に準拠し、エクスポート/インポートを1パネルに統合、パネル切替時のリサイズを固定高さで抑制。",[15,89,90],{},[42,91,44],{},[46,93,94,97,100,103],{},[49,95,96],{},"ミラーカラムズレイアウトへの変換（左130px固定ナビ + 右コンテンツ）",[49,98,99],{},"サービス選択チップの展開表示（5件以下なのでスクロール不要）",[49,101,102],{},"URL自動保存（一括保存ボタン廃止→入力即保存）",[49,104,105],{},"OAuthクライアントIDの差し替え（bad client idエラー対応）",[15,107,108,72,110],{},[42,109,71],{},[74,111,113],{"href":112},"/mf-miller-columns-ui","Chrome拡張の会計連携UIをミラーカラムズに書き直した記録",[79,115],{},[23,117,119],{"id":118},"_3-事業者管理とcti年度切替の仕組み解明","3. 事業者管理とCTI年度切替の仕組み解明",[15,121,122,123,126,127,130],{},"Chrome DevTools MCPで会計サービスの内部構造を調査し、CTI（事業者ID）とTID（年度ID）の関係を発見。officesページの切替リンクにある",[31,124,125],{},"tid","がそのまま切替先の",[31,128,129],{},"cti","になるため、1回のfetchで全事業者の情報を取得できる。年度切替はRails UJSのPATCHリクエスト方式。",[15,132,133],{},[42,134,44],{},[46,136,137,140,143],{},[49,138,139],{},"全13事業者のCTI一括取得機能をChrome拡張に実装",[49,141,142],{},"chrome.storage.localでの事業者設定管理（JSON形式エクスポート/インポート対応）",[49,144,145,146,149],{},"年度切替PATCHの正しい送信方式（POST + ",[31,147,148],{},"_method=patch"," + authenticity_token）",[15,151,152,72,154],{},[42,153,71],{},[74,155,157],{"href":156},"/mf-cti-year-switching","事業者管理とCTI年度切替の仕組みを解析して実装した",[79,159],{},[23,161,163],{"id":162},"_4-仕訳帳エクスポートapi調査と実装","4. 仕訳帳エクスポートAPI調査と実装",[15,165,166],{},"REST API → サービス形式CSV → ハイブリッド方式と方針が3回変わった。REST APIでは作成者が取れず、サービス形式CSVでは開始仕訳が含まれない。結局、サービス形式CSVをメインにしてREST APIで開始仕訳だけ補完するハイブリッド方式に落ち着いた。",[15,168,169],{},[42,170,44],{},[46,172,173,176,179,182],{},[49,174,175],{},"サービス形式CSVエクスポートAPIのフロー解明（POST→302→/storage/files/{fid}）",[49,177,178],{},"ハイブリッド方式の実装（CSV + REST API開始仕訳補完）",[49,180,181],{},"純粋関数をlib.jsに分離し、39件のテストを追加",[49,183,184],{},"年度別一括エクスポート対応",[15,186,187,72,189],{},[42,188,71],{},[74,190,192],{"href":191},"/mf-journal-export-api","仕訳帳エクスポートのAPI調査と実装",[79,194],{},[19,196,197],{"id":197},"今日の試行錯誤",[199,200,201,223],"table",{},[202,203,204],"thead",{},[205,206,207,211,214,217,220],"tr",{},[208,209,210],"th",{},"#",[208,212,213],{},"テーマ",[208,215,216],{},"試したこと",[208,218,219],{},"結果",[208,221,222],{},"気づき",[224,225,226,246,265,282,302,319,336,353,370],"tbody",{},[205,227,228,232,235,240,243],{},[229,230,231],"td",{},"1",[229,233,234],{},"Squareの名前が消える",[229,236,237,239],{},[31,238,33],{},"の正規表現を確認",[229,241,242],{},"英字6文字がマッチ",[229,244,245],{},"口座番号除去は数字含有チェックが必須",[205,247,248,251,254,259,262],{},[229,249,250],{},"2",[229,252,253],{},"非表示行の除外",[229,255,256,258],{},[31,257,37],{},"で除外",[229,260,261],{},"非表示テーブル配下の行まで消える",[229,263,264],{},"DOMツリーの祖先要素の影響を忘れがち",[205,266,267,270,273,276,279],{},[229,268,269],{},"3",[229,271,272],{},"UIレイアウト",[229,274,275],{},"タブUIで実装",[229,277,278],{},"即却下",[229,280,281],{},"デザインシステムを先に確認すべきだった",[205,283,284,287,290,293,296],{},[229,285,286],{},"4",[229,288,289],{},"年度切替",[229,291,292],{},"fetchでPATCH送信",[229,294,295],{},"422エラー",[229,297,298,299,301],{},"Rails UJSはPOST + ",[31,300,148],{},"方式",[205,303,304,307,310,313,316],{},[229,305,306],{},"5",[229,308,309],{},"CDP接続",[229,311,312],{},"port 9222でChrome起動",[229,314,315],{},"ポート開かず",[229,317,318],{},"Workspace管理ポリシーがブロック",[205,320,321,324,327,330,333],{},[229,322,323],{},"6",[229,325,326],{},"仕訳帳API",[229,328,329],{},"REST API方式で実装",[229,331,332],{},"作成者が取れない",[229,334,335],{},"サーバーサイドCSVのみに含まれる情報がある",[205,337,338,341,344,347,350],{},[229,339,340],{},"7",[229,342,343],{},"サービス形式CSV",[229,345,346],{},"エクスポートAPIを叩く",[229,348,349],{},"開始仕訳が含まれない",[229,351,352],{},"サービスの仕様。REST APIで補完が必要",[205,354,355,358,361,364,367],{},[229,356,357],{},"8",[229,359,360],{},"CSVパース",[229,362,363],{},"Shift-JISでデコード",[229,365,366],{},"文字化け",[229,368,369],{},"UTF-8だった。先入観で決めつけない",[205,371,372,375,378,381,384],{},[229,373,374],{},"9",[229,376,377],{},"修正先の取り違え",[229,379,380],{},"明細全取得側を修正",[229,382,383],{},"スプレッドシート側は直ってない",[229,385,386],{},"拡張が2つある時は両方チェック",[79,388],{},[19,390,391],{"id":391},"今日の学び",[46,393,394,403,409,412,415],{},[49,395,396,397,399,400,402],{},"内部構造: CTIが事業者×年度の一意キー、officesページの",[31,398,125],{},"がそのまま",[31,401,129],{},"になる",[49,404,405,406,408],{},"Rails UJSの年度切替: 通常のPATCHではなくPOST + ",[31,407,148],{}," + CSRFトークンが必要",[49,410,411],{},"Chrome拡張の制約: バンドルファイル（defaults.json）にはランタイムで書き込めない。chrome.storage.localを使う",[49,413,414],{},"ハイブリッドAPI: 1つのAPIで全データが取れない時は、複数APIを組み合わせて補完する設計が有効",[49,416,417,418,420,421,424],{},"CSSの非表示判定: ",[31,419,37],{},"は祖先要素の",[31,422,423],{},"display:none","も拾ってしまう。可視性判定は慎重に",[79,426],{},[19,428,429],{"id":429},"関連記事",[46,431,432,436,440,444],{},[49,433,434],{},[74,435,77],{"href":76},[49,437,438],{},[74,439,113],{"href":112},[49,441,442],{},[74,443,157],{"href":156},[49,445,446],{},[74,447,192],{"href":191},{"title":449,"searchDepth":450,"depth":450,"links":451},"",2,[452,459,460,461],{"id":21,"depth":450,"text":21,"children":453},[454,456,457,458],{"id":25,"depth":455,"text":26},3,{"id":83,"depth":455,"text":84},{"id":118,"depth":455,"text":119},{"id":162,"depth":455,"text":163},{"id":197,"depth":450,"text":197},{"id":391,"depth":450,"text":391},{"id":429,"depth":450,"text":429},"diary","会計サービス連携Chrome拡張機能のテーブルスクレイピングバグ修正、ミラーカラムズUI改修、事業者CTI管理、仕訳帳エクスポートAPI実装まで、9セッション分の作業を記録","md",{},true,"/2026-03-23-diary","daily-log",false,"2026-03-23T00:00:00.000Z",{"title":5,"description":463},"2026-03/2026-03-23/diary-2026-03-23",[474,475,476,477,478],"日記","Chrome拡張機能","会計サービス","UI設計","API",null,"btYAFkhYrG8Y9dzXxMR2vGTQK0XbQq9BvacXRboJdGo",[],"https://log.eurekapu.com/favicon.svg",1778379976359]