Skip to content

Phase 9: 仕上げ・本番デプロイの下準備 - #15

Merged
yamk12nfu merged 21 commits into
mainfrom
feature/phase-9-production-deploy
Jul 30, 2026
Merged

yamk12nfu merged 21 commits into
mainfrom
feature/phase-9-production-deploy

Conversation

@yamk12nfu

@yamk12nfu yamk12nfu commented Jul 26, 2026 •

Copy link
Copy Markdown
Owner

実装計画書 §11(Phase 9)のうち、リポジトリ側で先に済ませられることをまとめて片付けた。
ダッシュボードでの実作業(Clerk本番インスタンス、Google OAuth、Convex prod環境変数、Vercel Import、
スマホ実機テスト)は手順書に開いてあり、これから人手でやる。

実装内容

1. レシート以外の画像のエラー導線(持ち越し課題)

風景写真を実際に投げて確認した。文言は要件どおりだったが、「もう一度読み取る」ボタンが出ていた。
同じ画像を投げ直しても結果は変わらず、AI呼び出しと読み取り回数の枠を捨てるだけなので、この場合は
出さないようにした。撮り直しは上の「レシートを撮影・選択」がそのまま導線になる。

判定に使う文言は lib/receipt.ts の ERR_UNREADABLE_RECEIPT をサーバーと画面で共有する
(片側だけ直したときに静かに壊れないように)。

2. vercel.json を追加

Build Command をダッシュボードではなくリポジトリに置いた。理由:

  • ダッシュボード設定はリポジトリに残らず、プロジェクトを作り直すと消える。消えると
    「フロントは新しいのに Convex 関数は古い」という気づきにくい壊れ方をする
  • ignoreCommand で本番以外のビルドを止められる。プレビュービルドが本番用デプロイキーで
    npx convex deploy を走らせて本番の Convex 関数を書き換える
    事故を、設定ミスがあっても起こさない

vercel.json は厳格なJSONでコメントを書けないので、理由は docs/deployment.md §3-1 と計画書 §11 に置いた。

3. proxy.ts に authorizedParties

CLERK_AUTHORIZED_PARTIES(カンマ区切り)から読む。未設定なら従来どおりの挙動。
値は new URL() で http(s) のオリジンに正規化する — Clerkは azp と完全一致で判定するので、
末尾スラッシュ・大文字・:443 の表記ゆれだけで全員がログインできなくなるため。

⚠️ これだけではConvexへの直接アクセスは塞げない。 画面のデータは ConvexProviderWithClerk が
ClerkのJWTを直接Convexへ送る経路で流れており、convex/auth.config.ts は Issuer と applicationID
しか検証しない。サブドメインからの迂回は Clerkの Allowed Subdomains(手順書 §1-5)で塞ぐ。

4. docs/deployment.md(新規)

ダッシュボードで押す順に開いた手順書。症状 → 原因の早見表つき。
計画書に無かった前提を2つ拾った:

  • Clerkの本番インスタンスは自分が所有するドメインが必須(*.vercel.app では作れない)。
    Vercel側にも同じドメインを追加し、DNS登録後に Clerk の Deploy certificates を押すまでが1セット
  • 開発インスタンスのまま公開しない。Clerkは本番のワークロードに適さないと明言しており、
    理由はユーザー数上限ではなく、セッションを __clerk_db_jwt としてクエリ文字列で運ぶこと
    (サーバーログ・ブラウザ履歴に残る)

5. docs/verification-checklist.md(新規)

要件定義書と突き合わせた最終検証チェックリスト。全73項目(高17 / 中35 / 低21)。
vitest 203件で担保済みの範囲には [自動テスト済み] を付け、人間が画面・実機で見ないと
分からないものを中心に据えた。

6. 計画書 §11 の更新

  • コスト管理を Anthropic コンソール → Google AI Studio の Monthly spend cap に読み替え
  • 本番デプロイ前にローカルで潰せることを整理(本番だけで出る失敗は実質2つ)
  • 置き去りアップロードの掃除(TBD-002)の判断
  • 表示速度の本番ビルド実測値

判断したこと

論点 結論
コスト管理 既定プロバイダがGeminiなので Google AI Studio → Spend → Monthly spend cap。計画書も修正
vercel.json を置くか 置く(上記2の理由)
本番デプロイの事前検証 本番だけで出る失敗は2つに絞れ、両方ローカルから確認できる。npx convex env list --prod(未登録だとデプロイ自体が失敗)と npx convex data --prod(本番DBはテーブル0件なのでスキーマ検証は今回落ちない)
置き去りアップロードの掃除(TBD-002) 運用開始後に回す。年数MB規模で、本番稼働直前にインデックス追加+データを消す定期実行を入れるのは割に合わない。着手の閾値(File Storage が無料枠の50%)と実装方針を計画書に明記

実施した検証

  • npx tsc --noEmit / npm run lint(既存warning5件のみ)/ npx vitest run(203件 passed)/ npm run build すべて通過
  • npx convex dev --once で開発デプロイへ反映
  • ブラウザ: 風景写真を投げて「レシートを読み取れませんでした。撮り直してください」+「手入力に切り替える」だけが出ることを確認(修正前は「もう一度読み取る」も出ていた)
  • ブラウザ: proxy.ts の変更後もログインが維持されることを確認
  • 本番ビルドで表示速度を実測: ホーム LCP 1,652ms / 精算 1,820ms / 精算履歴 1,596ms。JSチャンク未キャッシュの初回は 2,764ms
  • CLERK_AUTHORIZED_PARTIES の正規化を ftp: / file: / data: / javascript: / blob:https: / スキーム無し / , だけ で確認
  • Codexレビュー6周(high 3件 → medium → low と収束。すべて対応済み)

⚠️ マージ前に決めてほしいこと

ドメインを用意するかどうか。 Clerkの本番インスタンスに必須で、*.vercel.app では作れない。
用意しない場合の暫定運用は docs/deployment.md §1-alt にあるが、上記のとおり推奨しない。

残る手動確認(すべて本番デプロイ後)

docs/verification-checklist.md が正本。重いものだけ:

  • 本番URLで2つの別Googleアカウントからログイン(GoogleのOAuth同意画面が「テスト」のままだと片方だけ弾かれる)
  • 世帯が違えばデータが見えない(3つ目のアカウントで確認。Phase 4 から持ち越し)
  • スマホ実機(iOS Safari / Android Chrome)で 撮影 → 仕分け → 確定 → 精算
  • 初期表示2秒以内(localhost実測で1.6〜1.8秒、初回2.76秒。実機・4Gではさらに遅くなるので余裕がない)
  • リアルタイム同期が本番でも効く
  • Google AI Studio の月額上限、Convex の File Storage 使用量

別途対応が要るかもしれないもの(Phase 9のスコープ外)

  • 同時編集の競合(F-006): 「他の端末で更新されました」の文言が無いだけでなく、ExpenseEditor が
    initialValue をマウント時にしか読まないため、編集画面を開いたまま相手が保存すると古いフォームの
    まま上書きされる
  • 世帯からの退出(TBD-007): 「先に退出してください」と案内する文言はあるが、退出する手段が無い
  • releaseUpload がUIから到達できない: 読み取り成功後はファイル選択が消え、編集画面にも画像の
    差し替えUIが無い。expenses.save の安全網としては効いている

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 改善
    • レシート読み取り失敗(不鮮明/未読取)を状況別に案内文と導線(撮り直し/手入力)で切り替え、再読取りの出し分けを整理しました。
  • セキュリティ/認証
    • 本番向けの許可元判定を強化し、許可するオリジンを設定に基づいて厳密化しました。
  • デプロイ/設定
    • Vercelのビルド/実行設定、ならびに本番起動ポート設定を追加・調整しました。
  • ドキュメント
    • Clerk本番手順(証明書確認/Allowed subdomains/DNS確認)と検証チェックリストを更新しました。

yamk12nfu and others added 12 commits July 27, 2026 01:32
風景写真を投げて実際に確認したところ、文言は要件どおりだったが、
再読み取りボタンが出ていた。同じ画像を投げ直しても結果は変わらず、
AI呼び出しと読み取り回数の枠を捨てるだけになる。撮り直しは上の
「レシートを撮影・選択」がそのまま導線になる。

判定に使う文言は lib/receipt.ts の ERR_UNREADABLE_RECEIPT を
サーバーと画面で共有する(片側だけ直したときに静かに壊れないように)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Build Command をダッシュボードにだけ書くと、プロジェクトを作り直したときに
消える。消えると「フロントは新しいのに Convex 関数は古い」という気づきにくい
壊れ方をするので、vercel.json に置いて優先させる。

ignoreCommand で本番以外のビルドを止めるのは、プレビュービルドが本番用の
デプロイキーで npx convex deploy を走らせて本番の Convex 関数を書き換える
事故を、設定ミスがあっても起こさないため。

vercel.json は厳格なJSONでコメントを書けないため、理由は
docs/deployment.md §3-1 と計画書 §11 に置いた。

launch.json には本番ビルドの確認用に warikapp-prod を追加した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs/deployment.md: ダッシュボードで押す順に開いた手順書。
Clerk本番インスタンスが「自分が所有するドメイン」を要求する点(計画書に
無かった前提)と、ドメインを用意しない場合の代替を §1-alt に入れた。
症状→原因の早見表も付けた。

計画書 §11 の変更:
- コスト管理を Anthropic コンソール → Google AI Studio の Monthly spend cap に
  読み替え(既定プロバイダが Gemini になったため)
- 本番デプロイ前にローカルで潰せることを表に整理
  (本番だけで出る失敗は実質2つ。うちスキーマ検証は本番DBが空なので今回は起きない)
- 置き去りアップロードの掃除(TBD-002)は運用開始後に回す判断と、その理由・
  実装方針・着手の閾値
- 表示速度の本番ビルド実測値

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs/requirements.md と実装を突き合わせて生成(/verification-checklist)。
vitest 203件で担保済みの範囲には [自動テスト済み] を付け、人間が画面・実機で
見ないと分からないものを中心に据えた。全73項目(高17 / 中34 / 低22)。

照合中に見つかった仕様との乖離を2件記録した:
- F-006 の「他の端末で更新されました」の文言が見当たらない(挙動は後勝ちで
  満たしているがメッセージは出ない)
- TBD-007 の世帯退出の導線が無い(「先に退出してください」と案内する文言は
  あるが、退出する手段が設定画面にもConvex関数にも無い)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
npx convex env set は値を省くと対話入力になる。確認も --names-only を
既定にして、値をうっかり画面に出さないようにした。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
高:
- Clerkの開発インスタンスを「2人用MVPなら十分」と案内していた。Clerk自身が
  本番のワークロードには適さないと明言しており、理由はユーザー数上限ではなく
  セッションを __clerk_db_jwt としてクエリ文字列で運ぶ点(サーバーログ・
  ブラウザ履歴に残る)。ドメイン取得を本線にし、§1-alt は「間に合わないときの
  暫定・推奨しない」に格下げして実際の警告を書いた
- Vercelにカスタムドメインを追加する工程と、Clerkの Deploy certificates が
  抜けていた。この2つが無いと本番認証が完成しない。全体の順序も§0に置いた

中:
- proxy.ts に authorizedParties を追加(CLERK_AUTHORIZED_PARTIES から読む。
  未設定なら従来どおり)。指定しないと同じルートドメイン配下の別サブドメインに
  渡ったcookieでトークン検証が通る
- GoogleのOAuthクライアントで「承認済みのJavaScript生成元」は空でよいと
  書いていたが、Clerkの手順はアプリのドメインを入れるよう明示している
- convex deploy --dry-run の確認プロンプトは n ではなく y。--dry-run が
  付いていればデプロイされず(Would have deployed)、n だと差分が見られない
- 検証チェックリスト: 満員メッセージには到達しない(2人目の参加で usedAt が
  立ち、無効コードとして先に弾かれる)/ 精算取り消しのガードは金額ではなく
  件数(expenseCount)/ F-006 は「後勝ちの挙動は満たす」も誤りで、
  ExpenseEditor が initialValue をマウント時にしか読まないため古いフォームの
  まま上書きされる

低:
- 計画書§10.4 が旧仕様(再読み取り導線あり)のままだった
- receipts.ts の parse action の行番号、チェックリストの件数集計、
  撮り直しのテスト手順(読み取り成功後はファイル選択が出ない)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
高:
- authorizedParties だけではConvexへの直接アクセスを塞げない。画面のデータは
  ConvexProviderWithClerk がClerkのJWTを直接Convexへ送る経路で流れており、
  convex/auth.config.ts は Issuer と applicationID しか検証しないため、
  Proxy側の azp 検査は迂回できる。Clerkの Allowed Subdomains を有効にする
  手順(deployment.md §1-5)を足し、proxy.ts のコメントにも「多層防御の1枚目」
  だと明記した

中:
- Vercelの初回作成順序が実際の画面と食い違っていた。環境変数はImport画面で
  入れられるがドメインはプロジェクト作成後でないと足せず、
  CLERK_AUTHORIZED_PARTIES は本番URL確定後になる。§3 を実際の順序に組み直した
- Clerkにサブドメインを登録すると Primary / Secondary を聞かれ、Clerk基盤の
  ホスト名が変わる。リダイレクトURIとIssuer URLは画面の実物をコピーする旨を追記
- 置き去りアップロードの経路が1本ではなかった。Storageへの POST 成功後に
  registerUpload が失敗すると台帳に行が残らず、uploads を走査するcronでは
  回収できない。_storage 側の走査も要ることを計画書のTBD-002に追記

低:
- CLERK_AUTHORIZED_PARTIES を new URL().origin で正規化するようにした。Clerkは
  azp と完全一致で判定するので、末尾スラッシュ・大文字・:443 の表記ゆれだけで
  全員がログインできなくなる。解釈できない値はログに残して無視する。
  症状→原因の早見表にもこの原因を追加
- releaseUpload は現状のUIから到達できない(読み取り成功後はファイル選択が消え、
  編集画面にも画像差し替えUIが無い)。チェックリストと計画書に明記
- 検証チェックリストの旧「金額不一致ガード」の取り残し、proxy.ts の行番号、件数集計

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
中:
- CLERK_AUTHORIZED_PARTIES の検証を http/https に限定した。new URL() だけでは
  オリジンの検証にならず、ftp:// はそのまま通り、file: / data: / javascript: は
  "null" というオリジンになり、blob:https://… は中のHTTPSオリジンとして通る
- 上と関連して、手順書の説明と症状早見表が実装と逆になっていた。値の間違え方は
  2通りあり症状が逆になる(別オリジン=全員ログイン不可 / オリジンとして解釈
  できない=無視されて検査なし)ので、両方を書き分けた
- Allowed Subdomains は完全修飾ドメインで登録する。また Primary application と
  Secondary application で必要な作業が変わる(Secondary ではアプリ自身が
  Primary domain になり常に許可される)

低:
- TBD-002 の経路A/Bの条件を実装に合わせた。レート制限は generateUploadUrl で
  消費するのでPOSTより手前で断られ、置き去りの原因にはならない。撮り直し時の
  discardUpload 失敗は台帳に行が残るので経路A側
- 検証チェックリストの Deploy certificates の参照先(§1-5 → §1-6)と
  proxy.ts の行番号

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- CLERK_AUTHORIZED_PARTIES が "," のように区切り文字だけだと、空要素が先に
  除去されて entries が空になり、警告も出ないまま検査なしに倒れていた。
  判定を raw 側に変えて、設定はしたのに有効な値が無いケースを必ず警告する
- 手順書とチェックリストが「別オリジンが1件あれば全員ログイン不可」
  「解釈できない値が1件あれば検査なし」と読めた。実装はエントリ単位なので、
  有効なオリジンが1件でも残れば検査は続き、1件も残らないときだけ倒れる
- 存在しない節への参照(計画書 §12-12)を実際の位置に直した

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- CLERK_AUTHORIZED_PARTIES の症状の説明で、2つの条件が重なっていて同じ設定が
  「全員ログイン不可」と「検査なし」の両方に読めた。書いた値と渡すもの・症状の
  対応表に置き換えた
- 前のコミットでコメントを3行足したぶん、検証チェックリストの proxy.ts の
  行番号がずれていた

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
書いた値の組み合わせを並べる書き方だと、列挙から漏れるパターンが出る。
症状は「http(s)のオリジンとして残った集合」だけで決まるので、
本番を含む / 1件以上あるが本番を含まない / 0件 の3状態に整理した。

あわせて「どちらもログに警告が出る」を訂正した。値としては正しいオリジンを
書き間違えた場合(=全員ログインできなくなるケース)は proxy.ts から間違いだと
判断できないので警告が出ない。ここが一番気づきにくいので明記した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 複数の別オリジンが残りうるので「その別オリジン」→「残ったオリジンすべて」
- 警告の条件を2種類に分けて書いた。解釈できなかった値は残りの件数に関係なく
  1件ずつ警告が出る。0件時の追加警告は raw が空でないときだけで、未設定・
  空文字では出ない(既定の挙動なので警告する意味がない)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1115 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c2c7b28e-35f2-4107-a6fe-b1983e3d2d1f

📥 Commits

Reviewing files that changed from the base of the PR and between 02c2245 and 3cdae1e.

📒 Files selected for processing (3)
  • docs/deployment.md
  • docs/implementation-plan.md
  • docs/verification-checklist.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/implementation-plan.md
  • docs/deployment.md
  • docs/verification-checklist.md

Walkthrough

レシート未読取エラーの分類と画面導線を更新し、本番デプロイ用のVercel・Clerk設定を追加した。Clerk、Convex、Vercelの運用手順、検証チェックリスト、実装計画も更新した。

Changes

レシート読み取り失敗処理

Layer / File(s) Summary
失敗種別とUI導線の統一
lib/receipt.ts, convex/receipts.ts, app/(app)/expenses/new/receipt/receipt-client.tsx
未読取エラーを共有定数で判定し、unreadable として管理する。通常の解析失敗かつ画像がある場合のみ再読取を表示し、それ以外は手入力へ切り替える。

本番デプロイ設定

Layer / File(s) Summary
Vercel・Clerk・起動設定
vercel.json, proxy.ts, .claude/launch.json
Convex経由の本番ビルド、非production環境の無視条件、CLERK_AUTHORIZED_PARTIES のオリジン正規化、production起動設定を追加した。

デプロイ文書と検証

Layer / File(s) Summary
本番手順・確認項目の整備
docs/deployment.md, docs/implementation-plan.md, docs/implementation-plan.html, docs/verification-checklist.md
ClerkのDNS・証明書・Allowed Subdomains設定、Vercel・Convex・AIサービスの手順、トラブルシュート、検証項目を更新した。

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReceiptClient
  participant ConvexReceipts
  participant ReceiptConstants
  participant ReceiptUI
  ReceiptClient->>ConvexReceipts: parse または retryParse
  ConvexReceipts->>ReceiptConstants: ERR_UNREADABLE_RECEIPT を参照
  ConvexReceipts-->>ReceiptClient: 読み取り結果またはエラー
  ReceiptClient->>ReceiptUI: failedStep と phase を更新
  ReceiptUI-->>ReceiptClient: 再読取または手入力を選択
Loading

Possibly related PRs

Poem

ぴょんと跳ねれば本番へ
レシート迷子も道しるべ
読めなきゃ手入力、すぐ進む
Clerkの門には許可証を
うさぎも安心、月の夜

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Phase 9の本番デプロイ準備という内容を端的に示しており、変更内容と整合しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/phase-9-production-deploy

Warning

Tools execution failed with the following error:

Failed to run tools: 14 UNAVAILABLE: read ECONNRESET


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
app/(app)/expenses/new/receipt/receipt-client.tsx (1)

143-152: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

エラー分類の回帰テストを追加してください。

convex/receipts.ts Line 131-136 の ConvexError(ERR_UNREADABLE_RECEIPT) と画面導線の契約です。少なくとも、未読取時は再読み取り非表示・手入力表示、その他の読み取り失敗時は再読み取り表示となるケースをVitestで固定してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`(app)/expenses/new/receipt/receipt-client.tsx around lines 143 - 152,
Extend the Vitest coverage for handleParseFailure and the
ConvexError(ERR_UNREADABLE_RECEIPT) contract, asserting that unreadable receipts
hide rereading and show manual entry, while other parse failures show the reread
option. Keep the assertions focused on the resulting failedStep/UI flow and
preserve existing behavior.
docs/deployment.md (2)

53-53: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

コードフェンスに言語を指定してください。

MD040 を解消するため、経路図のフェンスへ text などの言語を付けてください。

Also applies to: 249-249

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/deployment.md` at line 53, Update the fenced code blocks containing the
deployment path diagrams in the deployment documentation to specify an
appropriate language, such as text, on each opening fence, including the
additionally affected block. Preserve the diagram contents unchanged.

Source: Linters/SAST tools


95-95: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

引用ブロック内の空行を解消してください。

MD028 が出ているため、空行を除くか引用ブロックを分離してください。

Also applies to: 295-295, 346-346

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/deployment.md` at line 95,
ドキュメント内の引用ブロックで、引用行の間にある空行を削除するか、引用ブロックを分離してMD028違反を解消してください。該当箇所は95行付近に加え、同様の295行付近と346行付近も確認してください。

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/`(app)/expenses/new/receipt/receipt-client.tsx:
- Line 233: parseAndDraft の catch 処理を、読み取り失敗と下書き保存失敗で分離してください。saveExpense
実行後のエラーは handleParseFailure に渡さず、AIを再実行しない保存失敗用の導線で処理してください。読み取り処理中の失敗では既存の
handleParseFailure を維持し、expenseId が未設定でも保存成功後の応答失敗による重複ドラフトを防いでください。

In `@docs/verification-checklist.md`:
- Around line 13-18:
docs/verification-checklist.mdの検証件数サマリと完了チェックを本文の列挙内容と一致させてください。本文が示す[!!!]16件、[!!]35件、[!]21件、合計72件に修正するか、不足している高優先度項目を追加し、すべての集計表示で同じ件数を使用してください。
- Line 5: docs/verification-checklist.md
の生成日(5-5)、確認済み日(104-104)、観測日時(251-251)に未来日を使用せず、それぞれ実際の作成日・実施日・確認日に修正する。未実施の記録は確認済みとして扱わず、予定であることを表現する。

---

Nitpick comments:
In `@app/`(app)/expenses/new/receipt/receipt-client.tsx:
- Around line 143-152: Extend the Vitest coverage for handleParseFailure and the
ConvexError(ERR_UNREADABLE_RECEIPT) contract, asserting that unreadable receipts
hide rereading and show manual entry, while other parse failures show the reread
option. Keep the assertions focused on the resulting failedStep/UI flow and
preserve existing behavior.

In `@docs/deployment.md`:
- Line 53: Update the fenced code blocks containing the deployment path diagrams
in the deployment documentation to specify an appropriate language, such as
text, on each opening fence, including the additionally affected block. Preserve
the diagram contents unchanged.
- Line 95:
ドキュメント内の引用ブロックで、引用行の間にある空行を削除するか、引用ブロックを分離してMD028違反を解消してください。該当箇所は95行付近に加え、同様の295行付近と346行付近も確認してください。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 606e0ade-f4dd-4671-bea4-bc43ac4f0937

📥 Commits

Reviewing files that changed from the base of the PR and between e9cb1ce and fc91479.

📒 Files selected for processing (10)
  • .claude/launch.json
  • app/(app)/expenses/new/receipt/receipt-client.tsx
  • convex/receipts.ts
  • docs/deployment.md
  • docs/implementation-plan.html
  • docs/implementation-plan.md
  • docs/verification-checklist.md
  • lib/receipt.ts
  • proxy.ts
  • vercel.json

setError(toUserMessage(caught));
setFailedStep("parse");
setPhase("select");
handleParseFailure(caught);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

下書き保存の失敗を読み取り失敗として再試行させないでください。

parseAndDraft は読み取り後に Line 171-182 の saveExpense まで実行します。このcatchは保存失敗も handleParseFailure に渡すため、AIを再実行する導線になります。特に、Line 174 の expenseId が未設定のまま、サーバー側では保存成功・クライアント側では応答失敗となった場合、再試行で重複ドラフトになり得ます。読み取りと下書き保存を別ステージとして扱い、保存失敗時はAIを再呼び出ししない導線に分離してください。

Also applies to: 272-272

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`(app)/expenses/new/receipt/receipt-client.tsx at line 233, parseAndDraft
の catch 処理を、読み取り失敗と下書き保存失敗で分離してください。saveExpense 実行後のエラーは handleParseFailure
に渡さず、AIを再実行しない保存失敗用の導線で処理してください。読み取り処理中の失敗では既存の handleParseFailure
を維持し、expenseId が未設定でも保存成功後の応答失敗による重複ドラフトを防いでください。


> 仕様書: `docs/requirements.md`
> 対象実装: warikapp 全体(Phase 0〜9 / `main`〜`feature/phase-9-production-deploy`)
> 生成日: 2026-07-27

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

将来日を「確認済み」の記録に使わないでください。

現在日付の 2026年7月26日 時点で、2026年7月27日 は未来です。実施日へ修正するか、未実施なら予定として表現してください。

  • docs/verification-checklist.md#L5-L5: 生成日を実際の作成日へ修正する。
  • docs/verification-checklist.md#L104-L104: 確認済み日を実施日へ修正する。
  • docs/verification-checklist.md#L251-L251: 観測日時を実際の確認日へ修正する。
📍 Affects 1 file
  • docs/verification-checklist.md#L5-L5 (this comment)
  • docs/verification-checklist.md#L104-L104
  • docs/verification-checklist.md#L251-L251
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/verification-checklist.md` at line 5, docs/verification-checklist.md
の生成日(5-5)、確認済み日(104-104)、観測日時(251-251)に未来日を使用せず、それぞれ実際の作成日・実施日・確認日に修正する。未実施の記録は確認済みとして扱わず、予定であることを表現する。

Comment thread docs/verification-checklist.md
手順書が「ドメインを持っている前提」で始まっていたので、その手前を埋めた。
Cloudflare Registrar を選んだ理由(原価販売・更新時の値上げが無い・
WHOISプライバシー無料)と、購入直後のICANN確認メール(15日で停止される)を
チェック項目にした。DNSを正しく張ってもドメイン自体が死ぬ経路なので、
原因を見失いやすい。

あわせて、ルートドメインが後から変えられない理由(Clerkのissuerが
members.tokenIdentifier に焼き付く)を §0 に明記した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1156 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/deployment.md`:
- Line 93: Update the fenced code blocks in the deployment instructions to
include an explicit language identifier, such as text, immediately after each
opening fence. Ensure all applicable fences satisfy Markdownlint MD040 without
changing their content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 487830b1-5a2d-46f3-bf17-b88013d9a47c

📥 Commits

Reviewing files that changed from the base of the PR and between fc91479 and 699d770.

📒 Files selected for processing (1)
  • docs/deployment.md

Comment thread docs/deployment.md
Cloudflare Registrar で yamk12nfu.com を取得したので、example.com の
プレースホルダを実際の値にした。アプリは warikapp.yamk12nfu.com。

Clerk の Primary / Secondary の選択も Secondary に確定させた。ルートドメインは
他のプロジェクトでも使う前提なので、このアプリの Clerk 基盤はアプリの
サブドメイン配下(clerk.warikapp.yamk12nfu.com)に閉じ込める。これに伴い
§1-5 の Allowed Subdomains も「Secondary なら足すものは無い」を主にした。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1158 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

「必ず応答すること、15日で停止」と書いたのは ICANN の一般ルールをそのまま
写したもので、Cloudflare の実際の挙動を反映していなかった。Cloudflare
Registrar は Cloudflare アカウントのメールで登録者検証を満たすため、
確認メールは基本的に届かない。届かないのを異常と思って待たせてしまう。

メールを探させる代わりに、レジストリ側の Domain Status を見る手順に
差し替えた(clientHold が付いていなければ検証待ちではない)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1174 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

「画面に出ているとおりに追加する」で済ませていたので、実際に踏む罠が
書かれていなかった。1-2a / 1-2b として分け、次を明示した:

- CloudflareのName欄はゾーン名が自動で補われるので、Clerkが表示する完全修飾名を
  そのまま貼ると二重になりうる。入力後に一覧の表示名を突き合わせて確認する
- Proxy status の既定は Proxied。オレンジのままだとCNAMEがCloudflareのIPで
  隠れ、Clerkのドメイン検証が永久に通らない。DNS only に切り替える
  (_ で始まる名前は元からプロキシ不可なので対象外)
- Clerkの Verify を押す前に dig で自分で引ける。空なら名前ミスか未反映、
  CloudflareのIPが返るならProxied、と切り分けられる

Vercel側(§3-3)も同様に表形式にし、こちらも DNS only が要る理由
(証明書発行・SSLモード次第のリダイレクトループ)を書いた。
症状→原因の早見表にも2行足した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1236 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

§ は法律・学術の引用記号で、手順書の中では何のマークか分かりにくい。
参照先の種類ごとに日本語の言い方に置き換えた:

- deployment.md 自身の節   → 「手順1-2」「手順3-3」
- 計画書への参照           → 「計画書の11章」
- 要件定義書への参照       → 「要件定義書 6.3」
- 「全体の順序」ブロック内 → 全行が手順なので接頭辞なし(1-1, 1-2 …)

冒頭の「最後の7」も「末尾の『症状 → 原因の早見表』」に直した。

全参照が実在する見出しを指していることを確認済み。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1238 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

実際に進めたところ、Clerkに「Authorize DNS records from Clerk」が出て
5件のCNAMEを自動で入れてくれた。しかも全件 DNS only、Nameもゾーン相対で、
手順書で警告した二重付与とプロキシONの罠を両方回避してくれる。

手入力を主にしておく理由が無いので、自動連携を主にして手入力は
details に畳んだ。確認すべきことだけ残した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1252 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
docs/deployment.md (1)

110-110: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

コードフェンスに言語識別子を付けてください。

MD040違反が残っています。過去レビューと同様に、手順一覧のフェンスを text などで明示してください。

修正例
-```
+```text
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/deployment.md` at line 110, Update the code fences in the deployment
procedure list to include an explicit language identifier such as text,
resolving the MD040 violations while preserving the existing fenced content.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/deployment.md`:
- Line 436: docs/deployment.md の該当するブロック引用を確認し、引用内の空行による MD028
違反を修正してください。空行を削除するか、段落区切りとして残す場合は空行にも引用記号を付け、引用ブロック内の形式を統一してください。
- Around line 111-114: Update the Cloudflare Registrar step in the deployment
instructions so ICANN email verification is handled only when required, and
direct the reader to confirm the registry status instead of treating email
response as mandatory. Keep the remaining Clerk and OAuth steps unchanged.
- Line 187: docs/deployment.md の該当するブロック引用を整形し、引用内の空行による MD028
違反を解消してください。空行を削除するか、段落区切りとして残す場合は各空行後の内容にも引用記号を付け、引用範囲の書式を統一してください。
- Around line 48-50: docs/deployment.md
の取得日記載を更新し、未来日付の「2026-07-30」を実際の取得・確認日に置き換えるか、未実施なら予定日であることを明記してください。対象の取得済み表記と関連する日付記述のみ変更し、ドメイン方針は維持してください。

---

Duplicate comments:
In `@docs/deployment.md`:
- Line 110: Update the code fences in the deployment procedure list to include
an explicit language identifier such as text, resolving the MD040 violations
while preserving the existing fenced content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 88946269-07c9-4413-ab1f-725a2221fa0f

📥 Commits

Reviewing files that changed from the base of the PR and between 699d770 and 02c2245.

📒 Files selected for processing (3)
  • docs/deployment.md
  • docs/implementation-plan.md
  • docs/verification-checklist.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/implementation-plan.md
  • docs/verification-checklist.md

Comment thread docs/deployment.md
Comment on lines +48 to +50
**この節は取得済み(2026-07-30)。** 記録として残す。
ルートは個人名義、アプリはサブドメインにするという方針で
**ルート `yamk12nfu.com` / アプリ `warikapp.yamk12nfu.com`** にした。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

実測日を未来の日付のままにしないでください。

現在は2026年7月29日なので、2026-07-30 はまだ発生していない日付です。実際の取得日・確認日に更新するか、未確定なら予定日として明記してください。

Also applies to: 86-86

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/deployment.md` around lines 48 - 50, docs/deployment.md
の取得日記載を更新し、未来日付の「2026-07-30」を実際の取得・確認日に置き換えるか、未実施なら予定日であることを明記してください。対象の取得済み表記と関連する日付記述のみ変更し、ドメイン方針は維持してください。

Comment thread docs/deployment.md Outdated
Comment thread docs/deployment.md
Comment thread docs/deployment.md
実際に設定しようとして Subdomain cannot be the domain itself で弾かれた。
原因は手順書の前提が古かったこと。

この設定が制限するのは「プライマリドメイン配下」のサブドメイン。手順1-2 で
Secondary application を選んだ結果、プライマリドメインはアプリ自身
(warikapp.yamk12nfu.com)になっており、

- アプリはプライマリドメインそのものなので常に許可される(入力欄に入れられない)
- 制限対象は なにか.warikapp.yamk12nfu.com だけで、そんなホストは作らない
- ルートに置く別プロジェクトはこのインスタンスのサブドメイン空間の外

つまり Secondary を選んだ時点で、この設定でやりたかった分離は構造的に
達成済みだった。ONにして空リストのまま放置すると Clerk 自身のホストへの
影響が読めないので、OFF を推奨に変えた。

Primary application を選んだ場合は従来どおり必要なので、その分岐は残した。
検証チェックリストも「プライマリドメインがアプリ自身か」を見る項目に変更。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1261 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

DNS検証が通った時点でClerkが証明書を自動発行するため、Deploy certificates
ボタンは出ないことがある。「押す」前提で書いていたので、押すものを探させて
しまった。Primary/DNS/SSL の3つが緑かを見る形にし、curl での確認も足した。

Danger zone の Change domain を押さない注意も同じ節に置いた。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1277 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

中:
- Allowed Subdomains の判断が逆だった。OFF は *.warikapp.yamk12nfu.com を
  許可したままで、ON+空リストのほうが「プライマリドメインだけ許可」= 狭い。
  「Clerk自身のホストへの影響が読めない」という根拠も公式仕様と合わない
  (プライマリドメインは常に許可される)。3文書とも ON+空リスト に統一し、
  ONにしたらログインし直して確認する、を必須にした
- 「現在地」が「Clerkは開発インスタンスのみ」のままで、本番構築済みの実態と
  食い違っていた。手順1-1からやり直させてしまう
- Deploy certificates の完了条件が3文書でバラバラ(「必ず押す」vs「Issued確認」)。
  ボタンの有無ではなく SSL certificates: Issued で判定、に統一
- dig で proxied を判定できていなかった。Cloudflareはプロキシ中のCNAMEを
  flatten するので、判定材料は「CNAMEが返るか」。さらに実測したところ、
  Clerk自身がCloudflareの裏にいるため正常時でもA問い合わせは 104.x/172.64.x を
  返す。IPで判定する書き方は誤診を生むので直した

低:
- 冒頭のIssuer説明が Primary application 前提のままだった
- ICANN確認メールの訂正の取りこぼし(購入手順と全体の順序)と、clientHold の
  原因を検証滞留と断定していた点(支払い不備・紛争でも付く)
- 存在しない参照先(verification-checklist.md の「手順6」)
- 「更新時の値上げが無い」は言い過ぎ(上乗せしないだけで、レジストリの
  価格改定は反映される)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

aro guard: policies 違反を検出しました

kind path 内容
outside_allowed_paths vercel.json allowed_paths のいずれにも一致しません: vercel.json
too_many_added_lines - 追加行数の合計が上限を超えています: 1302 > 400

検証ルールは base 側の .ai/project.yaml と適用 policy から読まれます(PR 内の変更では緩められません)。詳細: docs/guard.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant