Skip to content

refactor(api): Stripe SDK への到達経路を Context の stripe.sdk に統一する - #52

Open
reiroop wants to merge 1 commit into
mainfrom
refactor/stripe-sdk-path
Open

reiroop wants to merge 1 commit into
mainfrom
refactor/stripe-sdk-path

Conversation

@reiroop

@reiroop reiroop commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

ContextstripeStripe から { sdk: Stripe } に変え、プロシージャが SDK を取り出す経路を 1 つにする。あわせて、変更系ガードのテストが検出できる変異を増やす。

なぜ

sdk プロパティで Stripe を返すオブジェクトなら何でも代入できる形にしておくと、プロシージャを変えずに実体を差し替えられる。この PR は Context の型と呼び出し側をその形に合わせるところまでで、実体の差し替えは行わない。

実装している決定

Stripe SDK への到達経路を 1 つにする

Context に SDK を直接置く形(変更前の stripe: Stripe)と、sdk プロパティを持つオブジェクトを置く形を比べ、後者を採った。前者のままだと、実体を sdk を持つアダプタに差し替えるときにプロシージャ 11 箇所の書き換えが要る。後者なら、本番の Context を組み立てる apps/web/server/routes/rpc/[...].ts の 1 箇所だけで差し替えが済み、プロシージャの側も Context の型も変えずに済む。

stripe を残したまま SDK を別フィールドで併置する形は採らなかった。SDK への経路が 2 つになり、stripe.sdk を通らない呼び出しが型の上で許されたままになる。経路を 1 つにするというこの PR の目的が達成されない。

apiVersion の明示的な指定を保つ

apps/web/server/utils/stripe.tsuseStripe() を残し、この PR では削除しない。このファイルが apiVersion を明示的に指定しており、省略するとアカウントの既定の API バージョンに従って SDK の型と実行時のレスポンスの形がずれることがある。SDK を更新すると LatestApiVersion 型が変わり、この文字列が型エラーになって気付ける。

変更系ガードのテストを強める

prices.updateproducts.updateinvoices.issuemutationsEnabled が false のとき FORBIDDEN を投げる。既存のテストは拒否されたことしか見ておらず、次の 2 つを検査していなかった。

  • 投げられたエラーのコードが FORBIDDEN であること
  • Stripe への書き込みが起きなかったこと

前者が無いと、ガードが別のエラーを投げるようになっても通る。後者が無いと、ガードを書き込みの後ろへ動かしても通る。どちらも、認可を持たない書き込みが Stripe に到達する状態を、CI がグリーンのまま許す形である。

変更をこの範囲で切る

実体の差し替え(useStripe() を削除し、sdk を持つアダプタに寄せる)は、この PR には含めず後続の PR で行う。新しいアダプタのファイルもこの PR では作らない。{ sdk: useStripe() } は既存の useStripe() をその場で包むだけなので、後でアダプタを採るときに置き換える対象が 1 つで済む。

まとめて 1 つの PR にする案は採らなかった。sdk 経路が正しく当たっているかという判断と、どのアダプタを採るかという判断が同じ差分に混ざり、レビュアーが失敗を見たときにどちらの軸の失敗かを切り分けられなくなるためである。この PR 単体で lint・型チェック・テスト・ビルドが通るので、分けても途中で壊れた状態は残らない。

apps/web/package.jsonstripe の依存と apps/web/server/plugins/validate-config.ts も変更していない。この PR が変えるのは SDK の取り出し方だけで、SDK の生成も鍵の存在チェックも変えていないためである。

確かめたこと

pnpm lintpnpm knippnpm typecheckpnpm testpnpm build がすべて通る。SDK への参照がすべて sdk を経由することは、git grep -n 'context\.stripe\.' -- packages/api/src | grep -v 'context\.stripe\.sdk\.' が何も返さないことで確かめられる。

強めたテストについて、主張が成り立たなくなる変異を当てて、どの変異でもテストが失敗することを確かめた。ガードそのものへの変異は assertMutationsEnabled に、プロシージャ側への変異は prices.update に当てた。「変更前のテスト」の列は、この PR の直前のコミットの実装とテストに同じ変異を当てた結果である。

変異 この PR のテスト 変更前のテスト
ガードの throw を削る 失敗する 失敗する
ガードが投げるコードを別のものに変える 失敗する 通ってしまう
ガードの条件を反転する 失敗する 失敗する
プロシージャからガードの呼び出しを削る 失敗する 失敗する
ガードを Stripe への書き込みの直後へ移す 失敗する 通ってしまう
ガードの例外を握りつぶして処理を続ける 失敗する 失敗する

変更前のテストを通ってしまう 2 つは、検査していなかった 2 つにそのまま対応する。エラーのコードを見ていなかったので「ガードが投げるコードを別のものに変える」が、書き込みが起きなかったことを見ていなかったので「ガードを Stripe への書き込みの直後へ移す」が、それぞれすり抜ける。

Context の stripe を Stripe から { sdk: Stripe } に変え、プロシージャが
SDK を取り出す経路を 1 つにする。sdk プロパティで Stripe を返すオブジェクト
なら何でも代入できるので、プロシージャを変えずに実体を差し替えられる。

あわせて、変更系ガードのテスト 3 件を強めた。これまでは拒否されたことしか
見ておらず、エラーのコードも、Stripe への書き込みが起きなかったことも
検査していなかった。ガードを書き込みの後ろへ動かす変更や、投げるエラーを
別のものに替える変更を検出できない状態だったので、FORBIDDEN のコードと
スタブが呼ばれなかったことの両方を表明する形にした。

apps/web/server/utils/stripe.ts は残しているので、apiVersion の明示的な
指定と SDK の遅延生成・キャッシュは変わらない。
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 0032bbfc-4d39-4b71-9bff-517be4024a4d


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.

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