eurekapu-nuxt4 全77ページ2カラム化 + Part 2 投資判断クイズ + 教科書 CH8-12 実装
朝イチ: Part 2 投資判断クイズの動作確認
まず昨日仕上げた Part 2 投資判断クイズ18ページが本当に動くか、Chrome DevTools を全ページに走らせた。結果は18ページ全部 HTTP 200、コンソールエラーゼロ。モバイル500px幅でも崩れないことを目視で確認した。
SVG が初期状態で「対応する図はありません」のプレースホルダーになっていて一瞬慌てたが、これは自分が前日に決めた仕様通り。回答するまで図を出さない設計で、回答後はマゼンタハイライトに切り替わる。ここは触らない。
TS型エラー 62件 → 0件
pnpm typecheck を走らせたら62件出てきた。1件は Part 2 由来だったが、リファクタの過程で既に消えていたので無視。
残りの構造を自分で眺めると、ほぼ2パターンに収束していた。
1件目は AnPerEmployeeHighlight 型の | null が原因で、ハンドラの分岐が網羅できないという指摘。型から | null を外すよう指示したら5件消えた。
56件は BS/PL 画面の同じパターンだと気づいた。
<div v-if="deltaPopups[key]">
{{ deltaPopups[key].id }} <!-- TS2532: Object is possibly 'undefined' -->
</div>
v-if でガードしているのに narrowing が効かない Vue + TS の既知パターン。1件ずつ書き換えるのは嫌なので、sed で deltaPopups[xxx].id を deltaPopups[xxx]!.id に一括置換してもらった。56件が一気に消えて、合計0件になった。
AnPerEmployee マゼンタハイライトで文字が消えるバグ
確認中に、ハイライト時のテキストが見えなくなる現象を画面で見つけた。ハイライト時にテキストすべてを #fff に塗っていて、白いボックスの中の白い文字が消滅していた。
該当箇所6つすべて #fff から #111 に戻すよう指示して、マゼンタ枠 + 黒文字の構成に直してもらった。これで読める。
全77ページの2カラム化
ここから本日のメインタスク。Part 2 の01ページで参考実装した2カラムレイアウトを、残り17ページに展開する方針を決めた。さらに practice-industry-quiz 系の5ページは別構造だったので、専用ラッパー PerQuizFigurePage を切って統一する設計に直した。
最終的に全77ページが3種類のラッパーに収まった。
- QuizPage を直接使う通常ページ
- InvestmentTopicPage(投資判断クイズ系の2カラム)
- PerQuizFigurePage(per-quiz 図対応の2カラム)
スクロールspy: 「見えているクイズの図」を出す
自分の一言で設計が変わった瞬間がここ。画面を触りながら「Q3にスクロールした時、答える前でもQ3に対応する図が左側に出てほしい」と感じて、その場で要件として投げた。
これまでは「回答済みクイズのうち最新のもの」をハイライトする設計にしていたが、スクロール位置で動的に切り替える方式に作り直すことに決めた。
QuizPage にスクロール追跡を入れて、slot に2つの prop を渡す設計に変えてもらった。
<slot
:visibleHighlight="currentVisibleHighlight"
:isVisibleAnswered="answered[currentVisibleQuizId]"
/>
これで「Q3にスクロールしたらQ3の図」「答えるとマゼンタになる」が両立する。実装後に自分でスクロールしてみると、図が切り替わる挙動は思った以上に気持ちいい。
目次に Part 1 / Part 2 の境界
連番だけだと CH7 と CH8 が直結して見えて、Part の切れ目が消えていることに気づいた。セクションヘッダで「Part 1: 財務諸表の読み方」「Part 2: 投資判断」と区切るよう指示したら、構造が一目で分かるようになった。
Part 2 教科書 CH8-12 を派遣
5/14 の handoff では「CH8-12 は別フェーズの大きな塊」として別日扱いだったが、勢いで今日着手することに決めた。Part 1 と同じパターンで、CH8 をパイロットで先行させて、CH9-12 をサブエージェント並列で派遣する段取りを組んだ。
最初は4並列でサブエージェントを派遣したら、Anthropic API が 529 Overloaded を返して全クラッシュした。2並列 × 2セットに減らして再派遣したら、これは通った。
書籍データの扱いで一つ判断した。当初は計画段階で Turso DB の書籍知識(Market Hack 本ほか)を参照させていたが、章立てが Eurekapu の指示書と似通っていることに気づいて、表面的にコピーする危険があると感じた。
書籍DB参照は CH8 のリライト段階に移すことに決めて、必ず Eurekapu の文脈(個人投資家向け、日本の投資環境)に合わせ直してから書かせる方針に切り替えた。Codex アプリに「指示書§4 を Eurekapu 文脈に書き換える提案」を頼み、返ってきた提案を自分で確認・承認したうえで4章分(CH8-12 v2.0)を派遣した。
全章 HTTP 200 を確認、3つに分割してコミットした。
- 実装ファイル
- 指示書改訂(§4 リライト)
- セキュリティ関連(後述)
Part 2 CH8-12 のレビュー計画書
書き上げた直後に質を担保したかったので、自分でレビュー計画書を起こした。観点は4つに絞った。
- 各章が独立した読み物として読めるか
- 数字のファクトチェック
- ロジカル構成(前章を引きずらない・次章へ繋ぐ)
- 日本語のAI臭除去
Codex に2回レビューを回した結果「致命的な指摘なし」まで到達した。最終的な実装は Codex アプリに担当させる方針に決めて、プロンプトを internal/ 配下に自分で保存しておいた。
EDINET APIキー漏洩の処理
夜にコミット履歴を眺めていたら、過去コミット d598c5f に EDINET の API キーが残っているのを自分で見つけてしまった。
すぐ EDINET の管理画面で revoke 済みを確認し、.gitignore に settings.local.json を追加するよう指示。Issue ファイルに経緯を自分で書いて「解決済み」のステータスで残した。今後の自分への踏み台として残しておく。
今日の振り返り
- 型エラー62件は、自分が2パターンに収束していると気づいて sed 一括置換に倒した。6文字書き換えるだけで0になった
- 4並列サブエージェント派遣は API Overloaded のリスクがあると体感した。書籍関連のような長文タスクは2並列が安全と判断した
- 書籍DB を「計画段階で読ませる」と章立てが寄ってしまうことに気づいた。「リライト段階で読ませる」が正解と決めた
- スクロール位置で図を切り替える設計は、自分が画面を触っていて出した一言から生まれた。実装後の体感は確かに気持ちいい
- API キー漏洩は即 revoke + .gitignore + Issue 記録の3点セットで動くと自分のルールに固めた
明日やること
- Part 2 CH8-12 v2.0 の最終チェックを Codex アプリに依頼
- レビュー観点(独立読み・ファクト・ロジカル・AI臭)を全章で再確認
- 書籍DB 参照ログを memo に残し、どの章でどの本を参照したかを追えるようにする