• #CF精算表
  • #Vue
  • #Codex
  • #ステップ学習
  • #ExcelHtmlViewer
開発eurekapu-nuxt4

CF精算表ステップ学習ページの構築

CF計算書の参考書をベースに、精算表の作り方をステップごとに学べるページ群を作った。最初の設計が2箇所で破綻していたのをCodexレビューが拾い、プランを書き直してから実装に入った1日。

方針決定: ドラフトMDを経由しない

当初は「memo/にドラフトMDを書く→レビュー→content/に清書」の流れを想定していた。しかしCF精算表ページはインタラクティブ要素(Excel HTMLの拡大表示、3カラムレイアウト、目次スクロール追従)を多用する。MDXの表現力では足りないと判断し、最初からVueコンポーネントとして直接構築する方針に切り替えた。

Codexレビューが致命的問題を2つ検出した

プランを書き終えた段階でCodexにレビューを投げたところ、即座に2点を突き返された。

問題1: memo/配下はCloudflare Pagesで配信されない

当初プランではExcelのHTML出力を memo/excel-html/ に置く設計だった。Codexの指摘:

memo/ はgitignore対象外だがCloudflare Pagesの公開ディレクトリ(public/)に含まれない。本番でアクセスすると404になる。

修正: public/excel-html/ に移動し、ビルド時に静的ファイルとして配信されるようにした。

問題2: v-htmlでグローバルCSS汚染が起きる

ExcelのHTML出力をそのまま v-html で描画すると、Excel由来のCSSセレクタがページ全体に漏れる。Codexの指摘:

Excelが吐くHTMLにはtd, th, body等の要素セレクタが含まれる。v-htmlで挿入するとscoped CSSの外側からグローバルに汚染する。

修正: ExcelHtmlViewerコンポーネントを作り、Shadow DOM的にスタイルを隔離する方針に変更した。

ExcelHtmlViewerコンポーネント

Codexの指摘を受けて設計したコンポーネント。核心部分:

<template>
  <div class="excel-viewer" @click="openModal">
    <iframe :srcdoc="htmlContent" sandbox="" class="preview" />
  </div>
  <Teleport to="body">
    <div v-if="isOpen" class="modal-overlay" @click="close" @keydown.esc="close">
      <iframe :srcdoc="htmlContent" sandbox="" class="fullscreen" />
    </div>
  </Teleport>
</template>

iframe + srcdoc でExcel由来のCSSを完全に隔離した。クリックでモーダル拡大、Escキーで閉じる。sandbox属性でスクリプト実行も防いでいる。

全9ページの構成

index(概要)+ ch0(前提知識)+ step1〜7の計9ページを作成した。

ページ内容
index学習ロードマップと全体像
ch0CF計算書の基礎知識(直接法・間接法)
step1営業CFの税引前利益からスタート
step2減価償却費の加算調整
step3運転資本の増減
step4投資CFの固定資産取得・売却
step5財務CFの借入・返済
step6現金同等物の増減額
step7全体の検算とバランス確認

3カラムレイアウト

左カラムにステップ一覧(現在地をハイライト)、中央にコンテンツ本体、右カラムに目次がスクロールに追従する。IntersectionObserver APIで見出しの通過を検知し、目次のアクティブ項目を切り替えている。

ドラフトビューアーの実装

Vueページ化の前段階として、memo/に置いたMarkdownドラフトをブラウザで確認するビューアーも作った。

  • marked.jsでクライアントサイドレンダリング
  • note.com風の余白とフォントサイズ(本文16px、行間1.8)
  • 画像クリックでライトボックス展開

このビューアーは開発時のプレビュー用で、本番には含めない。

書籍キーワードDDの結果

CF計算書の参考書に登場するキーワードをTursoDB上の用語マスタと突合した。結果:

  • 全キーワード数: 142
  • マスタに存在: 74
  • カバー率: 52%

残り48%のうち、CF精算表特有の用語(「小計」「利息及び配当金の受取額」等)が大半を占めた。これらをマスタに追加する作業は別チケットとして積み残した。全ドラフトのレビュー文書を作成し、各ステップで参照すべき基準条文を洗い出した。

StandardRef.vueコンポーネント

レビュー文書の作成中に「基準条文をその場で読みたい」という要求が出たため、StandardRef.vueを新規作成した。

<StandardRef code="IAS7" paragraph="18" />

クリックすると条文テキストがインラインで展開される。TursoDBから条文データを取得し、<details>要素で折りたたむ。ページ遷移せずにコンテキストを保ったまま条文を確認できる。

今日の学び

  • プランをCodexに投げる習慣が根付いてきた。今回は2つとも「実装してからでは手戻りが大きい」タイプの問題で、事前に潰せたのは大きい
  • iframe srcdocはCSS隔離の手段として手軽に動く。Shadow DOMより記述量が少なく、Excel HTMLのように「外部が生成した汚いHTML」を封じ込めるには十分
  • カバー率52%という数字は低く見えるが、CF精算表はニッチな領域で汎用用語マスタとの乖離は想定内。足りない用語を追加すれば70%台に届く見込み

関連記事