[{"data":1,"prerenderedAt":282},["ShallowReactive",2],{"content-/accounting-system-consumption-tax-phase6":3,"all-pages-for-dir":259,"related-/accounting-system-consumption-tax-phase6":260,"og-image-/accounting-system-consumption-tax-phase6":281},{"id":4,"title":5,"body":6,"category":238,"concepts":239,"description":240,"extension":241,"meta":242,"navigation":243,"ogImage":239,"path":244,"project_name":245,"published":246,"publishedAt":247,"seo":248,"stem":249,"tags":250,"todo":239,"unpublished":246,"updatedAt":239,"__hash__":258},"pages/2026-07/2026-07-30/accounting-system-consumption-tax-phase6.md","自作会計システムに消費税を通した日。composable の await 連続で Nuxt コンテキストが消えた",{"type":7,"value":8,"toc":229},"minimark",[9,13,16,24,27,30,34,37,40,43,46,49,52,55,59,62,65,68,72,75,135,138,141,144,148,151,154,157,160,163,166,169,172,183,190,193,200,203,206,225],[10,11,12],"p",{},"朝いちで投げた質問が「これってなんか積み残しありましたっけ。これ何のプロジェクトでしたっけ」だった。",[10,14,15],{},"自分で作ったものを、自分で忘れている。",[10,17,18,19,23],{},"返ってきた棚卸しはこうだった。自作の会計システムの MVP。Nuxt 4 と Nuxt UI 4、Drizzle、libSQL/SQLite で組んであって、",[20,21,22],"code",{},"pnpm dev"," を叩くと 3300 番で立ち上がる。Phase1 から Phase5 までは実装もコミットも終わっている。ユニットテストをその場で走らせたら67件が全通過した。",[10,25,26],{},"積み残しは4つ挙がった。Phase6 の消費税がまるごと未着手。トップページが「セットアップ中」の文言で止まっている。反対仕訳の自動起票が無い。Phase3 から Phase5 の E2E が足りていない。",[10,28,29],{},"「じゃあこれ順次続けてください」とだけ返した。",[31,32,33],"h2",{"id":33},"スキーマから始めた消費税対応",[10,35,36],{},"タスク管理ツールに積み直させてから、コード全体を読み込ませた。着手は Phase6 の消費税からにした。",[10,38,39],{},"順番は下から上に固定した。スキーマ、ドメイン関数、API と seed、最後に UI。",[10,41,42],{},"マイグレーションは ALTER TABLE の ADD COLUMN だけで適用し、既存のトリガーはそのまま残した。ドメイン関数まで通ったところで最初のタスクが閉じた。",[10,44,45],{},"次は API と seed だった。既存の仕訳フローを確認させてから、税区分マスタと消費税集計の API を足した。",[10,47,48],{},"税額の計算をどこに置くかだけは自分で決めた。仕訳の検証ロジックに、税区分の解決と消費税明細の生成をまとめて組み込ませた。検証を通った仕訳には必ず税額がついている状態になる。入力画面が増えても、税の出し方は一箇所しか無い。seed も合わせて更新させた。",[10,50,51],{},"UI では、仕訳入力画面に税区分の選択と税額プレビューを載せた。仕訳を入力する画面は2つあるので、共通のロジックは composable に切り出して両方から呼ばせた。",[10,53,54],{},"ここまでは詰まらずに進んだ。",[31,56,58],{"id":57},"chrome-devtools-mcp-が繋がらない","Chrome DevTools MCP が繋がらない",[10,60,61],{},"描画を確認するため dev サーバーを起動させた。Chrome DevTools MCP がブラウザに接続できない。",[10,63,64],{},"繋げる工夫で粘るのはやめて、Playwright での確認に切り替えさせた。やりたいのは接続の復旧ではなく、画面が正しく描けているかの確認だ。",[10,66,67],{},"切り替えた先で不具合が出た。",[31,69,71],{"id":70},"composable-の-await-と-nuxt-コンテキスト","composable の await と Nuxt コンテキスト",[10,73,74],{},"原因は composable の中にあった。await を連続させていて、その先で Nuxt のコンテキストが失われていた。形としてはこういう並びになる。",[76,77,82],"pre",{"className":78,"code":79,"language":80,"meta":81,"style":81},"language-ts shiki shiki-themes vitesse-light vitesse-light","const useTaxPreview = () => {\n  // 1つめの await までは通る\n  // その先の await のあとでは Nuxt のインスタンスを拾えない\n  // composable が内部で当てにしている機能が、そこから効かなくなる\n}\n","ts","",[20,83,84,110,117,123,129],{"__ignoreMap":81},[85,86,89,93,97,101,104,107],"span",{"class":87,"line":88},"line",1,[85,90,92],{"class":91},"stQ0i","const ",[85,94,96],{"class":95},"senZ8","useTaxPreview",[85,98,100],{"class":99},"shFtX"," =",[85,102,103],{"class":99}," ()",[85,105,106],{"class":99}," =>",[85,108,109],{"class":99}," {\n",[85,111,113],{"class":87,"line":112},2,[85,114,116],{"class":115},"sxvE3","  // 1つめの await までは通る\n",[85,118,120],{"class":87,"line":119},3,[85,121,122],{"class":115},"  // その先の await のあとでは Nuxt のインスタンスを拾えない\n",[85,124,126],{"class":87,"line":125},4,[85,127,128],{"class":115},"  // composable が内部で当てにしている機能が、そこから効かなくなる\n",[85,130,132],{"class":87,"line":131},5,[85,133,134],{"class":99},"}\n",[10,136,137],{},"仕訳画面から共通ロジックを引き剥がしたときに await が増えて、そのまま踏み抜いたのだと思う。",[10,139,140],{},"修正させたら、画面はすべて正常に出た。",[10,142,143],{},"既存の E2E も税の追加で壊れたので、設定を見直させた。Phase6 の E2E 6件が全部通ったところで消費税対応が閉じた。",[31,145,147],{"id":146},"トップページ反対仕訳管理画面","トップページ、反対仕訳、管理画面",[10,149,150],{},"「セットアップ中」のままだったトップページをダッシュボードに変えさせた。続けて反対仕訳の自動起票を実装させた。借方と貸方を入れ替えた仕訳を、手で打ち直さずに起こせるようにする。",[10,152,153],{},"型チェックを回しながら、E2E 用に既存ページの testid を確認させた。テストを書き足す前に共通ヘルパーを切り出させて、そのあとで消費税、帳票、反対仕訳の3系統を追加した。13件が全通過。",[10,155,156],{},"最後がユーザー管理と会社設定の画面だった。ここまで足して E2E は18件になった。",[31,158,159],{"id":159},"エラーメッセージの中身と二重表示",[10,161,162],{},"新しい画面を動かしていて気づいた。エラーメッセージにサーバー側の理由が出ていない。共通の取り出し処理を入れて全画面に適用させた。",[10,164,165],{},"今度は同じエラーがモーダルの中とページ上部の両方に出た。モーダルを開いている間はページ側を隠すよう直させた。",[10,167,168],{},"もう一度描画を確認させたら、会社設定のヒント文が入力欄から離れて浮いていた。ここも詰めさせた。",[31,170,171],{"id":171},"コミットと学習ゲート",[10,173,174,175,178,179,182],{},"コミットしようとしたら、pre-commit の学習ゲートに止められた。",[20,176,177],{},"/learn"," を起動したところで、こちらから「学習ゲートはパスでいい」と伝えた。理由を残してスキップコミットにした。ローカル設定の ",[20,180,181],{},".claude/"," は扱いの判断が要るので、コミットからは外してある。",[10,184,185,186,189],{},"積み残し7件をすべて実装して ",[20,187,188],{},"c81e87c"," でコミットした。ユニット100件、E2E18件、型チェックがすべて通った。画面は Playwright で実際に描かせて確認してある。",[10,191,192],{},"朝に走らせたときは67件だった。",[10,194,195,196,199],{},"そこでセッションの制限が近づいた。ドキュメントに詳細を残すよう頼んで、作業ログを memo 配下に1本書かせて ",[20,197,198],{},"0bec8b9"," でコミットした。作業ツリーはクリーンな状態で終わった。",[10,201,202],{},"「何のプロジェクトでしたっけ」と聞くところから始めて、積み残し7件が消えた。また同じことを聞く日は来る。そのときのために残したログでもある。",[31,204,205],{"id":205},"学び",[207,208,209,213,216,219,222],"ul",{},[210,211,212],"li",{},"ブラウザに繋がらないときは、繋げる工夫で粘らない。描画を確認するだけなら Playwright で足りる",[210,214,215],{},"composable への切り出しでは、中の await を数える。Nuxt のコンテキストは await をまたぐと失われる",[210,217,218],{},"テストを足す前に共通ヘルパーを切り出す。この順番は今回も効いた",[210,220,221],{},"エラー表示は「出るか」ではなく「理由が読めるか」で点検する。二重表示も同じ見方で拾える",[210,223,224],{},"学習ゲートは黙って回避せず、理由を残したスキップで通す。判断そのものがログに残る",[226,227,228],"style",{},"html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}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);}",{"title":81,"searchDepth":112,"depth":112,"links":230},[231,232,233,234,235,236,237],{"id":33,"depth":112,"text":33},{"id":57,"depth":112,"text":58},{"id":70,"depth":112,"text":71},{"id":146,"depth":112,"text":147},{"id":159,"depth":112,"text":159},{"id":171,"depth":112,"text":171},{"id":205,"depth":112,"text":205},"dev",null,"「これ何のプロジェクトでしたっけ」から棚卸しを始め、積み残し7件を一気に実装した記録。消費税対応をスキーマからUIまで通し、Chrome DevTools MCP が繋がらず Playwright に切り替え、画面の不具合は composable 内の await 連続が原因だった。","md",{},true,"/accounting-system-consumption-tax-phase6","accounting-system-lab",false,"2026-07-30T00:00:00.000Z",{"title":5,"description":240},"2026-07/2026-07-30/accounting-system-consumption-tax-phase6",[251,252,253,254,255,256,257],"Nuxt","消費税","会計システム","composable","Playwright","E2E","Drizzle","QT9gbGPhQZscy5s82wwGd0TeP90hCrvHOhO0YGKPYgE",[],[261,265,269,273,277],{"title":262,"path":263,"publishedAt":264},"消費税のインタラクティブ教材をNuxtで構築 — 調査エージェント2本を並行で走らせてコースページを実装した","/consumption-tax-course-build","2026-07-02T00:00:00.000Z",{"title":266,"path":267,"publishedAt":268},"過去記事に散らばったSVG図版を一覧するギャラリービューアを作った","/svg-gallery-viewer","2026-07-01T00:00:00.000Z",{"title":270,"path":271,"publishedAt":272},"テスト基盤整備とカバレッジ改善 - 8ステップ計画で0から215テストを積み上げた一日","/test-infrastructure-coverage-2026-03-02","2026-03-02T00:00:00.000Z",{"title":274,"path":275,"publishedAt":276},"Vitest・Playwright テスト環境整備 - 29パスから全34ファイル14,817テスト全パスまで","/vitest-playwright-coverage-2026-02-26","2026-02-26T00:00:00.000Z",{"title":278,"path":279,"publishedAt":280},"開発環境とテストスイートの整備 - Volta Node.js更新・ESLint修正・E2Eテスト全パス","/dev-environment-testing-2026-02-21","2026-02-21T00:00:00.000Z","https://log.eurekapu.com/og/blog/accounting-system-consumption-tax-phase6.png?v=2026-07-30T00%3A00%3A00.000Z&title=%E8%87%AA%E4%BD%9C%E4%BC%9A%E8%A8%88%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AB%E6%B6%88%E8%B2%BB%E7%A8%8E%E3%82%92%E9%80%9A%E3%81%97%E3%81%9F%E6%97%A5%E3%80%82composable%20%E3%81%AE%20await%20%E9%80%A3%E7%B6%9A%E3%81%A7%20Nuxt%20%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%8C%E6%B6%88%E3%81%88%E3%81%9F&author=Kei%20Komatsu&sig=e5a2ab313b693e46",1785464020406]