Skip to content

refactor(store): hosted 購入 hook の純粋な応答 parser と phase 対応表を leaf に抽出 (R15b) - #622

Merged
cipherwebllc merged 1 commit into
mainfrom
fix/r6-r15b-purchase-parsers
Sep 24, 2026
Merged

cipherwebllc merged 1 commit into
mainfrom
fix/r6-r15b-purchase-parsers

Conversation

@cipherwebllc

Copy link
Copy Markdown
Owner

概要

第 6 回レビュー Phase 6 (完全リファクタ) の R15b です (指摘 F14)。挙動を変えない抽出だけです。
Creator Store の購入 hook hooks/useHostedStorePurchase.ts (1,022 → 878 行) から、純粋な応答 parser と phase の対応表 (12 宣言・152 行) を、React に依存しない lib/x402/hostedPurchasePhases.ts (171 行) に移します。

公開文言・通信は変わりません。

固定と検証 (base = main に rebase 済み)

  • parser の表テスト 63 件 (402 の v1/v2・pending・settled・エラー・未知の形) と、hook の公開 API 経由の pin 67 件 (全 phase・session と商品の切替・切替中の遅い応答) を追加しました。旧コードでも通ります。
  • 別セッションの Opus 5.5 のレビュー: approve。わざと壊した変更 6 通り (phase の入れ替え・JSON null の扱い・未知の形の受理・ok 判定の削除 等) をすべて検出しました。
  • typecheck 0 / eslint 0 / full vitest 14,666 pass

既存の不具合 (本 PR では変えない・B-R15d・掟 12/15)

商品を切り替えても、切り替え前の通信結果を捨てません (wallet の切替は捨てる)。前の商品の遅い 200 settled が届くと、quote のない provisioning で止まります。表示される「支払い済み」自体は事実で、支払っていない商品の provisioning が出ることは、商品 ID による作り直しで防がれています。本番で到達する条件はほぼありません (送信中に商品の props が変わるのは、出品者の編集を取り込む再読み込みのときだけ)。

🤖 Generated with Claude Code

https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc

@vercel

vercel Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
openpay Ignored Ignored Preview Sep 24, 2026 3:11pm UTC

Request Review

…R15b)

第 6 回レビュー Phase 6 の R15b (F14)。hooks/useHostedStorePurchase.ts (1,022 行) から
応答の解釈と phase → 表示状態の対応 (12 宣言・byte 単位で同一) を browser-safe な
lib/x402/hostedPurchasePhases.ts に移す。session/product の scope・署名済み request の ref・
古い完了の保護・effect と timer は hook に残す (money-path の制御フローは不変)。
hook の公開 export と path は同じ。旧コードで固定した parser の表 (63) と hook の公開 API
経由の pin (67) を追加した。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc
@cipherwebllc
cipherwebllc force-pushed the fix/r6-r15b-purchase-parsers branch from 9498528 to 8a6f937 Compare September 24, 2026 15:11
@cipherwebllc
cipherwebllc merged commit 3305e3e into main Sep 24, 2026
10 of 11 checks passed
@cipherwebllc
cipherwebllc deleted the fix/r6-r15b-purchase-parsers branch September 24, 2026 16:05
cipherwebllc added a commit that referenced this pull request Sep 24, 2026
「unresolved old payment scopes the relay checkout hold and notice」は、fixture の時刻が実時刻で
発行される一方 vi.waitFor が fake 時計を進め、遅延 import の完了前に通知が描画されると
recovery のタイマーが未設置のまま期限判定に進む競合で、CI と並列負荷で時々落ちていた
(#622 の CI・R14 レビューで 7 回中 2 回)。時計を setup 前に固定し、vi.dynamicImportSettled() を
待ってから期限の 1ms 前と期限へ明示的に進める。元の assert はすべて残し、期限ちょうどに
状態を 1 回読むことを追加で固定した。隣の「expiry read holds payment until %s completes」も
同じ原因で単独実行だと必ず落ちていた (先の test が module を読み込むおかげで通っていた) ため
同じ形に直した。単独 25/25・併走 10/10・負荷下の file 全体 368/368。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc
cipherwebllc added a commit that referenced this pull request Sep 24, 2026
…正) (#640)

「unresolved old payment scopes the relay checkout hold and notice」は、fixture の時刻が実時刻で
発行される一方 vi.waitFor が fake 時計を進め、遅延 import の完了前に通知が描画されると
recovery のタイマーが未設置のまま期限判定に進む競合で、CI と並列負荷で時々落ちていた
(#622 の CI・R14 レビューで 7 回中 2 回)。時計を setup 前に固定し、vi.dynamicImportSettled() を
待ってから期限の 1ms 前と期限へ明示的に進める。元の assert はすべて残し、期限ちょうどに
状態を 1 回読むことを追加で固定した。隣の「expiry read holds payment until %s completes」も
同じ原因で単独実行だと必ず落ちていた (先の test が module を読み込むおかげで通っていた) ため
同じ形に直した。単独 25/25・併走 10/10・負荷下の file 全体 368/368。


Claude-Session: https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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