|
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
Docker Emulator Test / docker (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Test / docker (push) Has been cancelled
Runs E2E API Tests / build (22.x) (push) Has been cancelled
Runs E2E API Tests with external source of truth / build (22.x) (push) Has been cancelled
Lint & build / lint_and_build (latest) (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests / setup-tests (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
<!-- Make sure you've read the CONTRIBUTING.md guidelines: https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md --> <!-- RECURSEML_SUMMARY:START --> ## High-level PR Summary This PR implements a comprehensive renaming of "offer" to "product" and "offer group" to "product catalog" throughout the codebase. The changes include database migrations, schema updates, API compatibility layers, function renames, and updates to client and server implementations. Backwards compatibility is maintained through migration layers that handle requests using the old terminology, translating them to the new terminology before processing. The PR includes documentation of this approach in CLAUDE-KNOWLEDGE.md. This rename affects multiple parts of the system including the database schema, API endpoints, error types, and SDK interfaces. ⏱️ Estimated Review Time: 1-3 hours <details> <summary>💡 Review Order Suggestion</summary> | Order | File Path | |-------|-----------| | 1 | `apps/backend/prisma/migrations/20250923191615_rename_offers_to_products/migration.sql` | | 2 | `apps/backend/src/app/api/migrations/v2beta1/payments/purchases/offers-compat.ts` | | 3 | `apps/backend/src/app/api/migrations/v2beta1/payments/purchases/create-purchase-url/route.ts` | | 4 | `apps/backend/src/app/api/migrations/v2beta1/payments/purchases/validate-code/route.ts` | | 5 | `apps/backend/src/lib/payments.tsx` | | 6 | `.claude/CLAUDE-KNOWLEDGE.md` | | 7 | `packages/stack-shared/src/schema-fields.ts` | | 8 | `packages/stack-shared/src/known-errors.tsx` | | 9 | `packages/stack-shared/src/config/schema.ts` | | 10 | `packages/template/src/lib/stack-app/customers/index.ts` | | 11 | `packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts` | | 12 | `packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts` | </details> [](https://discord.gg/n3SsVDAW6U) <!-- RECURSEML_SUMMARY:END --> <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > Renames 'offer' to 'product' and 'offer group' to 'product catalog' across the codebase, updating database schema, API endpoints, and application logic for consistency and backward compatibility. > > - **Database**: > - Rename columns `offer` to `product` and `offerId` to `productId` in `OneTimePurchase` and `Subscription` tables in `migration.sql`. > - **API & Migrations**: > - Update API endpoints to accept `product_id`/`product_inline` instead of `offer_id`/`offer_inline`. > - Add `v2beta5` compatibility layer to map legacy `offer` fields to `product` equivalents. > - **Shared Schemas**: > - Rename `offerSchema` to `productSchema` and related schemas in `schema-fields.ts`. > - **Server Implementation**: > - Update `createCheckoutUrl` method in `server-app-impl.ts` to use `productId`/`InlineProduct`. > - **Tests**: > - Update tests to reflect renaming in `backend-helpers.ts` and other test files. > - **Miscellaneous**: > - Remove dummy data related to offers in `dummy-data.tsx`. > - Update documentation and comments to reflect terminology changes. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup> for |
||
|---|---|---|
| .. | ||
| v2beta1 | ||
| v2beta2 | ||
| v2beta3 | ||
| v2beta4 | ||
| v2beta5 | ||
| README.md | ||
API migrations
First, make sure you have a good reason to do an API migration. While they're relatively low-effort in our codebase, most changes don't break backwards compatibility, so it might not be required.
Examples of changes that are breaking and hence require an API migration:
- You are adding a required field to a request, or narrowing the allowed values of an existing request field
- You are removing a field of a response, or widening the allowed values for a response field
- You are renaming a field or endpoint
- You are removing an endpoint entirely
- The behavior changes in other ways that might affect clients
- ...
Release versions (eg. v1, v2) are documented thoroughly, while beta versions (eg. v2beta1, v3beta2) are mostly used by our own packages/SDKs and some external beta testers. We still need to maintain backwards compatibility for beta versions, so the only purpose of differentiating is to prevent "migration fatigue" if we were to announce a new API version every week. Beta versions come before release versions: v1 < v2beta1 < v2beta2 < v2, etc.
Each folder in src/app/api/migrations is a migration. The name of the folder is the name of the version you're migrating to — so, if you're migrating from v2beta3 to v2beta4, the folder is called v2beta4. In other words, the files in v2beta4 will process all requests for versions LESS than v2beta4 (but not v2beta4 itself).
To create a new migration, simply add a new folder in src/app/api/migrations. This folder has the same structure as src/app/api/latest, although it will fall back to that folder for routes that are not found. Additionally, this new folder should contain extra files: beta-changes.txt (the list of changes since the last beta version), and release-changes.txt (the list of changes since the last release version — only required for release versions). For every endpoint you migrate, you will likely also have to modify the most recent migration of that endpoint in previous versions (if any) to call your newly created endpoint, instead of the one that can be found in latest.
To understand the flow of old migrations, imagine a request for a v2 endpoint. Instead of looking for a Next.js file in the src/app/api folder directly, the middleware will instead rewrite the request to src/app/api/migrations/v2beta1. If not found, it will check v2beta2, and so on. If no migration strictly newer than the requested version is found, it will return the route from src/app/api/latest.