2026年5月11日の開発日記
今日は eurekapu-nuxt4 で簿記3級スライド1286枚を Cloudflare R2 に全移行した。WordPress を並列で叩きすぎて自分のサイトを自分でブロックされる事故を踏み、Dropbox 上のローカルキャッシュから R2 に直接上げる戦略に切り替えて1172枚を18分で完走した。並行して決算書の読み方教材から47枚の SVG 図解を作成し、book-knowledge-base 側では奥付抽出を Haiku から Opus に切り替えて精度を 1/10 から 8/10 に跳ね上げた。終盤は ESLint no-dynamic-delete の Phase 2 を片付けて、lint 全体も 1637 → 717 まで削減した。
今日のタイムライン

今日やったこと
1. 書籍奥付抽出パイプライン: HaikuからOpusへの精度逆転とDropboxオンライン専用ファイル問題
book-knowledge-base 側で Phase 0/1 を完走させた。最初に haiku で10並列OCRを回したら完璧 1/10、誤読 9/10 という散々な結果。Opus + 末尾10ページに切り替えて再実行したら 8/10 完璧、ISBN 完全一致 7/7 まで一気に跳ねた。副産物として amazon_metadata 側のメタデータ誤りを2件検出(奥付抽出は書誌正確性チェックにも使える)。スケールしようとして337件を画像化したら290件が空ディレクトリで、原因は Dropbox Files On-Demand のオンライン専用ファイル。フォルダ全体のローカル化はサイズ的に断念し、ローカル化済み46件で Phase 2 を進めた。ロングセラー検出レポートでは DIE WITH ZERO の1年で第10刷、夜と霧の50年で第37刷、金持ち父さん貧乏父さんの12年で第92刷、その節税が会社を殺すの2ヶ月で第4刷などが拾えた。
主な成果:
- haiku → Opus の精度逆転(1/10 → 8/10)
- Dropbox Files On-Demand 問題の特定と画像化スクリプト3点修正
- ロングセラー検出レポートを memo/2026-05-11/colophon-progress-final.md に保存
詳細: 書籍奥付抽出パイプライン: HaikuからOpusへの精度逆転とDropboxオンライン専用ファイル問題
2. 決算書の読み方教材: PDF199ページから47枚のSVG図解作成
1ヶ月前から棚に置いていた「決算書の読み方教材」のPDF 199ページを画像化し、図ありページを判定して47枚のSVG図解を作成した。「1ページ=1図」方針で、書籍の図を「下回らない・改善OK」のルール。途中で3つのバグを踏んだ:「セブン&アイ」の & がXMLエスケープされていなかった3箇所、対比図で反復ラベルが太字になり差分が見えにくくなる9ファイル35箇所、テキストはみ出しで p026 と p050 が見切れていた箇所。表示確認をサボって提出したら「表示確認をちゃんと」と一刺しされ、Python厳密チェック+Chrome DevTools 16枚実画面確認で潰しきった。svg-diagramスキルに新ルール「対比図での反復ラベル太字禁止」を追加。
主な成果:
- 47枚のSVG図解完成(preview.html 章別整理)
- svg-diagramスキルへの新ルール追加(反復ラベル太字禁止)
- セッション引き継ぎドキュメント memo/2026-05-11/session-handover.md 作成
詳細: 決算書の読み方教材: PDF199ページから47枚のSVG図解作成と表示確認の落とし穴
3. 簿記3級スライド1286枚のR2移行: WPブロック事故とDropboxローカル発見
旧プロジェクト cockpit-nuxt-vuetify の簿記3級スライド1286枚を Cloudflare R2 に全移行した。最初に WordPress から並列DLしようとしたら「自分たちで叩きすぎて」WPがレートリミットでIPブロック。ユーザーから「なんでそんなことするんですか」と叱られた。Dropbox 上の月別フォルダに1212枚のローカルキャッシュがあるのを発見し、WPを叩かずローカルから R2 へ並列6でアップロード(メインジョブ b1qe3ko6j → 1172/1172成功、18分)。Chapter16はPNG形式で漏れていたため別ジョブで213枚追加、合計1286/1286完了。/lessons/bookkeeping-slides/chapter 新ページもコクピット風3カラム+左右サイドバー折りたたみで作成。Illustrator AI ファイルからExtendScriptで読み上げスクリプトのテキスト抽出にも成功(40 JSON、漏れなし)。
主な成果:
- 1286/1286 全SVG/PNGをR2配信に切り替え
- /lessons/bookkeeping-slides/chapter 新ページ実装(章跨ぎナビ、画面幅いっぱい)
- ExtendScript .jsx でAI ファイルからテキスト抽出(本文判定: font=AXIS ProN, style=M, fontSize>=30)
詳細: 簿記3級スライド1286枚のR2移行: WPブロック事故、Dropboxローカル発見、Illustrator AIから読み上げスクリプト抽出
4. 簿記3級クイズの「着弾アニメ」ON/OFFトグル追加とハイライト残留バグ修正
簿記3級の練習問題ページで、解答後の着弾アニメ前に前の問題の青ハイライトが消えていないバグを修正。pendingApply.value 中も cumulativeImpact が changed フラグを残したまま再計算される問題で、pendingApply が立っている間は clearChanged を適用するように変更した。着弾色は感情科目のプラス→緑、マイナス→赤を背景色に。アニメが速すぎる/しつこいフィードバックには「着弾アニメ」ON/OFFトグルで対応した。最初は全アニメ止めようとしたら「カウントアップとハイライトとdelta popupは残せ、fly-pillだけ」と差し戻され、絞り込んで再修正。ESLint既存エラー2件は別タスクに切り出して Codex レビューにかけて計画書化。
主な成果:
- ハイライト残留バグ修正(pendingApply中は clearChanged 適用)
- fly-pill だけのトグル切替(C/Sトグルと同じデザイン)
- 引き算指示は「残す側」を書く、という学び
詳細: 簿記3級クイズの「着弾アニメ」ON/OFFトグル追加とハイライト残留バグ修正
5. ESLint no-dynamic-delete Phase 2解消と全体lint整理(1637→717)
Phase 1(popup型限定で Reflect.deleteProperty)に続き、Phase 2 では delete の用途を A/B/C に分類して Reflect.deleteProperty か = undefined を使い分けた。7件まとめて修正、Chrome DevToolsで3コンポーネント(Cash3Topics / Journal / ClosingTransfer)を実走確認、コミット2分割(fix+memo)。Phase 1 積み残しの delta popup 自動テスト7件をvitestで追加。lint 全体(残584エラー + 1053警告)の整理計画書を作成して Codex レビューに通し、致命的指摘3件(.pytest_cache をeslint ignoreに追加など)を反映。自動修正で 1637 → 717 に劇的削減(-920件、93ファイル)。翌日タスクは memo/2026-05-12/lint-rest-tasks.md にスターター文付きで保存。
主な成果:
- no-dynamic-delete 7件すべて解消(Phase 2 完了)
- delta popup Next/Backクリア自動テスト追加(vitest 7件)
- lint 全体 1637 → 717(-920件)
詳細: ESLint no-dynamic-delete Phase 2解消と全体lint整理(1637→717)
今日の試行錯誤
| # | テーマ | 試したこと | 結果 | 気づき |
|---|---|---|---|---|
| 1 | 奥付OCR | haiku 10並列で337件スケール想定 | 失敗(10件中9件誤読) | 精度モデルをケチるとPhase 2 に進めない |
| 2 | 奥付OCR | Opus + 末尾10ページに切替 | 成功(8/10完璧) | OCR精度はモデル選定がほぼ全て |
| 3 | 画像化 | 337件をfitz.openで一括 | 失敗(290件空ディレクトリ) | Dropbox Files On-Demand の存在 |
| 4 | SVG図解 | 反復ラベル太字で47枚作成 | 失敗(差分が見えない) | 対比図ではカラムヘッダーを太字にすると本来の差分がぼやける |
| 5 | SVG図解 | 表示確認せず提出 | 失敗(見切れ多発) | 「表示確認をちゃんと」一刺しから Python厳密チェック+実画面確認の運用へ |
| 6 | スライド移行 | WP 1224枚を並列DL | 失敗(自分でWPをブロックされる) | レート制御なしで自分のサイトを自分で殺した |
| 7 | スライド移行 | Dropboxローカル発見→R2直アップ | 成功(1172枚18分) | WPを叩かない戦略への切替が正解 |
| 8 | スライド漏れ | Chapter16が表示されない | 原因判明 | PNG形式(slide_chap16_*.png)でフィルタから漏れていた |
| 9 | クイズアニメ | アニメ全部止める | 失敗(差し戻し) | カウントアップ・ハイライトは残してほしかった |
| 10 | クイズアニメ | fly-pillだけトグル化 | 成功 | 引き算指示は「残す側」を明示しないと止めすぎる |
| 11 | スクリプト抽出 | pypdfで.aiから取得 | 失敗(プレースホルダのみ) | PDF互換オプションOFFで保存されていた |
| 12 | スクリプト抽出 | ExtendScript .jsxでアートボードから抽出 | 成功(40 JSON漏れなし) | font=AXIS ProN, style=M, fontSize>=30 で本文判定 |
| 13 | バッチPS | PowerShellでバッチ実行 | 失敗(cp932文字化け) | UTF-8 BOM + LiteralPath で対応 |
| 14 | lint整理 | 自動修正で全体走査 | 成功(1637→717) | 920件のうちの大半は自動修正で消える |
今日の学び
- OCR精度はモデル選定がほぼ全て。haikuで誤読9/10だったものがOpusで完璧8/10に跳ねる
- Dropbox Files On-Demand は fitz.open(と shutil.copyfile)を黙って失敗させる。事前に hydrate 済みかをチェックしないと一括処理が空回りする
- 対比図のカラムヘッダーは「反復している正規化された情報」なので太字にすると差分情報がノイズに埋もれる
- 自分のWordPressに自分の並列スクリプトでDoS気味の負荷をかけて落とした。レート制御は自分のサイト相手でも必須
- 引き算指示(「アニメ止めて」)は「残す側」を書かないと止めすぎる
- 表示確認をサボると後で全件チェックする羽目になる。Pythonで厳密チェック+ブラウザで実画面確認の二段構えが安い
- 計画書は Codex (gpt-5.5) に「瑣末な点へのクソリプはしないで。致命的な点だけ指摘して」のフレーズで通すと致命傷だけ拾える運用が回る
- delete の用途分類(A: 再代入予定、B: undefined許容、C: 完全削除必須)で Reflect.deleteProperty / = undefined を使い分ける
明日やること
- lint 残717件のグループA〜Eを順次解消(memo/2026-05-12/lint-rest-tasks.md 参照)
- 簿記3級スライド ↔ Illustrator スクリプト40 JSON のマッピング作業
- 決算書教材 SVG図解47枚を /lessons/zaimu-shohyo 配下にページとして組み込み
- book-knowledge-base 側 Dropbox 完全ローカル化後、残291件の奥付抽出を再実行