[{"data":1,"prerenderedAt":444},["ShallowReactive",2],{"content-/eurekapu-2col-and-part2-textbook":3,"all-pages-for-dir":442,"og-image-/eurekapu-2col-and-part2-textbook":443},{"id":4,"title":5,"body":6,"category":424,"description":425,"extension":426,"meta":427,"navigation":392,"ogImage":428,"path":429,"project_name":430,"published":431,"publishedAt":432,"seo":433,"stem":434,"tags":435,"todo":428,"unpublished":431,"updatedAt":428,"__hash__":441},"pages/2026-05/2026-05-15/eurekapu-2col-and-textbook.md","eurekapu-nuxt4 全77ページ2カラム化 + Part 2 投資判断クイズ + 教科書 CH8-12 実装",{"type":7,"value":8,"toc":411},"minimark",[9,13,18,22,25,29,36,39,53,56,122,136,140,147,157,160,171,174,187,191,194,197,203,263,266,270,273,277,280,288,291,294,297,308,312,315,329,336,340,347,358,361,378,381,407],[10,11,5],"h1",{"id":12},"eurekapu-nuxt4-全77ページ2カラム化-part-2-投資判断クイズ-教科書-ch8-12-実装",[14,15,17],"h2",{"id":16},"朝イチ-part-2-投資判断クイズの動作確認","朝イチ: Part 2 投資判断クイズの動作確認",[19,20,21],"p",{},"まず昨日仕上げた Part 2 投資判断クイズ18ページが本当に動くか、Chrome DevTools を全ページに走らせた。結果は18ページ全部 HTTP 200、コンソールエラーゼロ。モバイル500px幅でも崩れないことを目視で確認した。",[19,23,24],{},"SVG が初期状態で「対応する図はありません」のプレースホルダーになっていて一瞬慌てたが、これは自分が前日に決めた仕様通り。回答するまで図を出さない設計で、回答後はマゼンタハイライトに切り替わる。ここは触らない。",[14,26,28],{"id":27},"ts型エラー-62件-0件","TS型エラー 62件 → 0件",[19,30,31,35],{},[32,33,34],"code",{},"pnpm typecheck"," を走らせたら62件出てきた。1件は Part 2 由来だったが、リファクタの過程で既に消えていたので無視。",[19,37,38],{},"残りの構造を自分で眺めると、ほぼ2パターンに収束していた。",[19,40,41,42,45,46,49,50,52],{},"1件目は ",[32,43,44],{},"AnPerEmployeeHighlight"," 型の ",[32,47,48],{},"| null"," が原因で、ハンドラの分岐が網羅できないという指摘。型から ",[32,51,48],{}," を外すよう指示したら5件消えた。",[19,54,55],{},"56件は BS/PL 画面の同じパターンだと気づいた。",[57,58,63],"pre",{"className":59,"code":60,"language":61,"meta":62,"style":62},"language-vue shiki shiki-themes vitesse-light vitesse-light","\u003Cdiv v-if=\"deltaPopups[key]\">\n  {{ deltaPopups[key].id }}  \u003C!-- TS2532: Object is possibly 'undefined' -->\n\u003C/div>\n","vue","",[32,64,65,105,112],{"__ignoreMap":62},[66,67,70,74,78,81,84,87,91,94,97,100,102],"span",{"class":68,"line":69},"line",1,[66,71,73],{"class":72},"shFtX","\u003C",[66,75,77],{"class":76},"sHkkW","div",[66,79,80],{"class":76}," v-if",[66,82,83],{"class":72},"=",[66,85,86],{"class":72},"\"",[66,88,90],{"class":89},"s4oTP","deltaPopups",[66,92,93],{"class":72},"[",[66,95,96],{"class":89},"key",[66,98,99],{"class":72},"]",[66,101,86],{"class":72},[66,103,104],{"class":72},">\n",[66,106,108],{"class":68,"line":107},2,[66,109,111],{"class":110},"sG7-3","  {{ deltaPopups[key].id }}  \u003C!-- TS2532: Object is possibly 'undefined' -->\n",[66,113,115,118,120],{"class":68,"line":114},3,[66,116,117],{"class":72},"\u003C/",[66,119,77],{"class":76},[66,121,104],{"class":72},[19,123,124,127,128,131,132,135],{},[32,125,126],{},"v-if"," でガードしているのに narrowing が効かない Vue + TS の既知パターン。1件ずつ書き換えるのは嫌なので、sed で ",[32,129,130],{},"deltaPopups[xxx].id"," を ",[32,133,134],{},"deltaPopups[xxx]!.id"," に一括置換してもらった。56件が一気に消えて、合計0件になった。",[14,137,139],{"id":138},"anperemployee-マゼンタハイライトで文字が消えるバグ","AnPerEmployee マゼンタハイライトで文字が消えるバグ",[19,141,142,143,146],{},"確認中に、ハイライト時のテキストが見えなくなる現象を画面で見つけた。ハイライト時にテキストすべてを ",[32,144,145],{},"#fff"," に塗っていて、白いボックスの中の白い文字が消滅していた。",[19,148,149,150,152,153,156],{},"該当箇所6つすべて ",[32,151,145],{}," から ",[32,154,155],{},"#111"," に戻すよう指示して、マゼンタ枠 + 黒文字の構成に直してもらった。これで読める。",[14,158,159],{"id":159},"全77ページの2カラム化",[19,161,162,163,166,167,170],{},"ここから本日のメインタスク。Part 2 の01ページで参考実装した2カラムレイアウトを、残り17ページに展開する方針を決めた。さらに ",[32,164,165],{},"practice-industry-quiz"," 系の5ページは別構造だったので、専用ラッパー ",[32,168,169],{},"PerQuizFigurePage"," を切って統一する設計に直した。",[19,172,173],{},"最終的に全77ページが3種類のラッパーに収まった。",[175,176,177,181,184],"ul",{},[178,179,180],"li",{},"QuizPage を直接使う通常ページ",[178,182,183],{},"InvestmentTopicPage（投資判断クイズ系の2カラム）",[178,185,186],{},"PerQuizFigurePage（per-quiz 図対応の2カラム）",[14,188,190],{"id":189},"スクロールspy-見えているクイズの図を出す","スクロールspy: 「見えているクイズの図」を出す",[19,192,193],{},"自分の一言で設計が変わった瞬間がここ。画面を触りながら「Q3にスクロールした時、答える前でもQ3に対応する図が左側に出てほしい」と感じて、その場で要件として投げた。",[19,195,196],{},"これまでは「回答済みクイズのうち最新のもの」をハイライトする設計にしていたが、スクロール位置で動的に切り替える方式に作り直すことに決めた。",[19,198,199,202],{},[32,200,201],{},"QuizPage"," にスクロール追跡を入れて、slot に2つの prop を渡す設計に変えてもらった。",[57,204,206],{"className":59,"code":205,"language":61,"meta":62,"style":62},"\u003Cslot\n  :visibleHighlight=\"currentVisibleHighlight\"\n  :isVisibleAnswered=\"answered[currentVisibleQuizId]\"\n/>\n",[32,207,208,215,234,257],{"__ignoreMap":62},[66,209,210,212],{"class":68,"line":69},[66,211,73],{"class":72},[66,213,214],{"class":76},"slot\n",[66,216,217,220,224,226,228,231],{"class":68,"line":107},[66,218,219],{"class":72},"  :",[66,221,223],{"class":222},"senZ8","visibleHighlight",[66,225,83],{"class":72},[66,227,86],{"class":72},[66,229,230],{"class":89},"currentVisibleHighlight",[66,232,233],{"class":72},"\"\n",[66,235,236,238,241,243,245,248,250,253,255],{"class":68,"line":114},[66,237,219],{"class":72},[66,239,240],{"class":222},"isVisibleAnswered",[66,242,83],{"class":72},[66,244,86],{"class":72},[66,246,247],{"class":89},"answered",[66,249,93],{"class":72},[66,251,252],{"class":89},"currentVisibleQuizId",[66,254,99],{"class":72},[66,256,233],{"class":72},[66,258,260],{"class":68,"line":259},4,[66,261,262],{"class":110},"/>\n",[19,264,265],{},"これで「Q3にスクロールしたらQ3の図」「答えるとマゼンタになる」が両立する。実装後に自分でスクロールしてみると、図が切り替わる挙動は思った以上に気持ちいい。",[14,267,269],{"id":268},"目次に-part-1-part-2-の境界","目次に Part 1 / Part 2 の境界",[19,271,272],{},"連番だけだと CH7 と CH8 が直結して見えて、Part の切れ目が消えていることに気づいた。セクションヘッダで「Part 1: 財務諸表の読み方」「Part 2: 投資判断」と区切るよう指示したら、構造が一目で分かるようになった。",[14,274,276],{"id":275},"part-2-教科書-ch8-12-を派遣","Part 2 教科書 CH8-12 を派遣",[19,278,279],{},"5/14 の handoff では「CH8-12 は別フェーズの大きな塊」として別日扱いだったが、勢いで今日着手することに決めた。Part 1 と同じパターンで、CH8 をパイロットで先行させて、CH9-12 をサブエージェント並列で派遣する段取りを組んだ。",[19,281,282,283,287],{},"最初は4並列でサブエージェントを派遣したら、Anthropic API が ",[284,285,286],"strong",{},"529 Overloaded"," を返して全クラッシュした。2並列 × 2セットに減らして再派遣したら、これは通った。",[19,289,290],{},"書籍データの扱いで一つ判断した。当初は計画段階で Turso DB の書籍知識（Market Hack 本ほか）を参照させていたが、章立てが Eurekapu の指示書と似通っていることに気づいて、表面的にコピーする危険があると感じた。",[19,292,293],{},"書籍DB参照は CH8 のリライト段階に移すことに決めて、必ず Eurekapu の文脈（個人投資家向け、日本の投資環境）に合わせ直してから書かせる方針に切り替えた。Codex アプリに「指示書§4 を Eurekapu 文脈に書き換える提案」を頼み、返ってきた提案を自分で確認・承認したうえで4章分（CH8-12 v2.0）を派遣した。",[19,295,296],{},"全章 HTTP 200 を確認、3つに分割してコミットした。",[175,298,299,302,305],{},[178,300,301],{},"実装ファイル",[178,303,304],{},"指示書改訂（§4 リライト）",[178,306,307],{},"セキュリティ関連（後述）",[14,309,311],{"id":310},"part-2-ch8-12-のレビュー計画書","Part 2 CH8-12 のレビュー計画書",[19,313,314],{},"書き上げた直後に質を担保したかったので、自分でレビュー計画書を起こした。観点は4つに絞った。",[175,316,317,320,323,326],{},[178,318,319],{},"各章が独立した読み物として読めるか",[178,321,322],{},"数字のファクトチェック",[178,324,325],{},"ロジカル構成（前章を引きずらない・次章へ繋ぐ）",[178,327,328],{},"日本語のAI臭除去",[19,330,331,332,335],{},"Codex に2回レビューを回した結果「致命的な指摘なし」まで到達した。最終的な実装は Codex アプリに担当させる方針に決めて、プロンプトを ",[32,333,334],{},"internal/"," 配下に自分で保存しておいた。",[14,337,339],{"id":338},"edinet-apiキー漏洩の処理","EDINET APIキー漏洩の処理",[19,341,342,343,346],{},"夜にコミット履歴を眺めていたら、過去コミット ",[32,344,345],{},"d598c5f"," に EDINET の API キーが残っているのを自分で見つけてしまった。",[19,348,349,350,353,354,357],{},"すぐ EDINET の管理画面で revoke 済みを確認し、",[32,351,352],{},".gitignore"," に ",[32,355,356],{},"settings.local.json"," を追加するよう指示。Issue ファイルに経緯を自分で書いて「解決済み」のステータスで残した。今後の自分への踏み台として残しておく。",[14,359,360],{"id":360},"今日の振り返り",[175,362,363,366,369,372,375],{},[178,364,365],{},"型エラー62件は、自分が2パターンに収束していると気づいて sed 一括置換に倒した。6文字書き換えるだけで0になった",[178,367,368],{},"4並列サブエージェント派遣は API Overloaded のリスクがあると体感した。書籍関連のような長文タスクは2並列が安全と判断した",[178,370,371],{},"書籍DB を「計画段階で読ませる」と章立てが寄ってしまうことに気づいた。「リライト段階で読ませる」が正解と決めた",[178,373,374],{},"スクロール位置で図を切り替える設計は、自分が画面を触っていて出した一言から生まれた。実装後の体感は確かに気持ちいい",[178,376,377],{},"API キー漏洩は即 revoke + .gitignore + Issue 記録の3点セットで動くと自分のルールに固めた",[14,379,380],{"id":380},"明日やること",[175,382,385,395,401],{"className":383},[384],"contains-task-list",[178,386,389,394],{"className":387},[388],"task-list-item",[390,391],"input",{"disabled":392,"type":393},true,"checkbox"," Part 2 CH8-12 v2.0 の最終チェックを Codex アプリに依頼",[178,396,398,400],{"className":397},[388],[390,399],{"disabled":392,"type":393}," レビュー観点（独立読み・ファクト・ロジカル・AI臭）を全章で再確認",[178,402,404,406],{"className":403},[388],[390,405],{"disabled":392,"type":393}," 書籍DB 参照ログを memo に残し、どの章でどの本を参照したかを追えるようにする",[408,409,410],"style",{},"html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}",{"title":62,"searchDepth":107,"depth":107,"links":412},[413,414,415,416,417,418,419,420,421,422,423],{"id":16,"depth":107,"text":17},{"id":27,"depth":107,"text":28},{"id":138,"depth":107,"text":139},{"id":159,"depth":107,"text":159},{"id":189,"depth":107,"text":190},{"id":268,"depth":107,"text":269},{"id":275,"depth":107,"text":276},{"id":310,"depth":107,"text":311},{"id":338,"depth":107,"text":339},{"id":360,"depth":107,"text":360},{"id":380,"depth":107,"text":380},"dev","投資判断クイズ18ページの動作確認から始まり、TS型エラー62件をsed一括置換で0に潰し、77ページを2カラム化、Part 2 教科書 CH8-12 をサブエージェント並列で派遣して仕上げた1日","md",{},null,"/eurekapu-2col-and-part2-textbook","eurekapu-nuxt4",false,"2026-05-15T00:00:00.000Z",{"title":5,"description":425},"2026-05/2026-05-15/eurekapu-2col-and-textbook",[430,436,437,438,439,440],"vue3","typescript","claude-code","subagent","refactoring","vfqKo3yjHal6zdpBunfjhWeYkdGNrLlgdqQdYsqTLGo",[],"https://log.eurekapu.com/og/blog/eurekapu-2col-and-part2-textbook.png?v=2026-05-15T00%3A00%3A00.000Z&title=eurekapu-nuxt4%20%E5%85%A877%E3%83%9A%E3%83%BC%E3%82%B82%E3%82%AB%E3%83%A9%E3%83%A0%E5%8C%96%20%2B%20Part%202%20%E6%8A%95%E8%B3%87%E5%88%A4%E6%96%AD%E3%82%AF%E3%82%A4%E3%82%BA%20%2B%20%E6%95%99%E7%A7%91%E6%9B%B8%20CH8-12%20%E5%AE%9F%E8%A3%85&author=Kei%20Komatsu&sig=4e8c76105624accd",1782528836738]