[{"data":1,"prerenderedAt":338},["ShallowReactive",2],{"content-/edinet-quarterly-viewer-design":3,"all-pages-for-dir":336,"og-image-/edinet-quarterly-viewer-design":337},{"id":4,"title":5,"body":6,"category":315,"description":316,"extension":317,"meta":318,"navigation":319,"ogImage":320,"path":321,"project_name":322,"published":323,"publishedAt":324,"seo":325,"stem":326,"tags":327,"todo":334,"unpublished":323,"updatedAt":320,"__hash__":335},"pages/2026-04/2026-04-12/edinet-quarterly-viewer-design.md","EDINET四半期データビューアの設計とデータパイプライン -- Turso連携・Codexレビュー・セッション間データ受け渡し",{"type":7,"value":8,"toc":299},"minimark",[9,14,18,21,26,34,37,63,70,72,75,78,81,103,108,111,118,125,127,130,133,137,143,153,160,164,171,174,178,185,191,194,196,199,206,234,237,239,242,245,271,274,276,279],[10,11,13],"h1",{"id":12},"edinet四半期データビューアの設計とデータパイプライン","EDINET四半期データビューアの設計とデータパイプライン",[15,16,17],"p",{},"昨日までに年次データの可視化ページが動いていた。今日は「四半期も見たい」から始まって、データの取り方・渡し方で3回方針が揺れ、最終的に計画書と指示書を書き上げるところまで進んだ。コードは1行も書いていない。設計だけで半日が溶けた日。",[19,20],"hr",{},[22,23,25],"h2",{"id":24},"turso-embedded-replicaの使い分けを整理した","Turso Embedded Replicaの使い分けを整理した",[15,27,28,29,33],{},"朝一番の疑問は「edinet-apiディレクトリで取得したデータを、mdx-playgroundディレクトリでどう読むのか」だった。ローカルにSQLiteファイルがあり、Tursoのクラウドにもデータがある。",[30,31,32],"code",{},"turso-replicas"," というディレクトリも存在する。3つの場所にデータが散らばっている状態を整理するところから始めた。",[15,35,36],{},"確認した結果、構成は以下の通り。",[38,39,40,52,57],"ul",{},[41,42,43,47,48,51],"li",{},[44,45,46],"strong",{},"edinet-api",": EDINET DB APIを叩いてデータを取得し、ローカルSQLiteに保存。",[30,49,50],{},"turso db push"," でクラウドに同期",[41,53,54,56],{},[44,55,32],{},": Embedded Replicaのローカルキャッシュ。クラウドDBのミラーとして各プロジェクトから読み取り用に使う",[41,58,59,62],{},[44,60,61],{},"mdx-playground",": 表示側。クラウドのTursoDB（またはレプリカ）からデータを引いてJSONに変換し、フロントに渡す",[15,64,65,66,69],{},"プロジェクト間でデータを共有するには、クラウド側を経由するのが正解。edinet-api側でクラウドに同期した後、mdx-playground側でクラウドから ",[30,67,68],{},"sync"," すれば最新データがローカルレプリカに降りてくる。",[19,71],{},[22,73,74],{"id":74},"四半期ビューアの計画を立てた",[15,76,77],{},"年次データは既に2社分（会計ソフトA、会計ソフトB）がチャート表示できている。四半期を追加する方針を固めるため、計画書を作った。",[15,79,80],{},"骨子は以下の通り。",[38,82,83,86,89,96],{},[41,84,85],{},"右カラムに「年次 / 四半期」のタブ切替を追加",[41,87,88],{},"四半期タブには6つのチャートを2x3グリッドで並べる（売上高、営業利益+営業利益率、経常利益・純利益、BS、CF、純利益単独四半期）",[41,90,91,92,95],{},"データは ",[30,93,94],{},"data/edinet/E35325_quarterly.json"," のようなJSONファイルとして静的配置",[41,97,98,99,102],{},"既存の ",[30,100,101],{},"BaseComboChart"," コンポーネントをそのまま再利用",[104,105,107],"h3",{"id":106},"codexレビューで計画を修正した","Codexレビューで計画を修正した",[15,109,110],{},"Codexにプランを投げたところ、致命的な指摘が2つ返ってきた。",[15,112,113,114,117],{},"1つ目は",[44,115,116],{},"累計→単独値変換のテスト不足","。年次データでは113件のテストを書いたのに、四半期にはテストがない。「Q1+Q2+Q3+Q4の合計が年次PLに一致するか」を自動検証すべきだという指摘。これはそのまま計画に追加した。",[15,119,120,121,124],{},"2つ目は",[44,122,123],{},"四半期EPSの扱い","。四半期報告のEPSは累計値で、単純に差し引いても正しい単独四半期EPSにならない。加重平均株式数が四半期ごとに変わるからだ。この指摘を受けて、6つ目のチャートをEPSから「純利益（単独四半期）」に差し替えた。年次タブにEPSチャートがあるので、そちらで確認すれば足りる。",[19,126],{},[22,128,129],{"id":129},"データパイプラインの設計で3回揺れた",[15,131,132],{},"この日一番時間を使ったのが、四半期データをフロントまでどう届けるかの方式選定だった。3つの案を行ったり来たりした。",[104,134,136],{"id":135},"案1-turso-sync-json生成スクリプト","案1: Turso sync → JSON生成スクリプト",[15,138,139,140,142],{},"最初に固まった案。edinet-api側でAPIデータをTursoに格納済みなので、mdx-playground側でTursoクラウドから ",[30,141,68],{}," し、Pythonスクリプトで累計→単独値変換してJSONを吐く。",[144,145,150],"pre",{"className":146,"code":148,"language":149},[147],"language-text","edinet-api → Turso クラウドDB → mdx-playground側でsync → Python → JSON → Vue composable\n","text",[30,151,148],{"__ignoreMap":152},"",[15,154,155,156,159],{},"データの一元管理ができる。ただし、Tursoトークンが ",[30,157,158],{},".env"," にあるのでClaude Codeが直接スクリプトを実行できない。",[104,161,163],{"id":162},"案2-python直接json生成turso不要","案2: Python直接JSON生成（Turso不要）",[15,165,166,167,170],{},"途中で「確認しながら進めたい」と考え直した。Tursoを経由せず、EDINET DB APIを直接Pythonスクリプトで叩いてJSONを生成する案。ビルド不要で ",[30,168,169],{},"pnpm dev"," のホットリロードで即反映される点が魅力だった。",[15,172,173],{},"ただ冷静に考えると、edinet-api側に既にTursoへの格納パイプラインがある。同じAPIを二重に叩く意味がない。",[104,175,177],{"id":176},"案3採用-edinet-api側でturso格納-mdx-playground側でjson生成","案3（採用）: edinet-api側でTurso格納 → mdx-playground側でJSON生成",[15,179,180,181,184],{},"結局、案1に戻った。ただし、mdx-playground側のClaude Codeが自力でTursoDB接続するのが手間だったので、",[44,182,183],{},"edinet-api側のClaude Codeに指示書を渡してJSONを出力してもらう","方式に落ち着いた。",[144,186,189],{"className":187,"code":188,"language":149},[147],"edinet-api側Claude Code: Turso → 累計→単独値変換 → JSON出力\n↓（JSONファイルをmdx-playground/apps/web/data/edinet/ に配置）\nmdx-playground側Claude Code: JSONをimportしてVueで表示\n",[30,190,188],{"__ignoreMap":152},[15,192,193],{},"揺れた原因を振り返ると、「どこでデータ変換するか」と「誰がスクリプトを実行するか」が別の問題なのに、一緒に考えていたからだった。データの一元管理はTurso、変換の実行はedinet-api側のセッション、表示はmdx-playground側のセッション。役割を分けたら迷いが消えた。",[19,195],{},[22,197,198],{"id":198},"セッション間連携の指示書を書いた",[15,200,201,202,205],{},"edinet-api側のClaude Codeに渡す指示書を ",[30,203,204],{},"memo/2026-04-12/edinet-quarterly-data-export-instruction.md"," に作成した。盛り込んだ要素は以下の通り。",[38,207,208,211,214,225,228,231],{},[41,209,210],{},"対象企業のEDINETコードと期末月",[41,212,213],{},"APIエンドポイントのURL",[41,215,216,217,220,221,224],{},"出力JSON形式（年次JSONと同じ ",[30,218,219],{},"{ \"data\": [...] }"," 構造に ",[30,222,223],{},"quarter"," フィールドを追加）",[41,226,227],{},"累計→単独値の変換ルール（P/L・CFは差し引き、BSはそのまま）",[41,229,230],{},"フィールド一覧と優先度",[41,232,233],{},"検証ポイント（Q合計が年次に一致するか、BS貸借が合うか）",[15,235,236],{},"別セッションのClaude Codeに正確な仕事をしてもらうには、出力形式と検証条件を明示した指示書がいる。口頭で伝えると、フィールド名の揺れや変換ルールの曖昧さが入り込む。",[19,238],{},[22,240,241],{"id":241},"銘柄追加の手順を整理した",[15,243,244],{},"現在Tursoに入っているのは会計ソフトA（E33390）と会計ソフトB（E35325）の2社のみ。今後銘柄を追加するときの手順も計画書に盛り込んだ。",[246,247,248,251,258,261],"ol",{},[41,249,250],{},"EDINET検索APIでEDINETコードを調べる（認証不要）",[41,252,253,254,257],{},"edinet-api側の ",[30,255,256],{},"store_to_turso.py"," にコードを追加して6エンドポイント分を取得・格納",[41,259,260],{},"mdx-playground側でJSON生成スクリプトを実行",[41,262,263,266,267,270],{},[30,264,265],{},"types/edinet.ts"," の ",[30,268,269],{},"EDINET_COMPANIES"," 配列に企業メタデータを追加",[15,272,273],{},"手順をドキュメント化しておくと、次に銘柄を追加するときに「何をやるんだっけ」と手が止まらない。",[19,275],{},[22,277,278],{"id":278},"今日の学び",[38,280,281,287,293],{},[41,282,283,286],{},[44,284,285],{},"データの一元管理と変換の実行場所は別の問題","。Turso（一元管理）を使うかどうかと、どのセッションでスクリプトを走らせるかは独立した判断。混ぜて考えると方針が揺れる",[41,288,289,292],{},[44,290,291],{},"Codexレビューは設計段階で入れると効く","。テスト不足とEPS問題は、実装後に気づいていたら手戻りが大きかった。コードを書く前に計画書をレビューに出したのは正解",[41,294,295,298],{},[44,296,297],{},"別セッションへの指示書は「出力形式」と「検証条件」を書く","。ロジックの説明より、期待する成果物の仕様を正確に伝える方が結果が安定する",{"title":152,"searchDepth":300,"depth":300,"links":301},2,[302,303,307,312,313,314],{"id":24,"depth":300,"text":25},{"id":74,"depth":300,"text":74,"children":304},[305],{"id":106,"depth":306,"text":107},3,{"id":129,"depth":300,"text":129,"children":308},[309,310,311],{"id":135,"depth":306,"text":136},{"id":162,"depth":306,"text":163},{"id":176,"depth":306,"text":177},{"id":198,"depth":300,"text":198},{"id":241,"depth":300,"text":241},{"id":278,"depth":300,"text":278},"dev","四半期財務データの表示機能を設計する過程で、Turso Embedded Replicaの使い分け、データパイプラインの方式選定（Turso sync案→Python直接案→結局Turso→JSON案）、別セッションへの指示書作成までを記録","md",{},true,null,"/edinet-quarterly-viewer-design","financial-data",false,"2026-04-12T00:00:00.000Z",{"title":5,"description":316},"2026-04/2026-04-12/edinet-quarterly-viewer-design",[328,329,330,331,332,333],"EDINET","四半期データ","Turso","データパイプライン","設計","Codex","memo","zfgYuN3CvAt54i6fsD7d6hGZv7o52k6DHLG7189oW2A",[],"https://log.eurekapu.com/og/blog/edinet-quarterly-viewer-design.png?v=2026-04-12T00%3A00%3A00.000Z&title=EDINET%E5%9B%9B%E5%8D%8A%E6%9C%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%83%93%E3%83%A5%E3%83%BC%E3%82%A2%E3%81%AE%E8%A8%AD%E8%A8%88%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%20--%20Turso%E9%80%A3%E6%90%BA%E3%83%BBCodex%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%83%BB%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%93%E3%83%87%E3%83%BC%E3%82%BF%E5%8F%97%E3%81%91%E6%B8%A1%E3%81%97&author=Kei%20Komatsu&sig=41c60496bf8939c6",1782528826603]