create-ailk 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -22
- package/component-catalog.json +3 -3
- package/component-catalog.md +3 -3
- package/dist/add-module.js +4 -2
- package/dist/add-route.d.ts +12 -1
- package/dist/add-route.js +31 -3
- package/dist/cli.js +12 -7
- package/dist/derive-architecture.d.ts +3 -4
- package/dist/derive-architecture.js +65 -29
- package/dist/lib/design-checks.d.ts +9 -4
- package/dist/lib/design-checks.js +13 -7
- package/dist/lib/extract-module-bundle.js +29 -2
- package/dist/lib/fetch-template-snapshot.d.ts +2 -1
- package/dist/lib/fetch-template-snapshot.js +8 -3
- package/dist/lib/import-graph.d.ts +1 -1
- package/dist/lib/import-graph.js +4 -4
- package/dist/lib/module-license-gate.d.ts +12 -1
- package/dist/lib/module-license-gate.js +36 -15
- package/dist/lib/module-tier.d.ts +2 -8
- package/dist/lib/module-tier.js +13 -12
- package/dist/module-architecture.d.ts +20 -3
- package/dist/module-architecture.js +129 -552
- package/dist/paid-sections.d.ts +25 -1
- package/dist/paid-sections.js +88 -3
- package/dist/starter-grid.d.ts +6 -6
- package/dist/starter-grid.js +12 -5
- package/dist/surfaces.js +39 -2
- package/dist/template-record.d.ts +21 -3
- package/dist/template-record.js +38 -7
- package/dist/topology.d.ts +16 -3
- package/dist/topology.js +54 -23
- package/dist/update.d.ts +10 -1
- package/dist/update.js +715 -21
- package/package.json +3 -3
- package/release-scope.json +2 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +8 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +2 -2
- package/site-templates/marketing-site/ailk-template.json +7 -1
- package/site-templates/marketing-site/provenance.json +7 -1
- package/site-templates/saas-product/ailk-template.json +2 -1
- package/site-templates/saas-product/provenance.json +1 -0
- package/templates/.claude/cloudparity-repo-hooks.json +5 -0
- package/templates/.claude/hooks/template-guard.sh +137 -0
- package/templates/.claude/rules/extending.md +106 -0
- package/templates/.claude/rules/loop-contract.md +2 -2
- package/templates/.claude/settings.json +11 -0
- package/templates/.env.example +20 -5
- package/templates/.github/workflows/ci.yml +7 -4
- package/templates/CLAUDE.md +11 -1
- package/templates/CONVENTIONS.md +8 -10
- package/templates/README.md +14 -13
- package/templates/apps/api/.env.example +23 -2
- package/templates/apps/api/CLAUDE.md +119 -83
- package/templates/apps/api/jest.config.cjs +15 -5
- package/templates/apps/api/package.json +16 -20
- package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
- package/templates/apps/api/src/index.ts +1 -1
- package/templates/apps/api/src/lib/__mocks__/prisma-client.js +16 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
- package/templates/apps/api/src/modules/commerce.ts +10 -0
- package/templates/apps/api/src/modules/content-write.ts +10 -0
- package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
- package/templates/apps/api/src/modules/scheduling.ts +10 -0
- package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
- package/templates/apps/api/src/modules/workspace.ts +10 -0
- package/templates/apps/api/src/server.ts +117 -1882
- package/templates/apps/api/vercel.json +2 -2
- package/templates/apps/mcp/CLAUDE.md +90 -26
- package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
- package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
- package/templates/apps/mcp/jest.config.cjs +6 -1
- package/templates/apps/mcp/package.json +5 -13
- package/templates/apps/mcp/src/app.ts +8 -7
- package/templates/apps/mcp/src/index.ts +6 -34
- package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
- package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
- package/templates/apps/mcp/src/site.ts +12 -0
- package/templates/apps/web/.env.example +1 -1
- package/templates/apps/web/CLAUDE.md +31 -3
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +43 -4
- package/templates/apps/web/app/[locale]/(auth)/legal-footnote.tsx +35 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +117 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +14 -37
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +6 -6
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +20 -35
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +108 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +111 -5
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +78 -16
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +132 -12
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +53 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +4 -2
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +47 -24
- package/templates/apps/web/app/[locale]/(authed)/signed-out-gate.generated.tsx +23 -4
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
- package/templates/apps/web/app/[locale]/layout.tsx +33 -13
- package/templates/apps/web/app/[locale]/meet/confirmed/BookingHandOff.tsx +128 -0
- package/templates/apps/web/app/[locale]/meet/confirmed/__tests__/BookingHandOff.test.tsx +126 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
- package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
- package/templates/apps/web/app/api/revalidate/route.ts +3 -3
- package/templates/apps/web/auth.ts +10 -6
- package/templates/apps/web/i18n/request.ts +49 -1
- package/templates/apps/web/jest.config.cjs +1 -0
- package/templates/apps/web/lib/__tests__/account-config.test.ts +7 -0
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +276 -0
- package/templates/apps/web/lib/auth-email.ts +103 -21
- package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +72 -23
- package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +94 -70
- package/templates/apps/web/lib/prisma-for-auth.ts +5 -2
- package/templates/apps/web/lib/relay.ts +2 -2
- package/templates/apps/web/lib/release-scope.ts +47 -0
- package/templates/apps/web/lib/server-api.ts +1 -1
- package/templates/apps/web/lib/sign-up-agreements.ts +291 -28
- package/templates/apps/web/lib/site-contributions.ts +18 -0
- package/templates/apps/web/messages/en.json +186 -20
- package/templates/apps/web/messages/site/en.json +1 -0
- package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
- package/templates/customizations.yaml +37 -0
- package/templates/database/prisma.config.ts +10 -14
- package/templates/database/seed-test.ts +2 -2
- package/templates/database/seed.ts +5 -5
- package/templates/package.json +12 -6
- package/templates/pnpm-workspace.yaml +0 -1
- package/templates/project.yaml +16 -8
- package/templates/tools/jest/reporters.cjs +65 -0
- package/templates/tools/lint-architecture.ts +553 -7
- package/templates/tsconfig.json +1 -2
- package/versions.json +49 -36
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
- package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
- package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
- package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
- package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
- package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
- package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
- package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
- package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
- package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
- package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
- package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
- package/templates/apps/api/src/bin/spokes.ts +0 -198
- package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
- package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
- package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
- package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
- package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
- package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
- package/templates/apps/api/src/config/index.ts +0 -596
- package/templates/apps/api/src/config/modules.ts +0 -83
- package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
- package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
- package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
- package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
- package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
- package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
- package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
- package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
- package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
- package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
- package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
- package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
- package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
- package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
- package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
- package/templates/apps/api/src/lib/agent-store.ts +0 -613
- package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
- package/templates/apps/api/src/lib/consent-store.ts +0 -363
- package/templates/apps/api/src/lib/content-adapter.ts +0 -112
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
- package/templates/apps/api/src/lib/error-serializer.ts +0 -164
- package/templates/apps/api/src/lib/errors.ts +0 -95
- package/templates/apps/api/src/lib/file-fallback.ts +0 -87
- package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
- package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
- package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
- package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
- package/templates/apps/api/src/lib/license-key-store.ts +0 -45
- package/templates/apps/api/src/lib/locales.ts +0 -201
- package/templates/apps/api/src/lib/outbound-http.ts +0 -127
- package/templates/apps/api/src/lib/prisma.ts +0 -21
- package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
- package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
- package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
- package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
- package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
- package/templates/apps/api/src/lib/site.ts +0 -257
- package/templates/apps/api/src/lib/slice-load.ts +0 -90
- package/templates/apps/api/src/lib/spoke-store.ts +0 -180
- package/templates/apps/api/src/lib/stripe.ts +0 -321
- package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
- package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
- package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
- package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
- package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
- package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
- package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
- package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
- package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
- package/templates/apps/api/src/middleware/auth.ts +0 -864
- package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
- package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
- package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
- package/templates/apps/api/src/openapi/index.ts +0 -18
- package/templates/apps/api/src/openapi/spec.ts +0 -2148
- package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
- package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
- package/templates/apps/api/src/routes/aeo/index.ts +0 -107
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
- package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
- package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
- package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
- package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
- package/templates/apps/api/src/routes/auth/user.ts +0 -305
- package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
- package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
- package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
- package/templates/apps/api/src/routes/checkout/index.ts +0 -34
- package/templates/apps/api/src/routes/checkout/session.ts +0 -171
- package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
- package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
- package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
- package/templates/apps/api/src/routes/consent/account.ts +0 -268
- package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
- package/templates/apps/api/src/routes/consent/index.ts +0 -26
- package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
- package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
- package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
- package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
- package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
- package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
- package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
- package/templates/apps/api/src/routes/content/get-page.ts +0 -183
- package/templates/apps/api/src/routes/content/index.ts +0 -49
- package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
- package/templates/apps/api/src/routes/content/list-types.ts +0 -19
- package/templates/apps/api/src/routes/content/offerings.ts +0 -184
- package/templates/apps/api/src/routes/content/pricing.ts +0 -176
- package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
- package/templates/apps/api/src/routes/content/search.ts +0 -100
- package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
- package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
- package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
- package/templates/apps/api/src/routes/leads/index.ts +0 -639
- package/templates/apps/api/src/routes/leads/list.ts +0 -104
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
- package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
- package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
- package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
- package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
- package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
- package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
- package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
- package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
- package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
- package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
- package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
- package/templates/apps/api/src/routes/requests/index.ts +0 -54
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
- package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
- package/templates/apps/api/src/routes/webhooks/README.md +0 -398
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
- package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
- package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
- package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
- package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
- package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
- package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
- package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
- package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
- package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
- package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
- package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
- package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
- package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
- package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
- package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
- package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
- package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
- package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
- package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
- package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
- package/templates/apps/api/src/services/abandon-email.ts +0 -336
- package/templates/apps/api/src/services/aeo-score.ts +0 -325
- package/templates/apps/api/src/services/answer-distributions.ts +0 -138
- package/templates/apps/api/src/services/audit-log.ts +0 -961
- package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
- package/templates/apps/api/src/services/consent.ts +0 -834
- package/templates/apps/api/src/services/default-tenant.ts +0 -416
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
- package/templates/apps/api/src/services/dunning-policy.ts +0 -294
- package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
- package/templates/apps/api/src/services/entitlements.ts +0 -338
- package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
- package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
- package/templates/apps/api/src/services/lead-promotion.ts +0 -160
- package/templates/apps/api/src/services/lead-routing.ts +0 -1372
- package/templates/apps/api/src/services/leads-inbox.ts +0 -312
- package/templates/apps/api/src/services/listing-config.ts +0 -178
- package/templates/apps/api/src/services/magnet-completion.ts +0 -242
- package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
- package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
- package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
- package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
- package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
- package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
- package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
- package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
- package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
- package/templates/apps/api/src/services/offerings/index.ts +0 -614
- package/templates/apps/api/src/services/offerings/source.ts +0 -140
- package/templates/apps/api/src/services/offerings/store.ts +0 -150
- package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
- package/templates/apps/api/src/services/person.ts +0 -1211
- package/templates/apps/api/src/services/plan-offerings.ts +0 -125
- package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
- package/templates/apps/api/src/services/project-listings.ts +0 -2085
- package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
- package/templates/apps/api/src/services/request-confirm.ts +0 -698
- package/templates/apps/api/src/services/revalidation.ts +0 -235
- package/templates/apps/api/src/services/slack-notify.ts +0 -291
- package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
- package/templates/apps/api/src/services/usage-credits.ts +0 -340
- package/templates/apps/api/src/services/verified-email.ts +0 -71
- package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
- package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
- package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
- package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
- package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
- package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
- package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
- package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
- package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
- package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
- package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
- package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
- package/templates/apps/mcp/__tests__/index.test.ts +0 -195
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
- package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
- package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
- package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
- package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
- package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
- package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
- package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
- package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
- package/templates/apps/mcp/__tests__/server.test.ts +0 -388
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
- package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
- package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
- package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
- package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
- package/templates/apps/mcp/src/abuse/index.ts +0 -349
- package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
- package/templates/apps/mcp/src/boot.ts +0 -167
- package/templates/apps/mcp/src/config/modules.ts +0 -43
- package/templates/apps/mcp/src/http-transport.ts +0 -564
- package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
- package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
- package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
- package/templates/apps/mcp/src/lib/errors.ts +0 -61
- package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
- package/templates/apps/mcp/src/lib/locales.ts +0 -171
- package/templates/apps/mcp/src/lib/prisma.ts +0 -39
- package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
- package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
- package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
- package/templates/apps/mcp/src/lib/site-config.ts +0 -53
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
- package/templates/apps/mcp/src/request-context.ts +0 -52
- package/templates/apps/mcp/src/server.ts +0 -343
- package/templates/apps/mcp/src/serverless-app.ts +0 -88
- package/templates/apps/mcp/src/tools/audit.ts +0 -127
- package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
- package/templates/apps/mcp/src/tools/create_project.ts +0 -134
- package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
- package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
- package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
- package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
- package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
- package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
- package/templates/apps/mcp/src/tools/index.ts +0 -138
- package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
- package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
- package/templates/apps/mcp/src/tools/proposals.ts +0 -27
- package/templates/apps/mcp/src/tools/purchase.ts +0 -205
- package/templates/apps/mcp/src/tools/read_content.ts +0 -81
- package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
- package/templates/apps/mcp/src/tools/search_content.ts +0 -63
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
- package/templates/apps/mcp/src/workspace-server.ts +0 -224
- package/templates/database/CHANGELOG.md +0 -981
- package/templates/database/LICENSE +0 -202
- package/templates/database/NOTICE +0 -2
- package/templates/database/README.md +0 -243
- package/templates/database/__tests__/agents.db.test.ts +0 -320
- package/templates/database/__tests__/appointment.db.test.ts +0 -106
- package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
- package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
- package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
- package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
- package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
- package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
- package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
- package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
- package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
- package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
- package/templates/database/__tests__/flows-presets.test.ts +0 -173
- package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
- package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
- package/templates/database/__tests__/member-area.db.test.ts +0 -257
- package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
- package/templates/database/__tests__/member-contract.db.test.ts +0 -413
- package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
- package/templates/database/__tests__/offerings-migration.test.ts +0 -197
- package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
- package/templates/database/__tests__/offerings.db.test.ts +0 -303
- package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
- package/templates/database/__tests__/person-contact.db.test.ts +0 -563
- package/templates/database/__tests__/person-notes.db.test.ts +0 -249
- package/templates/database/__tests__/person.db.test.ts +0 -586
- package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
- package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
- package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
- package/templates/database/__tests__/seed.test.ts +0 -272
- package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
- package/templates/database/__tests__/tenancy.test.ts +0 -141
- package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
- package/templates/database/__tests__/user-cascade.test.ts +0 -140
- package/templates/database/_gitignore +0 -8
- package/templates/database/auth/.gitkeep +0 -0
- package/templates/database/auth/schema.prisma +0 -641
- package/templates/database/config/.gitkeep +0 -0
- package/templates/database/config/schema.prisma +0 -441
- package/templates/database/content/.gitkeep +0 -0
- package/templates/database/content/schema.prisma +0 -339
- package/templates/database/eslint.config.mjs +0 -69
- package/templates/database/flows/listing-diagnostic.ts +0 -182
- package/templates/database/flows/presets.ts +0 -315
- package/templates/database/inbox/.gitkeep +0 -0
- package/templates/database/inbox/README.md +0 -3
- package/templates/database/inbox/__tests__/schema.test.ts +0 -44
- package/templates/database/inbox/schema.prisma +0 -1447
- package/templates/database/jest.config.cjs +0 -36
- package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
- package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
- package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
- package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
- package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
- package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
- package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
- package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
- package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
- package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
- package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
- package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
- package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
- package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
- package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
- package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
- package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
- package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
- package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
- package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
- package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
- package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
- package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
- package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
- package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
- package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
- package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
- package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
- package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
- package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
- package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
- package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
- package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
- package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
- package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
- package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
- package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
- package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
- package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
- package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
- package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
- package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
- package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
- package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
- package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
- package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
- package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
- package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
- package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
- package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
- package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
- package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
- package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
- package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
- package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
- package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
- package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
- package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
- package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
- package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
- package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
- package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
- package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
- package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
- package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
- package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
- package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
- package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
- package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
- package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
- package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
- package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
- package/templates/database/migrations/migration_lock.toml +0 -3
- package/templates/database/ops/.gitkeep +0 -0
- package/templates/database/ops/schema.prisma +0 -43
- package/templates/database/package.json +0 -89
- package/templates/database/schema.prisma +0 -71
- package/templates/database/scripts/db-generate-locked.sh +0 -80
- package/templates/database/scripts/person-backfill.sql +0 -132
- package/templates/database/tenancy.ts +0 -183
- package/templates/database/tsconfig.build.json +0 -16
- package/templates/database/tsconfig.flows.json +0 -15
- package/templates/database/tsconfig.json +0 -16
- package/templates/database/tsconfig.tenancy.json +0 -14
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
-- The verified owner link on `project_listings` (#5295).
|
|
2
|
-
--
|
|
3
|
-
-- A listing carried `founder_email` and `lead_id` and no user link, so there
|
|
4
|
-
-- was no query for "the listings belonging to this signed-in person". The only
|
|
5
|
-
-- join available was a session's email against `founder_email` — and
|
|
6
|
-
-- `founder_email` is an UNVERIFIED string typed into an anonymous form, so that
|
|
7
|
-
-- join hands a stranger someone else's submission the first time two people
|
|
8
|
-
-- type the same address. These two columns are the ownership claim instead.
|
|
9
|
-
--
|
|
10
|
-
-- Plain scalars, no foreign key into `users`: ADR 0009 invariant #1 forbids a
|
|
11
|
-
-- relation across the namespace boundary, and `leads.promoted_user_id` /
|
|
12
|
-
-- `promoted_at` (20260714000000_add_lead_promotion_fields) are the same shape
|
|
13
|
-
-- for the same reason. The join is stable-id matching in the service layer.
|
|
14
|
-
--
|
|
15
|
-
-- `apps/api/src/services/listing-promotion.ts` is the sole writer, and it sets
|
|
16
|
-
-- the pair only when all three of these hold:
|
|
17
|
-
-- 1. the reconciling user's OWN email is verified (`users.email_verified`) —
|
|
18
|
-
-- never a claimed or session-asserted address;
|
|
19
|
-
-- 2. that verified address matches the row's `founder_email`;
|
|
20
|
-
-- 3. the row's `site_id` is one of that user's own tenant workspaces.
|
|
21
|
-
-- Any one failing writes nothing.
|
|
22
|
-
--
|
|
23
|
-
-- NO BACKFILL, deliberately and permanently. Every existing row predates
|
|
24
|
-
-- verification, so deriving `owner_user_id` from `founder_email` here would
|
|
25
|
-
-- assert exactly the link nobody proved — the bug the column exists to remove.
|
|
26
|
-
-- Existing rows stay null, and a listing submitted by someone who never signs
|
|
27
|
-
-- in stays null for the life of the row: that is a legitimate resting state,
|
|
28
|
-
-- not a backlog to clean up.
|
|
29
|
-
--
|
|
30
|
-
-- The index backs the self-scoped read's whole WHERE clause
|
|
31
|
-
-- (`GET /v1/project-listings/me` — `owner_user_id = $1`, and nothing else: the
|
|
32
|
-
-- owner link IS the scope, so no site term joins it). Single-column by design —
|
|
33
|
-
-- the promotion match (`founder_email` + `site_id` + a null owner) is already
|
|
34
|
-
-- served by the existing (site_id, founder_email) index.
|
|
35
|
-
--
|
|
36
|
-
-- Forward-additive only: both columns are nullable with no default, so every
|
|
37
|
-
-- existing read and write is unaffected.
|
|
38
|
-
--
|
|
39
|
-
-- Rollback:
|
|
40
|
-
-- DROP INDEX "project_listings_owner_user_id_idx";
|
|
41
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "owner_linked_at";
|
|
42
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "owner_user_id";
|
|
43
|
-
|
|
44
|
-
-- AlterTable
|
|
45
|
-
ALTER TABLE "project_listings" ADD COLUMN "owner_user_id" TEXT,
|
|
46
|
-
ADD COLUMN "owner_linked_at" TIMESTAMP(3);
|
|
47
|
-
|
|
48
|
-
-- CreateIndex
|
|
49
|
-
CREATE INDEX "project_listings_owner_user_id_idx" ON "project_listings"("owner_user_id");
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
-- The founder's structured identity and PROVEN email address on
|
|
2
|
-
-- `project_listings` (#5407).
|
|
3
|
-
--
|
|
4
|
-
-- Step one of the application collected ONE `founder_name` line and an email.
|
|
5
|
-
-- samhenry spec 316 D1 asks for first name, last name, email and phone, with
|
|
6
|
-
-- the two name parts stored separately, and 316 D6b asks that an application
|
|
7
|
-
-- whose emailed resume link was opened be marked verified so the operator can
|
|
8
|
-
-- filter on it at review.
|
|
9
|
-
--
|
|
10
|
-
-- FIVE NULLABLE COLUMNS, NO BACKFILL, NO CHANGE TO ANY EXISTING ONE.
|
|
11
|
-
--
|
|
12
|
-
-- `founder_first_name` / `founder_last_name` sit BESIDE `founder_name`, not
|
|
13
|
-
-- instead of it — the #5279 precedent that put six address parts beside the
|
|
14
|
-
-- single-line `address`. `founder_name` stays NOT NULL and stays the DISPLAY
|
|
15
|
-
-- string every existing reader already reads (the submit-time slug fallback,
|
|
16
|
-
-- the approve/reject email's greeting, the Slack review card's Founder row,
|
|
17
|
-
-- the build issue, the `routeLead` identity); where the parts are written the
|
|
18
|
-
-- server COMPOSES it from them, and where they are not it is the line the
|
|
19
|
-
-- founder typed, verbatim.
|
|
20
|
-
--
|
|
21
|
-
-- Composition runs ONE WAY ONLY, and that is why nothing here backfills.
|
|
22
|
-
-- "First" + "Last" composes into a display line deterministically; a display
|
|
23
|
-
-- line does not decompose into parts. Splitting on the last space mangles
|
|
24
|
-
-- "van der Berg", "Maria del Carmen" and every mononym, and a wrong split is
|
|
25
|
-
-- silent — it would put an invented surname on the row the approve email
|
|
26
|
-
-- greets and the operator reviews, with nothing to mark it as invented. A
|
|
27
|
-
-- null part is honest; a guessed one is not. Every existing row therefore
|
|
28
|
-
-- keeps `founder_name` byte-for-byte and keeps both parts NULL for the life
|
|
29
|
-
-- of the row.
|
|
30
|
-
--
|
|
31
|
-
-- `founder_phone` is the contact detail spec 316 D1 adds. Nullable at rest
|
|
32
|
-
-- for the #5036 D1 reason — every field the submit payload requires must be
|
|
33
|
-
-- storable half-filled — and nullable permanently besides: a row written
|
|
34
|
-
-- before #5407 has none, and a site may declare the question optional through
|
|
35
|
-
-- its own listing config. It NEVER rides the public read; the public row
|
|
36
|
-
-- shape omits it beside `founder_email`.
|
|
37
|
-
--
|
|
38
|
-
-- `email_verify_nonce_hash` and `email_verified_at` are the verification pair,
|
|
39
|
-
-- and the first is what makes the second mean what it says.
|
|
40
|
-
--
|
|
41
|
-
-- The obvious design is to stamp verification when the emailed resume link is
|
|
42
|
-
-- opened, keyed on the resume token that link carries. That design does not
|
|
43
|
-
-- work, and the reason is worth stating here because the column name does not
|
|
44
|
-
-- carry it: `start` returns the resume token to WHOEVER POSTED THE FORM, in
|
|
45
|
-
-- its own 201 body. The emailed link is a second copy of a credential the
|
|
46
|
-
-- applicant already holds — so two HTTP calls (open a draft under a
|
|
47
|
-
-- stranger's address, take the token out of the response, present it back)
|
|
48
|
-
-- would forge the stamp with no mailbox involved. Caught by this PR's
|
|
49
|
-
-- security review before it shipped.
|
|
50
|
-
--
|
|
51
|
-
-- So verification requires a SECOND credential the applicant never receives
|
|
52
|
-
-- any other way. `email_verify_nonce_hash` holds the sha-256 digest of a
|
|
53
|
-
-- 256-bit nonce minted at `start`, handed to nothing except the resume-email
|
|
54
|
-
-- builder (apps/api/src/services/project-listing-resume-email.ts), and
|
|
55
|
-
-- present in no response body and no log line. It reaches exactly one place:
|
|
56
|
-
-- the `?verify=` parameter of the link inside the email. Holding it means
|
|
57
|
-
-- having read mail sent to `founder_email`, which is what the stamp claims.
|
|
58
|
-
--
|
|
59
|
-
-- `email_verified_at` is therefore genuine evidence of address control, and
|
|
60
|
-
-- is still WRITE-ONCE: the verify call sets it only where it is still NULL,
|
|
61
|
-
-- by compare-and-swap, so a founder who opens the link five times is stamped
|
|
62
|
-
-- with the first opening and two concurrent openings produce one stamp
|
|
63
|
-
-- between them.
|
|
64
|
-
--
|
|
65
|
-
-- WHAT IT STILL DOES NOT SAY is who the founder is. `owner_user_id`
|
|
66
|
-
-- (20260912120000_listing_owner_link) is the identity claim and needs a
|
|
67
|
-
-- signed-in user whose own address the auth system verified. A row can carry
|
|
68
|
-
-- either, both, or neither.
|
|
69
|
-
--
|
|
70
|
-
-- Neither is a backfill target. Stamping an existing row would assert exactly
|
|
71
|
-
-- the event nobody recorded. NULL means "not verified", never "verification
|
|
72
|
-
-- failed" — and it is also what a site that has not switched the resume email
|
|
73
|
-
-- on will read forever, because the nonce is minted there and simply never
|
|
74
|
-
-- delivered. That is the correct outcome, not a gap.
|
|
75
|
-
--
|
|
76
|
-
-- `email_verify_nonce_hash` is UNIQUE, mirroring `resume_token_hash`: two
|
|
77
|
-
-- rows can never share a nonce, and the digest lookup is indexed. It is
|
|
78
|
-
-- cleared at `submit` beside the resume-token digest, so a credential that
|
|
79
|
-
-- leaks after the draft stops being a draft is inert twice over. It has NO
|
|
80
|
-
-- EXPIRY otherwise, by design and for the reason the service records: the
|
|
81
|
-
-- same message carries the resume token, so a TTL on the nonce alone would
|
|
82
|
-
-- bound nothing.
|
|
83
|
-
--
|
|
84
|
-
-- OPERATIONAL NOTE on the index. `CREATE UNIQUE INDEX` below is not
|
|
85
|
-
-- `CONCURRENTLY`, so it takes a SHARE lock and blocks writes to
|
|
86
|
-
-- `project_listings` while it builds. Every existing row is NULL there and
|
|
87
|
-
-- Postgres treats NULLs as distinct in a unique index (no NULLS NOT
|
|
88
|
-
-- DISTINCT), so it cannot fail on existing data and builds fast — and the
|
|
89
|
-
-- same property is why `submit` setting many rows back to NULL never
|
|
90
|
-
-- collides. Stated so whoever runs this against a large table knows it is
|
|
91
|
-
-- write-blocking DDL; it matches the `resume_token_hash` precedent.
|
|
92
|
-
--
|
|
93
|
-
-- Distinct from `owner_user_id` (20260912120000_listing_owner_link), which
|
|
94
|
-
-- needs a SIGNED-IN user whose own address the auth system verified. This
|
|
95
|
-
-- column needs no account at all: it records that a capability sent to
|
|
96
|
-
-- `founder_email` came back. A row can carry either, both, or neither.
|
|
97
|
-
--
|
|
98
|
-
-- NO INDEX on the other four. The verify write is keyed by the row's primary
|
|
99
|
-
-- key plus two digests, both already UNIQUE, and the operator filters
|
|
100
|
-
-- verified applications inside a site's already-indexed page of listings
|
|
101
|
-
-- (`project_listings_site_id_status_idx`) rather than by scanning on
|
|
102
|
-
-- `email_verified_at`.
|
|
103
|
-
--
|
|
104
|
-
-- Forward-additive only: all five columns are nullable with no default, so
|
|
105
|
-
-- every existing read and write is unaffected.
|
|
106
|
-
--
|
|
107
|
-
-- Rollback:
|
|
108
|
-
-- DROP INDEX "project_listings_email_verify_nonce_hash_key";
|
|
109
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "email_verified_at";
|
|
110
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "email_verify_nonce_hash";
|
|
111
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "founder_phone";
|
|
112
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "founder_last_name";
|
|
113
|
-
-- ALTER TABLE "project_listings" DROP COLUMN "founder_first_name";
|
|
114
|
-
|
|
115
|
-
-- AlterTable
|
|
116
|
-
ALTER TABLE "project_listings" ADD COLUMN "founder_first_name" TEXT,
|
|
117
|
-
ADD COLUMN "founder_last_name" TEXT,
|
|
118
|
-
ADD COLUMN "founder_phone" TEXT,
|
|
119
|
-
ADD COLUMN "email_verify_nonce_hash" TEXT,
|
|
120
|
-
ADD COLUMN "email_verified_at" TIMESTAMP(3);
|
|
121
|
-
|
|
122
|
-
-- CreateIndex
|
|
123
|
-
CREATE UNIQUE INDEX "project_listings_email_verify_nonce_hash_key" ON "project_listings"("email_verify_nonce_hash");
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
-- The founder's "how are you solving it?" answer on `project_listings` (#5096).
|
|
2
|
-
--
|
|
3
|
-
-- `problem` (step five) has had a column since the surface shipped; its
|
|
4
|
-
-- narrative other half has not, so samhenry PR #324's step six had nowhere to
|
|
5
|
-
-- write.
|
|
6
|
-
--
|
|
7
|
-
-- ONE NULLABLE COLUMN, NO DEFAULT, NO BACKFILL, NO CHANGE TO ANY EXISTING ONE.
|
|
8
|
-
-- Additive and opt-in: the field is absent from the platform's default
|
|
9
|
-
-- `collectedFields` mask (#5096 DD1), so no existing site can have it written
|
|
10
|
-
-- until that site names it. Every row written before this migration keeps a
|
|
11
|
-
-- NULL here, which the row schema already allows for every application field
|
|
12
|
-
-- (#5036 D1 — a half-filled draft is a legitimate row).
|
|
13
|
-
--
|
|
14
|
-
-- Rollback: ALTER TABLE "project_listings" DROP COLUMN "solution";
|
|
15
|
-
ALTER TABLE "project_listings" ADD COLUMN "solution" TEXT;
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
-- #5800 — the Artifact content store: roadmap D1 (generalize `Artifact`) and
|
|
2
|
-
-- D7 (`Asset`, workspace-scoped).
|
|
3
|
-
--
|
|
4
|
-
-- D1's one sentence: THE SESSION BECOMES PROVENANCE, THE WORKSPACE OWNS THE
|
|
5
|
-
-- ARTIFACT. Today `artifacts.session_id` is NOT NULL behind an ON DELETE
|
|
6
|
-
-- CASCADE, so deleting a conversation deletes the pages it produced. After this
|
|
7
|
-
-- migration the column is nullable behind ON DELETE SET NULL: the session is
|
|
8
|
-
-- where the artifact came from, not what keeps it alive.
|
|
9
|
-
--
|
|
10
|
-
-- The relaxation is bracketed by ZERO-ROW ASSERTIONS. It applies to an empty
|
|
11
|
-
-- database and to a populated one, and each assertion names a specific way the
|
|
12
|
-
-- relaxation could have lost data. A failed assertion aborts the transaction
|
|
13
|
-
-- with a message that says which rows to look at — the migration never proceeds
|
|
14
|
-
-- on a silent surprise, and it never backfills its way past one.
|
|
15
|
-
--
|
|
16
|
-
-- The rest is additive: four nullable-or-defaulted columns, two indexes, and a
|
|
17
|
-
-- new `assets` table. `content_type` is BACKFILLED from the legacy `type`
|
|
18
|
-
-- column rather than replacing it, because
|
|
19
|
-
-- apps/api/src/routes/workspaces/sessions.ts (a hard-floor surface) reads
|
|
20
|
-
-- `type` and must keep working unchanged; the two agree row-for-row when this
|
|
21
|
-
-- migration commits, and retiring `type` belongs to the card that moves that
|
|
22
|
-
-- route.
|
|
23
|
-
--
|
|
24
|
-
-- Rollback: drop the two indexes and the four columns, drop "assets", restore
|
|
25
|
-
-- the FK as NOT NULL + ON DELETE CASCADE. That restore is only safe while no
|
|
26
|
-
-- artifact has yet outlived its session.
|
|
27
|
-
|
|
28
|
-
-- ── PRE-ASSERTIONS (zero rows, or this migration does not run) ──────────────
|
|
29
|
-
DO $$
|
|
30
|
-
DECLARE
|
|
31
|
-
already_null bigint;
|
|
32
|
-
orphaned bigint;
|
|
33
|
-
BEGIN
|
|
34
|
-
-- "session_id" is NOT NULL today. A non-zero count here means the column is
|
|
35
|
-
-- not the shape this migration was written against — stop rather than guess.
|
|
36
|
-
SELECT count(*) INTO already_null FROM "artifacts" WHERE "session_id" IS NULL;
|
|
37
|
-
IF already_null <> 0 THEN
|
|
38
|
-
RAISE EXCEPTION
|
|
39
|
-
'#5800 pre-assertion: % artifact row(s) already carry a NULL session_id before the FK was relaxed; the column was expected NOT NULL',
|
|
40
|
-
already_null;
|
|
41
|
-
END IF;
|
|
42
|
-
|
|
43
|
-
-- The outgoing FK is what guarantees this is zero. Proving it BEFORE the
|
|
44
|
-
-- swap is what lets the post-assertion below attribute any orphan to the
|
|
45
|
-
-- swap itself.
|
|
46
|
-
SELECT count(*) INTO orphaned
|
|
47
|
-
FROM "artifacts" a
|
|
48
|
-
LEFT JOIN "agent_sessions" s ON s."id" = a."session_id"
|
|
49
|
-
WHERE s."id" IS NULL;
|
|
50
|
-
IF orphaned <> 0 THEN
|
|
51
|
-
RAISE EXCEPTION
|
|
52
|
-
'#5800 pre-assertion: % artifact row(s) point at an agent_sessions row that does not exist',
|
|
53
|
-
orphaned;
|
|
54
|
-
END IF;
|
|
55
|
-
END $$;
|
|
56
|
-
|
|
57
|
-
-- The census the post-assertion compares against. ON COMMIT DROP: `prisma
|
|
58
|
-
-- migrate` runs each migration in one transaction, so this disappears with it.
|
|
59
|
-
CREATE TEMP TABLE "_5800_artifact_census" ON COMMIT DROP AS
|
|
60
|
-
SELECT count(*) AS n FROM "artifacts";
|
|
61
|
-
|
|
62
|
-
-- ── The FK relaxation (D1) ─────────────────────────────────────────────────
|
|
63
|
-
-- DropForeignKey
|
|
64
|
-
ALTER TABLE "artifacts" DROP CONSTRAINT "artifacts_session_id_fkey";
|
|
65
|
-
|
|
66
|
-
-- AlterTable
|
|
67
|
-
ALTER TABLE "artifacts" ADD COLUMN "content_type" TEXT NOT NULL DEFAULT 'text/document',
|
|
68
|
-
ADD COLUMN "locale" TEXT NOT NULL DEFAULT 'en',
|
|
69
|
-
ADD COLUMN "published_version_id" TEXT,
|
|
70
|
-
ADD COLUMN "slug" TEXT,
|
|
71
|
-
ALTER COLUMN "session_id" DROP NOT NULL;
|
|
72
|
-
|
|
73
|
-
-- AddForeignKey
|
|
74
|
-
ALTER TABLE "artifacts" ADD CONSTRAINT "artifacts_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "agent_sessions"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
75
|
-
|
|
76
|
-
-- Backfill: the new discriminator starts life agreeing with the legacy one, so
|
|
77
|
-
-- a pre-existing chat artifact reads identically through either column.
|
|
78
|
-
UPDATE "artifacts" SET "content_type" = "type";
|
|
79
|
-
|
|
80
|
-
-- ── POST-ASSERTIONS (zero rows lost, zero rows nulled, zero drift) ─────────
|
|
81
|
-
DO $$
|
|
82
|
-
DECLARE
|
|
83
|
-
before_n bigint;
|
|
84
|
-
after_n bigint;
|
|
85
|
-
nulled bigint;
|
|
86
|
-
drift bigint;
|
|
87
|
-
BEGIN
|
|
88
|
-
SELECT n INTO before_n FROM "_5800_artifact_census";
|
|
89
|
-
SELECT count(*) INTO after_n FROM "artifacts";
|
|
90
|
-
IF before_n <> after_n THEN
|
|
91
|
-
RAISE EXCEPTION
|
|
92
|
-
'#5800 post-assertion: artifact count changed across the FK relaxation (% -> %)',
|
|
93
|
-
before_n, after_n;
|
|
94
|
-
END IF;
|
|
95
|
-
|
|
96
|
-
-- Relaxing the constraint must not itself null anyone's provenance. Rows
|
|
97
|
-
-- become NULL later, one at a time, as sessions are deleted.
|
|
98
|
-
SELECT count(*) INTO nulled FROM "artifacts" WHERE "session_id" IS NULL;
|
|
99
|
-
IF nulled <> 0 THEN
|
|
100
|
-
RAISE EXCEPTION
|
|
101
|
-
'#5800 post-assertion: relaxing the FK left % artifact row(s) with a NULL session_id',
|
|
102
|
-
nulled;
|
|
103
|
-
END IF;
|
|
104
|
-
|
|
105
|
-
SELECT count(*) INTO drift
|
|
106
|
-
FROM "artifacts" WHERE "content_type" IS DISTINCT FROM "type";
|
|
107
|
-
IF drift <> 0 THEN
|
|
108
|
-
RAISE EXCEPTION
|
|
109
|
-
'#5800 post-assertion: % artifact row(s) disagree between content_type and the legacy type column',
|
|
110
|
-
drift;
|
|
111
|
-
END IF;
|
|
112
|
-
END $$;
|
|
113
|
-
|
|
114
|
-
-- ── Content-store identity + the list index (D1) ───────────────────────────
|
|
115
|
-
-- CreateIndex
|
|
116
|
-
CREATE INDEX "artifacts_workspace_id_content_type_updated_at_idx" ON "artifacts"("workspace_id", "content_type", "updated_at");
|
|
117
|
-
|
|
118
|
-
-- CreateIndex
|
|
119
|
-
-- `slug` is NULL until publish and NULLs never collide in a Postgres unique
|
|
120
|
-
-- index, so a workspace may hold any number of unpublished drafts while
|
|
121
|
-
-- exactly one artifact may claim a given published path.
|
|
122
|
-
CREATE UNIQUE INDEX "artifacts_workspace_id_content_type_locale_slug_key" ON "artifacts"("workspace_id", "content_type", "locale", "slug");
|
|
123
|
-
|
|
124
|
-
-- ── Asset (D7) ─────────────────────────────────────────────────────────────
|
|
125
|
-
-- Shaped after `deliverable_assets` (20260811050000_add_deliverable_models):
|
|
126
|
-
-- the bytes live in the row. Same CreateTable + CreateIndex + ADR-0031 rule-3
|
|
127
|
-
-- id-format completion in ONE migration as
|
|
128
|
-
-- 20260911180000_consent_grants, since the table is new and needs no retrofit.
|
|
129
|
-
-- CreateTable
|
|
130
|
-
CREATE TABLE "assets" (
|
|
131
|
-
"id" TEXT NOT NULL DEFAULT ('asset_'::text || (uuidv7())::text),
|
|
132
|
-
"workspace_id" TEXT NOT NULL,
|
|
133
|
-
"key" TEXT NOT NULL,
|
|
134
|
-
"filename" TEXT NOT NULL,
|
|
135
|
-
"content_type" TEXT NOT NULL,
|
|
136
|
-
"bytes" BYTEA NOT NULL,
|
|
137
|
-
"size" INTEGER NOT NULL,
|
|
138
|
-
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
139
|
-
|
|
140
|
-
CONSTRAINT "assets_pkey" PRIMARY KEY ("id")
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
-- CreateIndex
|
|
144
|
-
CREATE INDEX "assets_workspace_id_idx" ON "assets"("workspace_id");
|
|
145
|
-
|
|
146
|
-
-- CreateIndex
|
|
147
|
-
CREATE UNIQUE INDEX "assets_workspace_id_key_key" ON "assets"("workspace_id", "key");
|
|
148
|
-
|
|
149
|
-
-- ADR-0031 rule 3 — assets: asset_ (registered in
|
|
150
|
-
-- packages/ids/src/registry.ts ENTITY_PREFIX.asset; this migration's path is
|
|
151
|
-
-- added to migration-sync.test.ts's PK_CHECK_MIGRATIONS). workspace_id is a
|
|
152
|
-
-- relation-free scope column (ADR-0009 invariant 1) and gets the same CHECK
|
|
153
|
-
-- every other content-namespace table's does.
|
|
154
|
-
ALTER TABLE "assets" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
155
|
-
ALTER TABLE "assets" ALTER COLUMN "id" SET DEFAULT ('asset_'::text || (uuidv7())::text);
|
|
156
|
-
ALTER TABLE "assets" ADD CONSTRAINT "assets_id_format" CHECK ("id" ~ '^asset_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
157
|
-
ALTER TABLE "assets" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
158
|
-
ALTER TABLE "assets" ADD CONSTRAINT "assets_workspace_id_format" CHECK ("workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
-- #5970 — request-and-confirm: the callback row gains a confirm/pay lifecycle
|
|
2
|
-
-- (D-67 / SUB-100, spec docs/specs/5970-request-and-confirm-spec.md § 4.3).
|
|
3
|
-
--
|
|
4
|
-
-- Eleven nullable columns and two indexes on "callbacks". Every column is
|
|
5
|
-
-- NULL-able with no default, so on Postgres this ALTER TABLE is metadata-only:
|
|
6
|
-
-- no table rewrite, no backfill, no lock held for the length of a scan.
|
|
7
|
-
--
|
|
8
|
-
-- Nothing here relaxes a constraint and nothing here backfills, so — unlike
|
|
9
|
-
-- 20260916120000_artifact_content_store — this migration carries no zero-row
|
|
10
|
-
-- pre-assertion block: there is no way for it to lose a row.
|
|
11
|
-
--
|
|
12
|
-
-- The two indexes are the webhook stamp's `where` (spec § D8). Without them
|
|
13
|
-
-- every checkout.session.completed carrying a payment_link would sequential-
|
|
14
|
-
-- scan "callbacks" on a hot path. "stripe_checkout_session_id" carries no
|
|
15
|
-
-- index deliberately: nothing queries by it — it is a support-lookup column.
|
|
16
|
-
--
|
|
17
|
-
-- Rollback: drop the two indexes and the eleven columns. Safe unconditionally
|
|
18
|
-
-- while nothing but #5970's own code reads them.
|
|
19
|
-
|
|
20
|
-
ALTER TABLE "callbacks"
|
|
21
|
-
ADD COLUMN "confirm_token_hash" TEXT,
|
|
22
|
-
ADD COLUMN "confirm_token_expires_at" TIMESTAMP(3),
|
|
23
|
-
ADD COLUMN "confirmed_at" TIMESTAMP(3),
|
|
24
|
-
ADD COLUMN "confirmed_time" TEXT,
|
|
25
|
-
ADD COLUMN "buyer_email" TEXT,
|
|
26
|
-
ADD COLUMN "amount_minor" INTEGER,
|
|
27
|
-
ADD COLUMN "currency" TEXT,
|
|
28
|
-
ADD COLUMN "stripe_payment_link_id" TEXT,
|
|
29
|
-
ADD COLUMN "stripe_checkout_session_id" TEXT,
|
|
30
|
-
ADD COLUMN "stripe_invoice_id" TEXT,
|
|
31
|
-
ADD COLUMN "paid_at" TIMESTAMP(3);
|
|
32
|
-
|
|
33
|
-
-- The digest is unique: two rows sharing one is a mint bug, and the constraint
|
|
34
|
-
-- is what turns that bug into a write failure instead of a silent cross-row
|
|
35
|
-
-- credential.
|
|
36
|
-
CREATE UNIQUE INDEX "callbacks_confirm_token_hash_key" ON "callbacks"("confirm_token_hash");
|
|
37
|
-
|
|
38
|
-
CREATE INDEX "callbacks_stripe_payment_link_id_idx" ON "callbacks"("stripe_payment_link_id");
|
|
39
|
-
|
|
40
|
-
CREATE INDEX "callbacks_stripe_invoice_id_idx" ON "callbacks"("stripe_invoice_id");
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
-- #6085 — the Appointment model: a Cal.com booking normalized from the new
|
|
2
|
-
-- webhook receiver (brief H7, spec docs/specs/6085-appointments-from-cal-com-webhooks-spec.md § 4.3).
|
|
3
|
-
--
|
|
4
|
-
-- One new table, three indexes, in the house style of
|
|
5
|
-
-- 20260903010000_add_playbook_instance (CreateTable + CreateIndex immediately
|
|
6
|
-
-- followed by the ADR-0031 rule-3 id-format completion, in ONE migration
|
|
7
|
-
-- since the table is new and needs no retrofit).
|
|
8
|
-
--
|
|
9
|
-
-- The unique index over (site_id, provider, provider_booking_uid) is the
|
|
10
|
-
-- LOAD-BEARING line of this migration: it is the spec's own idempotency key
|
|
11
|
-
-- (§ D4) — a table without it makes "exactly one Appointment row per booking
|
|
12
|
-
-- uid" unenforceable, and § D7(a)'s guarded-write shape races on precisely
|
|
13
|
-
-- this index.
|
|
14
|
-
--
|
|
15
|
-
-- No backfill, no constraint relaxed, no existing table touched, so this
|
|
16
|
-
-- migration carries no zero-row pre-assertion block — there is no way for it
|
|
17
|
-
-- to lose a row.
|
|
18
|
-
--
|
|
19
|
-
-- Rollback: DROP TABLE "appointments". Safe unconditionally while nothing but
|
|
20
|
-
-- #6085's own code reads it.
|
|
21
|
-
|
|
22
|
-
-- CreateTable
|
|
23
|
-
CREATE TABLE "appointments" (
|
|
24
|
-
"id" TEXT NOT NULL DEFAULT ('appt_'::text || (uuidv7())::text),
|
|
25
|
-
"site_id" VARCHAR(200) NOT NULL,
|
|
26
|
-
"provider_booking_uid" VARCHAR(200) NOT NULL,
|
|
27
|
-
"provider" VARCHAR(32) NOT NULL DEFAULT 'cal',
|
|
28
|
-
"start_time" TIMESTAMP(3) NOT NULL,
|
|
29
|
-
"end_time" TIMESTAMP(3) NOT NULL,
|
|
30
|
-
"title" VARCHAR(300),
|
|
31
|
-
"attendee_name" VARCHAR(120) NOT NULL,
|
|
32
|
-
"attendee_email" VARCHAR(254) NOT NULL,
|
|
33
|
-
"attendee_time_zone" VARCHAR(64),
|
|
34
|
-
"status" VARCHAR(32) NOT NULL,
|
|
35
|
-
"paid" BOOLEAN NOT NULL DEFAULT false,
|
|
36
|
-
"payment_initiated_at" TIMESTAMP(3),
|
|
37
|
-
"no_show" BOOLEAN NOT NULL DEFAULT false,
|
|
38
|
-
"cancelled_at" TIMESTAMP(3),
|
|
39
|
-
"lifecycle_event_at" TIMESTAMP(3) NOT NULL,
|
|
40
|
-
"payment_event_at" TIMESTAMP(3),
|
|
41
|
-
"no_show_event_at" TIMESTAMP(3),
|
|
42
|
-
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
43
|
-
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
44
|
-
|
|
45
|
-
CONSTRAINT "appointments_pkey" PRIMARY KEY ("id")
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
-- CreateIndex
|
|
49
|
-
-- The idempotency key (§ D4) — see the file header. `provider` is included
|
|
50
|
-
-- per § 9 SEC-10 so a second scheduling provider's uid space cannot collide
|
|
51
|
-
-- with this one's (#4288).
|
|
52
|
-
CREATE UNIQUE INDEX "appointments_site_id_provider_provider_booking_uid_key" ON "appointments"("site_id", "provider", "provider_booking_uid");
|
|
53
|
-
|
|
54
|
-
-- CreateIndex
|
|
55
|
-
-- The read's `where` + `order by` (§ D6). Without it every appointments page
|
|
56
|
-
-- load sequential-scans "appointments".
|
|
57
|
-
CREATE INDEX "appointments_site_id_start_time_idx" ON "appointments"("site_id", "start_time");
|
|
58
|
-
|
|
59
|
-
-- CreateIndex
|
|
60
|
-
CREATE INDEX "appointments_created_at_idx" ON "appointments"("created_at");
|
|
61
|
-
|
|
62
|
-
-- ADR-0031 rule 3 — appointments: appt_ (registered in
|
|
63
|
-
-- packages/ids/src/registry.ts ENTITY_PREFIX.appointment; this migration's
|
|
64
|
-
-- path is added to migration-sync.test.ts's PK_CHECK_MIGRATIONS).
|
|
65
|
-
ALTER TABLE "appointments" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
66
|
-
ALTER TABLE "appointments" ALTER COLUMN "id" SET DEFAULT ('appt_'::text || (uuidv7())::text);
|
|
67
|
-
ALTER TABLE "appointments" ADD CONSTRAINT "appointments_id_format" CHECK ("id" ~ '^appt_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
-- #6092 — S4's data tier: an asset carries title, description and tags.
|
|
2
|
-
--
|
|
3
|
-
-- Today `assets` holds bytes and a filename and nothing the owner wrote
|
|
4
|
-
-- (decisions.html D10: "an asset has a filename and dimensions only"). The
|
|
5
|
-
-- lightbox edits three things in place — a title, a description and a set of
|
|
6
|
-
-- tags — so the table gains exactly those three columns.
|
|
7
|
-
--
|
|
8
|
-
-- STRICTLY ADDITIVE. Nothing is dropped, renamed, relaxed or backfilled. The
|
|
9
|
-
-- `(workspace_id, key)` identity, the `assets_id_format` and
|
|
10
|
-
-- `assets_workspace_id_format` CHECKs and the `asset_`+UUIDv7 default are all
|
|
11
|
-
-- untouched, so a pre-existing row stays valid and an INSERT written before
|
|
12
|
-
-- this migration keeps working unchanged.
|
|
13
|
-
--
|
|
14
|
-
-- `tags` is TEXT[] with an empty-array default rather than a nullable column:
|
|
15
|
-
-- an untagged asset is an empty set, not an unknown one, and a NULL would give
|
|
16
|
-
-- two spellings of the same state. It carries tag SLUGS, never the human
|
|
17
|
-
-- labels, and it is deliberately UNCONSTRAINED — two vocabularies ride it (the
|
|
18
|
-
-- twelve asset tags and D9's four document tags, since a document is a row in
|
|
19
|
-
-- this same store), and the "fixed set" of D10 is a surface affordance. A tag
|
|
20
|
-
-- whose slug a surface cannot resolve is that surface's problem to render, not
|
|
21
|
-
-- a reason to reject an upload.
|
|
22
|
-
--
|
|
23
|
-
-- `title` and `description` are nullable with no default: NULL means the owner
|
|
24
|
-
-- has not written one, which is distinct from an empty string meaning they
|
|
25
|
-
-- cleared it. `title` is NOT backfilled from `filename` — they are different
|
|
26
|
-
-- facts and the lightbox shows both.
|
|
27
|
-
--
|
|
28
|
-
-- Rollback: ALTER TABLE "assets" DROP COLUMN "tags", DROP COLUMN
|
|
29
|
-
-- "description", DROP COLUMN "title". Safe unconditionally; the columns carry
|
|
30
|
-
-- no constraint and nothing references them.
|
|
31
|
-
|
|
32
|
-
-- The census the post-assertion compares against. ON COMMIT DROP: `prisma
|
|
33
|
-
-- migrate` runs each migration in one transaction, so this disappears with it.
|
|
34
|
-
CREATE TEMP TABLE "_6092_asset_census" ON COMMIT DROP AS
|
|
35
|
-
SELECT count(*) AS n FROM "assets";
|
|
36
|
-
|
|
37
|
-
-- AlterTable
|
|
38
|
-
ALTER TABLE "assets" ADD COLUMN "title" TEXT,
|
|
39
|
-
ADD COLUMN "description" TEXT,
|
|
40
|
-
ADD COLUMN "tags" TEXT[] DEFAULT ARRAY[]::TEXT[];
|
|
41
|
-
|
|
42
|
-
-- ── POST-ASSERTIONS (no row lost; every pre-existing row reads back empty) ──
|
|
43
|
-
-- This is AC-1's second half, asserted against the rows the target database
|
|
44
|
-
-- actually holds rather than against a fixture's.
|
|
45
|
-
DO $$
|
|
46
|
-
DECLARE
|
|
47
|
-
before_n bigint;
|
|
48
|
-
after_n bigint;
|
|
49
|
-
written bigint;
|
|
50
|
-
BEGIN
|
|
51
|
-
SELECT n INTO before_n FROM "_6092_asset_census";
|
|
52
|
-
SELECT count(*) INTO after_n FROM "assets";
|
|
53
|
-
IF before_n <> after_n THEN
|
|
54
|
-
RAISE EXCEPTION
|
|
55
|
-
'#6092 post-assertion: asset count changed across a purely additive migration (% -> %)',
|
|
56
|
-
before_n, after_n;
|
|
57
|
-
END IF;
|
|
58
|
-
|
|
59
|
-
-- Adding the columns must not itself author metadata for anyone. Rows gain a
|
|
60
|
-
-- title, a description or a tag later, one at a time, from the lightbox.
|
|
61
|
-
SELECT count(*) INTO written FROM "assets"
|
|
62
|
-
WHERE "title" IS NOT NULL
|
|
63
|
-
OR "description" IS NOT NULL
|
|
64
|
-
OR "tags" IS DISTINCT FROM ARRAY[]::TEXT[];
|
|
65
|
-
IF written <> 0 THEN
|
|
66
|
-
RAISE EXCEPTION
|
|
67
|
-
'#6092 post-assertion: % pre-existing asset row(s) came out of the migration with metadata already set',
|
|
68
|
-
written;
|
|
69
|
-
END IF;
|
|
70
|
-
END $$;
|