improvement(aws-marketplace): close billing gaps and simplify the license write paths

Merged
WA
2d ago
+452-233

Summary

  • Linking a Marketplace license to an organization that already pays Stripe for a self-serve plan is refused (buyer and admin paths), so AWS and Stripe never bill the same organization. Enterprise stays linkable, since the team provisions it with collection paused
  • The Stripe checkout block counts only licenses of listings this deployment still sells
  • A usage record frozen for sending is never added to, even when the charge and the freeze hold locks for different organizations (a license relinked after its organization was deleted); the charge rolls back and its units go to the next record
  • Container license: a delegate grant, or one pending, rejected, disabled, or deleted by the license administrator, no longer turns Enterprise on; replicas restart at random points over ten minutes on a license change instead of all at once
  • CloudFormation prerequisites: the RDS password is a fixed, URL-safe generated secret. RDS's managed password rotates every 7 days and may contain characters that break the connection URL, while the chart copies it into a Kubernetes Secret once
  • Example values use a placeholder product ID, and say how to read both passwords out of Secrets Manager
  • Simplification: one insert path for new licenses, the inactive-has-no-claim rule applied in one place, a once-only team notice helper, a single buyer contact shape, the claim lookup, lock recheck, and audit entry each written once, a shared products-map type, and a misplaced doc comment moved to its function

Type of Change

  • Bug fix
  • Improvement

Testing

  • lifecycle.integration.ts, metering.integration.ts, checkout-guard.integration.ts against Postgres: 96 pass
  • New tests: Stripe-billed organizations are refused and Enterprise ones linked; a license on a listing no longer sold does not block checkout. Each goes red with its guard reverted
  • authorization.test.ts, entitlements.test.ts, aws-marketplace.test.tsx: 22 pass
  • bun run lint, type-check, check:audits (all but the local-only docs content registry); aws cloudformation validate-template on the prerequisites template

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)