[{"data":1,"prerenderedAt":671},["ShallowReactive",2],{"content-/2026-05-15-diary":3,"all-pages-for-dir":669,"og-image-/2026-05-15-diary":670},{"id":4,"title":5,"body":6,"category":648,"description":649,"extension":650,"meta":651,"navigation":554,"ogImage":652,"path":653,"project_name":654,"published":655,"publishedAt":656,"seo":657,"stem":658,"tags":659,"todo":652,"unpublished":655,"updatedAt":652,"__hash__":668},"pages/2026-05/2026-05-15/diary-2026-05-15.md","2026年5月15日の開発日記 - 都道府県クイズ12ページ完成・地図クイズ4種・eurekapu 77ページ2カラム化・yomitoku 0.13.0 まで",{"type":7,"value":8,"toc":631},"minimark",[9,14,23,27,34,37,42,57,65,76,79,83,102,105,113,115,119,142,145,153,155,159,169,180,188,190,194,204,222,225,233,235,238,470,472,475,538,540,543,598,600,603],[10,11,13],"h1",{"id":12},"_2026年5月15日の開発日記","2026年5月15日の開発日記",[15,16,17,18,22],"p",{},"朝6時から動き始めて、都道府県クイズの統計編12ページ（合計89問）と地図クイズ4種（by-prefecture / find-prefecture / 地形図モード / study-map）を1日で組み上げた。途中で「神経衰弱」を作らせたら却下されて全削除、ずんだもん音声を VOICEVOX 直接呼び出しから事前生成 MP3 + Cloudflare R2 配信に切り替え、Codex のプランレビューで合計21件以上の致命的指摘を拾って全件潰すという長丁場。並行して eurekapu-nuxt4 では全77ページ2カラム化と Part 2 教科書 CH8-12 をサブエージェント派遣、yomitoku 0.13.0 アップグレード、自炊書籍1冊（235ページの問題集）の OCR 取り込みまで進めた。最後は本番が404のまま全デプロイ失敗していた wrangler 問題を、4.91.0 更新と ",[19,20,21],"code",{},"--commit-message"," ASCII 固定で復旧して締めた。",[24,25,26],"h2",{"id":26},"今日のタイムライン",[15,28,29],{},[30,31],"img",{"alt":32,"src":33},"タイムライン","/2026-05/2026-05-15/timeline-2026-05-15.png",[24,35,36],{"id":36},"今日やったこと",[38,39,41],"h3",{"id":40},"_1-都道府県クイズ統計編-12ページ完成5589問","1. 都道府県クイズ統計編 12ページ完成（55→89問）",[15,43,44,45,48,49,52,53,56],{},"朝の段階では Phase 1 の4ページ24問しか手元になかった。共通composable ",[19,46,47],{},"usePrefectureQuiz"," に復習モード（localStorage で正誤保存→「未正解のみ」フィルター）を抽出させて4ページに展開し、Phase 2（人口・地理）、Phase 3（製造業・貿易港・財政・地価）、Phase 4（観光・教育・防災）と順に積んでいった。非加算指標（地価円/m²など）のため ",[19,50,51],{},"QuizQuestion"," 型に ",[19,54,55],{},"totalLabel?"," を追加してフッター表示を切り替える設計にした。さらに Phase 8 で全12ページに増問させて 55→89問（+34問）に拡張。",[15,58,59,60,64],{},"Codex（gpt-5.5）に通したら ",[61,62,63],"strong",{},"10件の致命的誤り","（県内総生産 total、海岸線延長順序、港湾コンテナ統一、最深積雪、活火山数、平均標高順序、人口密度解説の自己矛盾など）が出てきて全件修正させた。「フェーズ」表記は子供にとって分かりにくいので、本番向けに「📊 統計クイズ」「🗾 地図クイズ」の2カテゴリ表示に整理し直した。",[15,66,67,70,71],{},[61,68,69],{},"詳細:"," ",[72,73,75],"a",{"href":74},"/prefecture-quiz-statistics-12pages","都道府県クイズに統計編12ページを増設し、89問へ拡張した日",[77,78],"hr",{},[38,80,82],{"id":81},"_2-都道府県クイズ-地図クイズ4種を実装","2. 都道府県クイズ 地図クイズ4種を実装",[15,84,85,86,89,90,93,94,97,98,101],{},"Phase 5 で「県→特徴 逆引きクイズ」（by-prefecture）。最初は path 別になっていない Wikimedia SVG で簡略タイル地図にしていたが、Geolonia の ",[19,87,88],{},"japan-prefectures.svg","（GFDL、47県が ",[19,91,92],{},"\u003Cg class=\"hokkaido prefecture\" data-code=\"01\">"," でグループ化）に差し替えた。Phase 6A で「白地図クリック型」（find-prefecture）、6B で「地形図モード」（標高ティア段彩 CSS）。Phase 7 は「神経衰弱」を完成させたあとで、自分から「意図は地図クリックで県名カードを開閉する学習モードだった」と方針転換を入れて ",[19,95,96],{},"memory-game.vue"," を全削除させ、",[19,99,100],{},"study-map.vue"," を作り直してもらった。",[15,103,104],{},"find-prefecture には「直近3回の正誤」を localStorage に保存する履歴管理＋連続誤答フィルター、地方別8チップでの色分けも追加させた。",[15,106,107,70,109],{},[61,108,69],{},[72,110,112],{"href":111},"/prefecture-quiz-map-modes","都道府県クイズに地図モードを4つ追加してずんだもん音声をR2配信に乗せた",[77,114],{},[38,116,118],{"id":117},"_3-eurekapu-nuxt4-全77ページ2カラム化-part-2-教科書-ch8-12","3. eurekapu-nuxt4 全77ページ2カラム化 + Part 2 教科書 CH8-12",[15,120,121,122,125,126,129,130,133,134,137,138,141],{},"朝の段階で Part 2 投資判断クイズ18ページの動作確認、TS型エラー 62件を sed で ",[19,123,124],{},"!.id"," 一括置換してもらって 0件に。",[19,127,128],{},"AnPerEmployee.vue"," のマゼンタハイライト時に白い箱の中の文字が消えるバグも潰した。そのあと、投資判断クイズの2カラム化を残り17ページに展開させ、別構造の ",[19,131,132],{},"practice-industry-quiz"," など5ページも ",[19,135,136],{},"PerQuizFigurePage"," ラッパーで統一して ",[61,139,140],{},"全77ページ2カラム化"," 完了。スクロール spy で visible quiz の図を出す設計も足した。",[15,143,144],{},"Part 2 教科書 CH8-12 はサブエージェント並列で書かせた。CH8 をパイロットで先行、CH9-12 を並列起動。ただし4並列で派遣したら API Error 529 Overloaded で全クラッシュしたので 2並列×2セットに切り替え。当初は計画段階で書籍 Turso DB を裏読みさせていたため章立てが似ていた件を Codex に指摘されて、CH8-12 を Eurekapu 文脈にリライトさせた。",[15,146,147,70,149],{},[61,148,69],{},[72,150,152],{"href":151},"/eurekapu-2col-and-part2-textbook","eurekapu-nuxt4 全77ページ2カラム化 + Part 2 投資判断クイズ + 教科書 CH8-12 実装",[77,154],{},[38,156,158],{"id":157},"_4-yomitoku-0130-アップグレード-自炊書籍-ocr","4. yomitoku 0.13.0 アップグレード + 自炊書籍 OCR",[15,160,161,162,165,166,168],{},"GitHub で yomitoku v0.13.0 が出ているのに気づいてアップグレード。",[19,163,164],{},"pyproject.toml"," 経由で更新したら torch が CUDA版（2.7.1+cu118）→ CPU版（2.12.0）に置き換わって速度が落ちる落とし穴を踏んだ。PyTorch CUDA インデックス設定を ",[19,167,164],{}," に追加させて GPU 版に戻した。",[15,170,171,172,175,176,179],{},"午後に自炊した1冊（235ページの問題集）を OCR に流した。GPU 処理で6分で完了したが、紙面の各ページに縦書きで「第N章 章名」のタブが印刷されていて全文に混入する問題に気づいた。「3個以上の章名が連続するブロックを検出して除去」する正規表現を ",[19,173,174],{},"yomitoku_import.py"," の前処理に追加させ、235ページ → 211チャンク → restructure-book で ",[61,177,178],{},"45セクション"," に統合して Turso DB（book-knowledge-base）に格納させた。",[15,181,182,70,184],{},[61,183,69],{},[72,185,187],{"href":186},"/yomitoku-and-textbook-ocr","yomitoku 0.13.0 アップグレードと自炊書籍の OCR 取り込み",[77,189],{},[38,191,193],{"id":192},"_5-テスト失敗修正cloudflareデプロイ復旧公開記事3本","5. テスト失敗修正・Cloudflareデプロイ復旧・公開記事3本",[15,195,196,199,200,203],{},[19,197,198],{},"pnpm test:run"," で26件失敗していたのを、A-1（keydownハンドラに修飾キーガード1行）と A-2（共通composable ",[19,201,202],{},"useQuizSeoMeta"," を作って各ページに1行追加）で計123件パスに持っていってもらった。",[15,205,206,207,210,211,214,215,217,218,221],{},"夕方に「",[19,208,209],{},"log.eurekapu.com/prefecture-quiz"," の目次ページが404」と気づいて、今日のデプロイが全失敗していたことに気づいた。原因は wrangler 4.68.1 が古い件と、Windows + 日本語コミットメッセージで ",[19,212,213],{},"code: 8000111","（UTF-8として無効）で落ちる件。wrangler を 4.91.0 に上げてもらい、",[19,216,21],{}," で ASCII を明示指定する形に ",[19,219,220],{},"scripts/measure-deploy.ps1"," を直してもらって再発防止。",[15,223,224],{},"合間に公開記事3本（CLI-Anything の検証、Notion CLI ntn の実態、Playwright Chrome拡張 vs Chrome DevTools MCP）も書いた。",[15,226,227,70,229],{},[61,228,69],{},[72,230,232],{"href":231},"/tests-deploy-and-misc-articles","テスト失敗修正・Cloudflareデプロイの日本語コミットメッセージ問題・公開記事3本",[77,234],{},[24,236,237],{"id":237},"今日の試行錯誤",[239,240,241,263],"table",{},[242,243,244],"thead",{},[245,246,247,251,254,257,260],"tr",{},[248,249,250],"th",{},"#",[248,252,253],{},"テーマ",[248,255,256],{},"試したこと",[248,258,259],{},"結果",[248,261,262],{},"気づき",[264,265,266,286,306,330,347,368,392,409,432,453],"tbody",{},[245,267,268,272,275,280,283],{},[269,270,271],"td",{},"1",[269,273,274],{},"神経衰弱 Phase 7",[269,276,277,279],{},[19,278,96],{}," で県と特徴のペアマッチング型を完成まで作らせた",[269,281,282],{},"自分の意図は地図トグル開閉だったと気づいて全削除",[269,284,285],{},"「神経衰弱」という単語から想像する形と、自分の意図がズレていた。画面で見せるまで認識合わせができない",[245,287,288,291,294,297,303],{},[269,289,290],{},"2",[269,292,293],{},"Geolonia 日本地図 SVG",[269,295,296],{},"最初は path 別になっていない Wikimedia SVG で簡略タイル地図にしてもらっていた",[269,298,299,300,302],{},"自分で「もっと頑張ってほしい」と再指示 → Geolonia の ",[19,301,88],{}," に差し替えてもらった",[269,304,305],{},"1回試して妥協した判断でも、自分が許容しないなら別ライブラリを当たり直す価値はある",[245,307,308,311,314,324,327],{},[269,309,310],{},"3",[269,312,313],{},"VOICEVOX 直接呼び出し",[269,315,316,319,320,323],{},[19,317,318],{},"useVoicevox.ts"," で ",[19,321,322],{},"localhost:50021"," を fetch して wav 再生する設計にしていた",[269,325,326],{},"開発では動くが本番で読者がエンジン起動していないと無音",[269,328,329],{},"「本番で誰の端末でも動くか」を最初に確認すべきだった。事前生成 MP3 + R2 に切り替えた",[245,331,332,335,338,341,344],{},[269,333,334],{},"4",[269,336,337],{},"4並列サブエージェント派遣",[269,339,340],{},"CH9-12 を4並列でサブエージェントに派遣",[269,342,343],{},"API Error 529 Overloaded で全クラッシュ",[269,345,346],{},"2並列×2セットに切り替えて安定。並列度は API 負荷で調整する変数",[245,348,349,352,355,360,365],{},[269,350,351],{},"5",[269,353,354],{},"yomitoku 0.13.0 アップグレード",[269,356,357,359],{},[19,358,164],{}," で更新したら torch が CPU 版に置き換わった",[269,361,362,364],{},[19,363,164],{}," に PyTorch CUDA インデックス追加で GPU 版に戻させた",[269,366,367],{},"アップグレードで依存パッケージの index が消える落とし穴。index は明示しておく",[245,369,370,373,376,386,389],{},[269,371,372],{},"6",[269,374,375],{},"TS型エラー 62件 → 0件",[269,377,378,379,382,383,385],{},"BS/PL の ",[19,380,381],{},"v-if=\"deltaPopups[key]\""," ガード後の TS2532 を sed で ",[19,384,124],{}," 一括置換させた",[269,387,388],{},"一気に56件解消、全体 0件達成",[269,390,391],{},"同じパターンの narrowing 失敗は sed 一発で潰せる。手作業より速くて安全",[245,393,394,397,400,403,406],{},[269,395,396],{},"7",[269,398,399],{},"章タブが全ページに混入",[269,401,402],{},"紙面の縦書き「第N章」が OCR で全文に入る現象を発見",[269,404,405],{},"「3個以上の章名が連続するブロックを検出して除去」する正規表現で前処理に追加させた",[269,407,408],{},"OCR の前処理は紙面構造を見てからルールを書く。1ページサンプルだけだと判断を間違える",[245,410,411,414,417,423,429],{},[269,412,413],{},"8",[269,415,416],{},"wrangler 日本語コミットメッセージ",[269,418,419,420,422],{},"デプロイが全失敗、",[19,421,213],{}," で落ちた",[269,424,425,426,428],{},"wrangler 4.91.0 + ",[19,427,21],{}," で ASCII 固定 → 復旧",[269,430,431],{},"Windows + 日本語コミットメッセージは wrangler の自動取得で壊れる。固定形式に逃がす",[245,433,434,437,440,447,450],{},[269,435,436],{},"9",[269,438,439],{},"Codex レビュー",[269,441,442,443,446],{},"プランと実装に対して ",[19,444,445],{},"codex exec -m gpt-5.5"," で複数回通した",[269,448,449],{},"致命的指摘21件以上を全件反映させた",[269,451,452],{},"完成宣言の前に Codex に通すと矛盾と未完了タスクが大量に出る。レビュー先行を習慣化",[245,454,455,458,461,464,467],{},[269,456,457],{},"10",[269,459,460],{},"book Turso DB の参照タイミング",[269,462,463],{},"計画段階で読ませていたが本文ドラフトでは読ませていなかった",[269,465,466],{},"Codex 指摘で CH8 リライトから書籍参照を明示、Eurekapu 文脈に書き換えさせた",[269,468,469],{},"参照の有無と参照タイミングは別。引用箇所と引用元の対応が後で追えるようにしておく",[77,471],{},[24,473,474],{"id":474},"今日の学び",[476,477,478,485,491,508,517,523,529],"ul",{},[479,480,481,484],"li",{},[61,482,483],{},"「○○みたいなやつ」は画面で見せるまで認識が合わない",": 神経衰弱を作らせたら自分の意図は地図トグル開閉だった。最初に簡単なモックを見せてもらう流れに戻すと迷子コストが減る",[479,486,487,490],{},[61,488,489],{},"本番デプロイの観点を最初から入れる",": VOICEVOX 直接呼び出しは開発でしか動かない。読者の端末で動くかを実装着手前に決めたい",[479,492,493,496,497,500,501,504,505,507],{},[61,494,495],{},"同型の TS narrowing 失敗は sed で潰せる",": ",[19,498,499],{},"v-if"," ガード後の ",[19,502,503],{},"deltaPopups[key].id"," を ",[19,506,124],{}," に一括置換させるだけで56件消えた。手作業より速い",[479,509,510,513,514,516],{},[61,511,512],{},"アップグレードで依存 index が消える落とし穴",": yomitoku 0.13.0 で torch CUDA→CPU。",[19,515,164],{}," に index を書き込ませて再発防止",[479,518,519,522],{},[61,520,521],{},"並列度は API 負荷で調整",": 4並列で 529 Overloaded、2並列×2セットなら安定。固定値じゃなく API 状況で変える変数",[479,524,525,528],{},[61,526,527],{},"Codex レビューは完成宣言の前に必ず通す",": 1日で 21件以上の致命的指摘が出た。レビュー先行を計画書テンプレに組み込む",[479,530,531,534,535,537],{},[61,532,533],{},"wrangler の日本語コミットメッセージ問題は再現性が高い",": 5/14 にも踏んで memo に対策を残しておいたから5/15に即解決できた。再発予防のために ",[19,536,21],{}," をスクリプト固定",[77,539],{},[24,541,542],{"id":542},"明日やること",[476,544,547,564,574,580,586,592],{"className":545},[546],"contains-task-list",[479,548,551,556,557,560,561],{"className":549},[550],"task-list-item",[552,553],"input",{"disabled":554,"type":555},true,"checkbox"," 未追跡ファイル（statistics/map両方）の ",[19,558,559],{},"git add"," + ",[19,562,563],{},"git commit",[479,565,567,569,570,573],{"className":566},[550],[552,568],{"disabled":554,"type":555}," Cloudflare Pages 環境変数 ",[19,571,572],{},"NUXT_PUBLIC_VOICE_BASE_URL=https://assets.otoarchive.com/prefecture-quiz"," を設定して本番デプロイ",[479,575,577,579],{"className":576},[550],[552,578],{"disabled":554,"type":555}," 本番デプロイ後の音声再生確認（公開URLでブラウザから実際に鳴るか）",[479,581,583,585],{"className":582},[550],[552,584],{"disabled":554,"type":555}," iPhone/Android 実機での 768px 以下レイアウト確認（Chrome DevTools エミュレーションは確認済み）",[479,587,589,591],{"className":588},[550],[552,590],{"disabled":554,"type":555}," eurekapu-nuxt4 Part 2 CH8-12 レビュー計画書の本実行（Codex アプリに派遣）",[479,593,595,597],{"className":594},[550],[552,596],{"disabled":554,"type":555}," テスト残り失敗（グループB系統）の調査",[77,599],{},[24,601,602],{"id":602},"関連記事",[476,604,605,609,613,617,621,625],{},[479,606,607],{},[72,608,75],{"href":74},[479,610,611],{},[72,612,112],{"href":111},[479,614,615],{},[72,616,152],{"href":151},[479,618,619],{},[72,620,187],{"href":186},[479,622,623],{},[72,624,232],{"href":231},[479,626,627],{},[72,628,630],{"href":629},"/2026-05-14-diary","前日の開発日記",{"title":632,"searchDepth":633,"depth":633,"links":634},"",2,[635,636,644,645,646,647],{"id":26,"depth":633,"text":26},{"id":36,"depth":633,"text":36,"children":637},[638,640,641,642,643],{"id":40,"depth":639,"text":41},3,{"id":81,"depth":639,"text":82},{"id":117,"depth":639,"text":118},{"id":157,"depth":639,"text":158},{"id":192,"depth":639,"text":193},{"id":237,"depth":633,"text":237},{"id":474,"depth":633,"text":474},{"id":542,"depth":633,"text":542},{"id":602,"depth":633,"text":602},"diary","都道府県クイズの統計編12ページ55→89問、地図クイズ Phase 5-8 を1日で実装。ずんだもん音声を R2 配信に切替、eurekapu-nuxt4 は全77ページ2カラム化と Part 2 教科書 CH8-12 を派遣完了。yomitoku 0.13.0 と自炊書籍OCRも。","md",{},null,"/2026-05-15-diary","daily-log",false,"2026-05-15T00:00:00.000Z",{"title":5,"description":649},"2026-05/2026-05-15/diary-2026-05-15",[660,661,662,663,664,665,666,667],"日記","prefecture-quiz","eurekapu-nuxt4","VOICEVOX","Cloudflare R2","yomitoku","Claude Code","Codex","g4t3LDMFAmtE6yxu3fmxH64dFETkcJ1mOlp3WpDVmUk",[],"https://log.eurekapu.com/og/blog/2026-05-15-diary.png?v=2026-05-15T00%3A00%3A00.000Z&title=2026%E5%B9%B45%E6%9C%8815%E6%97%A5%E3%81%AE%E9%96%8B%E7%99%BA%E6%97%A5%E8%A8%98%20-%20%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C%E3%82%AF%E3%82%A4%E3%82%BA12%E3%83%9A%E3%83%BC%E3%82%B8%E5%AE%8C%E6%88%90%E3%83%BB%E5%9C%B0%E5%9B%B3%E3%82%AF%E3%82%A4%E3%82%BA4%E7%A8%AE%E3%83%BBeurekapu%2077%E3%83%9A%E3%83%BC%E3%82%B82%E3%82%AB%E3%83%A9%E3%83%A0%E5%8C%96%E3%83%BByomitoku%200.13.0%20%E3%81%BE%E3%81%A7&author=Kei%20Komatsu&sig=51634c5cf4cf041a",1782528836680]