- Ya
- 26 Agosti 2026, 02:40 UTC
- Mwandishi
- Kamo
- Ahadi ya
- d54a9fe
Round 1 review (Ruling 15) found the Critical: a stable idempotency key on an update/cancel/attach/detach is not a safeguard, it is a bug. Those calls already set an explicit target state, so they are idempotent in effect without any key; a stable key instead lets Stripe's 24h cached-response replay swallow a genuinely later change. Concretely: cancel() -> reactivate() -> cancel() presented the SAME key on both cancel() calls, so the second one got back the FIRST call's cached response and never touched the live subscription -- the DB and UI said "will not renew" while Stripe kept billing, with no exception anywhere. The same shape hit the default-payment-method toggle and syncStripeItems' proration-bearing update (5 seats -> 10 -> 5 would have dropped a real proration). Neither AccountSubscription nor Account carries a per-invocation field (no updated-at that moves, no version column) to fold into a key instead, which is why the fix is no key at all on these ten mutations, not a smarter one. Keeps the key on all ten genuine creates (SetupIntent, Customer, Session, four Price.create, Product, Meter, Subscription.create), which remain non-idempotent by nature and still need one. StripeIdempotency's class javadoc now states this plainly, including the specific cancel/reactivate/cancel failure mode, so the ten mutation call sites aren't "restored" later. The coverage test now asserts both directions: every create carries a key **************** a forward-looking regex net) and no mutation does **************** for the regex-visible ones, plus **************** pinning the true per-file count so a key added back to any of the local-variable- receiver mutations the regex cannot see -- most of AccountSubscriptionService's and AccountPaymentMethodService's -- still fails the build). Verified both new assertions actually catch a reintroduced key before reverting the probe.