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,132 +0,0 @@
|
|
|
1
|
-
-- #852 — the Person backfill (spec
|
|
2
|
-
-- docs/specs/852-person-the-per-workspace-client-spec.md D2, D4).
|
|
3
|
-
--
|
|
4
|
-
-- Fills "people" from the rows the hub already holds and stamps
|
|
5
|
-
-- leads.person_id and appointments.person_id, so the People list is not
|
|
6
|
-
-- empty on the day it ships. Set-based and idempotent: every insert is
|
|
7
|
-
-- ON CONFLICT DO NOTHING and every update is guarded by IS NULL, so running
|
|
8
|
-
-- this text twice changes nothing the first run wrote.
|
|
9
|
-
--
|
|
10
|
-
-- THE SAME TEXT, byte for byte, is database/scripts/person-backfill.sql. The
|
|
11
|
-
-- previous deployment keeps writing leads and appointments without a
|
|
12
|
-
-- person_id between this migration and the cutover to the new code; run
|
|
13
|
-
-- that script ONCE against the hub database after the cutover to stamp them.
|
|
14
|
-
-- database/__tests__/person.db.test.ts asserts the two files are identical
|
|
15
|
-
-- and that a second run changes no row.
|
|
16
|
-
--
|
|
17
|
-
-- Normalization — the SQL twin of apps/api/src/services/person.ts's
|
|
18
|
-
-- normalizePersonEmail / isStorablePersonEmail:
|
|
19
|
-
-- N(x) = lower(btrim(x, E' \t\n\r\f\x0B') COLLATE "C")
|
|
20
|
-
-- (\x0B is vertical tab; an E-string has no \v escape — E'\v'
|
|
21
|
-
-- is the letter v, which would strip the v of every .dev)
|
|
22
|
-
-- VALID(e) = e ~ '^[!-?A-~]+@[!-?A-~]+$' AND length(e) <= 254
|
|
23
|
-
-- NAME(x) = C0/C1 controls and bidi controls removed, trimmed, cut to
|
|
24
|
-
-- 200 characters; empty → NULL
|
|
25
|
-
-- A row whose email is not VALID makes no Person and keeps person_id NULL.
|
|
26
|
-
--
|
|
27
|
-
-- Sources, in order: leads (oldest first), then completed hub FlowCheckouts
|
|
28
|
-
-- through their lead (the customer id, first writer wins), then appointments
|
|
29
|
-
-- by attendee email. Subscriber is NOT a source; FlowSession, ProjectListing
|
|
30
|
-
-- and DeliverableGrant reach a Person through their lead at read time.
|
|
31
|
-
-- The join to "users" reads the auth namespace inside this one-off
|
|
32
|
-
-- statement only; it adds no foreign key (ADR 0009 invariant 1).
|
|
33
|
-
--
|
|
34
|
-
-- Rollback: nothing to undo on its own — dropping 20261010120000_person's
|
|
35
|
-
-- table and columns removes everything this wrote.
|
|
36
|
-
|
|
37
|
-
-- 1. Leads, oldest first: one Person per (workspace, normalized email). The
|
|
38
|
-
-- name is the oldest lead's payload.name when it is a JSON string.
|
|
39
|
-
INSERT INTO "people" ("workspace_id", "email", "name", "created_at", "updated_at")
|
|
40
|
-
SELECT DISTINCT ON (l."workspace_id", lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"))
|
|
41
|
-
l."workspace_id",
|
|
42
|
-
lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"),
|
|
43
|
-
CASE WHEN jsonb_typeof(l."payload" -> 'name') = 'string'
|
|
44
|
-
THEN NULLIF(left(btrim(regexp_replace(l."payload" ->> 'name', '[\x01-\x1F\x7F-\x9F\u200E\u200F\u202A-\u202E\u2066-\u2069]', '', 'g')), 200), '')
|
|
45
|
-
END,
|
|
46
|
-
l."created_at",
|
|
47
|
-
now()
|
|
48
|
-
FROM "leads" l
|
|
49
|
-
WHERE lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C") ~ '^[!-?A-~]+@[!-?A-~]+$'
|
|
50
|
-
AND length(lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C")) <= 254
|
|
51
|
-
ORDER BY l."workspace_id", lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"), l."created_at" ASC, l."id" ASC
|
|
52
|
-
ON CONFLICT ("workspace_id", "email") DO NOTHING;
|
|
53
|
-
|
|
54
|
-
-- 2. Hub FlowCheckouts, through their lead (same workspace): the oldest
|
|
55
|
-
-- completed checkout with a customer id writes it onto a Person that has
|
|
56
|
-
-- none. First writer wins — oldest by completed_at, then created_at, then id.
|
|
57
|
-
UPDATE "people" p
|
|
58
|
-
SET "billing_provider" = 'stripe',
|
|
59
|
-
"billing_customer_id" = c."stripe_customer_id",
|
|
60
|
-
"updated_at" = now()
|
|
61
|
-
FROM (
|
|
62
|
-
SELECT DISTINCT ON (fc."workspace_id", lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"))
|
|
63
|
-
fc."workspace_id",
|
|
64
|
-
lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C") AS "email",
|
|
65
|
-
fc."stripe_customer_id"
|
|
66
|
-
FROM "flow_checkouts" fc
|
|
67
|
-
JOIN "leads" l ON l."id" = fc."lead_id" AND l."workspace_id" = fc."workspace_id"
|
|
68
|
-
WHERE fc."status" = 'completed'
|
|
69
|
-
AND fc."stripe_customer_id" IS NOT NULL
|
|
70
|
-
AND fc."stripe_customer_id" <> ''
|
|
71
|
-
AND length(fc."stripe_customer_id") <= 255
|
|
72
|
-
ORDER BY fc."workspace_id", lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"),
|
|
73
|
-
fc."completed_at" ASC NULLS LAST, fc."created_at" ASC, fc."id" ASC
|
|
74
|
-
) c
|
|
75
|
-
WHERE p."workspace_id" = c."workspace_id"
|
|
76
|
-
AND p."email" = c."email"
|
|
77
|
-
AND p."billing_customer_id" IS NULL;
|
|
78
|
-
|
|
79
|
-
-- 3. Appointments, by attendee email: a Person a lead already made keeps its
|
|
80
|
-
-- lead-derived name and created_at (ON CONFLICT DO NOTHING).
|
|
81
|
-
INSERT INTO "people" ("workspace_id", "email", "name", "created_at", "updated_at")
|
|
82
|
-
SELECT DISTINCT ON (a."workspace_id", lower(btrim(a."attendee_email", E' \t\n\r\f\x0B') COLLATE "C"))
|
|
83
|
-
a."workspace_id",
|
|
84
|
-
lower(btrim(a."attendee_email", E' \t\n\r\f\x0B') COLLATE "C"),
|
|
85
|
-
NULLIF(left(btrim(regexp_replace(a."attendee_name", '[\x01-\x1F\x7F-\x9F\u200E\u200F\u202A-\u202E\u2066-\u2069]', '', 'g')), 200), ''),
|
|
86
|
-
a."created_at",
|
|
87
|
-
now()
|
|
88
|
-
FROM "appointments" a
|
|
89
|
-
WHERE lower(btrim(a."attendee_email", E' \t\n\r\f\x0B') COLLATE "C") ~ '^[!-?A-~]+@[!-?A-~]+$'
|
|
90
|
-
AND length(lower(btrim(a."attendee_email", E' \t\n\r\f\x0B') COLLATE "C")) <= 254
|
|
91
|
-
ORDER BY a."workspace_id", lower(btrim(a."attendee_email", E' \t\n\r\f\x0B') COLLATE "C"), a."created_at" ASC, a."id" ASC
|
|
92
|
-
ON CONFLICT ("workspace_id", "email") DO NOTHING;
|
|
93
|
-
|
|
94
|
-
-- 4. Stamps: every lead and appointment with a storable email points at its
|
|
95
|
-
-- workspace's Person; a row already stamped is left alone.
|
|
96
|
-
UPDATE "leads"
|
|
97
|
-
SET "person_id" = p."id"
|
|
98
|
-
FROM "people" p
|
|
99
|
-
WHERE "leads"."person_id" IS NULL
|
|
100
|
-
AND p."workspace_id" = "leads"."workspace_id"
|
|
101
|
-
AND p."email" = lower(btrim("leads"."email", E' \t\n\r\f\x0B') COLLATE "C");
|
|
102
|
-
|
|
103
|
-
UPDATE "appointments"
|
|
104
|
-
SET "person_id" = p."id"
|
|
105
|
-
FROM "people" p
|
|
106
|
-
WHERE "appointments"."person_id" IS NULL
|
|
107
|
-
AND p."workspace_id" = "appointments"."workspace_id"
|
|
108
|
-
AND p."email" = lower(btrim("appointments"."attendee_email", E' \t\n\r\f\x0B') COLLATE "C");
|
|
109
|
-
|
|
110
|
-
-- 5. user_id, verified only: the oldest promoted lead (by promoted_at, then
|
|
111
|
-
-- created_at, then id) whose user is email-verified and whose verified
|
|
112
|
-
-- address normalizes to the Person's. An unverified or differing user is
|
|
113
|
-
-- never copied — the rule stampPersonUser applies to new rows.
|
|
114
|
-
UPDATE "people" p
|
|
115
|
-
SET "user_id" = c."user_id",
|
|
116
|
-
"updated_at" = now()
|
|
117
|
-
FROM (
|
|
118
|
-
SELECT DISTINCT ON (l."workspace_id", lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"))
|
|
119
|
-
l."workspace_id",
|
|
120
|
-
lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C") AS "email",
|
|
121
|
-
l."promoted_user_id" AS "user_id"
|
|
122
|
-
FROM "leads" l
|
|
123
|
-
JOIN "users" u ON u."id" = l."promoted_user_id"
|
|
124
|
-
WHERE l."promoted_user_id" IS NOT NULL
|
|
125
|
-
AND u."email_verified" = true
|
|
126
|
-
AND lower(btrim(u."email", E' \t\n\r\f\x0B') COLLATE "C") = lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C")
|
|
127
|
-
ORDER BY l."workspace_id", lower(btrim(l."email", E' \t\n\r\f\x0B') COLLATE "C"),
|
|
128
|
-
l."promoted_at" ASC NULLS LAST, l."created_at" ASC, l."id" ASC
|
|
129
|
-
) c
|
|
130
|
-
WHERE p."workspace_id" = c."workspace_id"
|
|
131
|
-
AND p."email" = c."email"
|
|
132
|
-
AND p."user_id" IS NULL;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
-- #852 — an agent key may be granted people-read (spec
|
|
2
|
-
-- docs/specs/852-person-the-per-workspace-client-spec.md D9).
|
|
3
|
-
--
|
|
4
|
-
-- Widens the agents_grants_allowed CHECK from the five #7864 permissions to
|
|
5
|
-
-- six. The CHECK names the same six as @working-theory/validation's
|
|
6
|
-
-- AGENT_GRANTABLE_PERMISSIONS; database/__tests__/agents.db.test.ts reads
|
|
7
|
-
-- this file and fails if the two lists differ (SEC-7864-G).
|
|
8
|
-
--
|
|
9
|
-
-- PURELY ADDITIVE in effect: the new CHECK admits every row the old one
|
|
10
|
-
-- admitted, so re-adding it cannot fail on existing data. No row changes.
|
|
11
|
-
--
|
|
12
|
-
-- Rollback: ALTER TABLE "agents" DROP CONSTRAINT "agents_grants_allowed";
|
|
13
|
-
-- then re-add the five-id CHECK from 20261009120000_agent_grants. That
|
|
14
|
-
-- re-add FAILS while any row holds people-read — remove those grants first.
|
|
15
|
-
|
|
16
|
-
ALTER TABLE "agents" DROP CONSTRAINT "agents_grants_allowed";
|
|
17
|
-
|
|
18
|
-
-- Only the six grantable permissions may be stored.
|
|
19
|
-
ALTER TABLE "agents" ADD CONSTRAINT "agents_grants_allowed"
|
|
20
|
-
CHECK ("grants" <@ ARRAY['content-edit','content-publish','assets-write','magnets-manage','meeting-types-manage','people-read']::TEXT[]);
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
-- #7877 — the member area contract (spec
|
|
2
|
-
-- docs/specs/7877-the-member-area-contract-a-spec.md D1, D2, D3).
|
|
3
|
-
--
|
|
4
|
-
-- pieces (inbox) — one deliverable for one client: a title, a stage
|
|
5
|
-
-- drawn from the workspace's declared list, a
|
|
6
|
-
-- needs-client flag. Written only through
|
|
7
|
-
-- apps/api's tenantDb(tenant).memberArea.
|
|
8
|
-
-- interactions (inbox) — one outbound message on the 'member' channel to
|
|
9
|
-
-- one client, optionally carrying a workspace
|
|
10
|
-
-- library asset. The original CRM spec's
|
|
11
|
-
-- Interaction table cut to one channel and one
|
|
12
|
-
-- direction; an inbound reply is a later second
|
|
13
|
-
-- direction value on this table.
|
|
14
|
-
-- workspace_piece_stages (config) — a workspace's declared piece stages,
|
|
15
|
-
-- in order, one row per workspace. No row means the
|
|
16
|
-
-- product default, which lives in apps/api only.
|
|
17
|
-
-- people_id_workspace_id_key — a unique index over a pair the PK already
|
|
18
|
-
-- makes unique: the target of the composite
|
|
19
|
-
-- (person_id, workspace_id) foreign keys, so "a
|
|
20
|
-
-- Person of the same workspace" is a database fact.
|
|
21
|
-
--
|
|
22
|
-
-- Both foreign keys stay inside the inbox namespace (ADR 0009 invariant 1).
|
|
23
|
-
-- workspace_id, asset_id, created_by and updated_by name rows of other
|
|
24
|
-
-- namespaces: plain columns with format CHECKs, no foreign key. Neither new
|
|
25
|
-
-- inbox table carries an email.
|
|
26
|
-
--
|
|
27
|
-
-- PURELY ADDITIVE, DDL ONLY: three new tables and one unique index on
|
|
28
|
-
-- "people". No existing row changes. The unique index builds under the
|
|
29
|
-
-- file's transaction, holding a SHARE lock on "people" (writes wait, reads do
|
|
30
|
-
-- not) for one scan of a table that is one row per client.
|
|
31
|
-
--
|
|
32
|
-
-- Rollout: deploy this migration BEFORE the API code that reads or writes
|
|
33
|
-
-- these tables; code without them fails every member-area read and write.
|
|
34
|
-
--
|
|
35
|
-
-- Rollback: DROP TABLE "interactions"; DROP TABLE "pieces"; DROP TABLE
|
|
36
|
-
-- "workspace_piece_stages"; DROP INDEX "people_id_workspace_id_key"; (the
|
|
37
|
-
-- indexes, foreign keys and CHECKs go with them). Safe while nothing but
|
|
38
|
-
-- #7877's own code reads them.
|
|
39
|
-
|
|
40
|
-
-- CreateTable
|
|
41
|
-
CREATE TABLE "workspace_piece_stages" (
|
|
42
|
-
"id" TEXT NOT NULL DEFAULT ('pstages_'::text || (uuidv7())::text),
|
|
43
|
-
"workspace_id" TEXT NOT NULL,
|
|
44
|
-
"stages" TEXT[],
|
|
45
|
-
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
46
|
-
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
47
|
-
|
|
48
|
-
CONSTRAINT "workspace_piece_stages_pkey" PRIMARY KEY ("id")
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
-- CreateTable
|
|
52
|
-
CREATE TABLE "pieces" (
|
|
53
|
-
"id" TEXT NOT NULL DEFAULT ('piece_'::text || (uuidv7())::text),
|
|
54
|
-
"workspace_id" TEXT NOT NULL,
|
|
55
|
-
"person_id" TEXT NOT NULL,
|
|
56
|
-
"title" VARCHAR(200) NOT NULL,
|
|
57
|
-
"stage" VARCHAR(40) NOT NULL,
|
|
58
|
-
"needs_client" BOOLEAN NOT NULL DEFAULT false,
|
|
59
|
-
"updated_by" TEXT NOT NULL,
|
|
60
|
-
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
61
|
-
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
62
|
-
|
|
63
|
-
CONSTRAINT "pieces_pkey" PRIMARY KEY ("id")
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
-- CreateTable
|
|
67
|
-
CREATE TABLE "interactions" (
|
|
68
|
-
"id" TEXT NOT NULL DEFAULT ('intx_'::text || (uuidv7())::text),
|
|
69
|
-
"workspace_id" TEXT NOT NULL,
|
|
70
|
-
"person_id" TEXT NOT NULL,
|
|
71
|
-
"channel" VARCHAR(16) NOT NULL,
|
|
72
|
-
"direction" VARCHAR(16) NOT NULL,
|
|
73
|
-
"subject" VARCHAR(200) NOT NULL,
|
|
74
|
-
"body" TEXT NOT NULL,
|
|
75
|
-
"asset_id" TEXT,
|
|
76
|
-
"created_by" TEXT NOT NULL,
|
|
77
|
-
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
78
|
-
"read_at" TIMESTAMP(3),
|
|
79
|
-
|
|
80
|
-
CONSTRAINT "interactions_pkey" PRIMARY KEY ("id")
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
-- CreateIndex
|
|
84
|
-
-- One stage list per workspace — the WorkspaceMeetings shape.
|
|
85
|
-
CREATE UNIQUE INDEX "workspace_piece_stages_workspace_id_key" ON "workspace_piece_stages"("workspace_id");
|
|
86
|
-
|
|
87
|
-
-- CreateIndex
|
|
88
|
-
-- A client's pieces: workspace_id = $1 AND person_id = $2 ORDER BY created_at DESC.
|
|
89
|
-
CREATE INDEX "pieces_workspace_id_person_id_created_at_idx" ON "pieces"("workspace_id", "person_id", "created_at");
|
|
90
|
-
|
|
91
|
-
-- CreateIndex
|
|
92
|
-
-- A client's messages, the same read shape as pieces.
|
|
93
|
-
CREATE INDEX "interactions_workspace_id_person_id_created_at_idx" ON "interactions"("workspace_id", "person_id", "created_at");
|
|
94
|
-
|
|
95
|
-
-- CreateIndex
|
|
96
|
-
-- The public asset read's "is this asset attached to any message" count (D18).
|
|
97
|
-
CREATE INDEX "interactions_asset_id_idx" ON "interactions"("asset_id");
|
|
98
|
-
|
|
99
|
-
-- CreateIndex
|
|
100
|
-
-- Redundant with the PK; the composite foreign keys below need it as their target.
|
|
101
|
-
CREATE UNIQUE INDEX "people_id_workspace_id_key" ON "people"("id", "workspace_id");
|
|
102
|
-
|
|
103
|
-
-- AddForeignKey
|
|
104
|
-
-- A piece names a Person of ITS OWN workspace; deleting a Person with a piece is refused.
|
|
105
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_person_fk" FOREIGN KEY ("person_id", "workspace_id") REFERENCES "people"("id", "workspace_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
106
|
-
|
|
107
|
-
-- AddForeignKey
|
|
108
|
-
-- The same rule for a message.
|
|
109
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_person_fk" FOREIGN KEY ("person_id", "workspace_id") REFERENCES "people"("id", "workspace_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
110
|
-
|
|
111
|
-
-- ADR-0031 rule 3 — pieces: piece_, interactions: intx_,
|
|
112
|
-
-- workspace_piece_stages: pstages_ (registered in
|
|
113
|
-
-- packages/ids/src/registry.ts; this migration's path is added to
|
|
114
|
-
-- migration-sync.test.ts's PK_CHECK_MIGRATIONS). Each reference column
|
|
115
|
-
-- carries the format CHECK of the entity it names, in the person-migration
|
|
116
|
-
-- shape.
|
|
117
|
-
ALTER TABLE "pieces" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
118
|
-
ALTER TABLE "pieces" ALTER COLUMN "id" SET DEFAULT ('piece_'::text || (uuidv7())::text);
|
|
119
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_id_format" CHECK ("id" ~ '^piece_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
120
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_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}$');
|
|
121
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_person_id_format" CHECK ("person_id" ~ '^person_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
122
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_updated_by_format" CHECK ("updated_by" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
123
|
-
|
|
124
|
-
ALTER TABLE "interactions" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
125
|
-
ALTER TABLE "interactions" ALTER COLUMN "id" SET DEFAULT ('intx_'::text || (uuidv7())::text);
|
|
126
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_id_format" CHECK ("id" ~ '^intx_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
127
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_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}$');
|
|
128
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_person_id_format" CHECK ("person_id" ~ '^person_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
129
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_created_by_format" CHECK ("created_by" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
130
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_asset_id_format" CHECK ("asset_id" ~ '^asset_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
131
|
-
|
|
132
|
-
ALTER TABLE "workspace_piece_stages" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
133
|
-
ALTER TABLE "workspace_piece_stages" ALTER COLUMN "id" SET DEFAULT ('pstages_'::text || (uuidv7())::text);
|
|
134
|
-
ALTER TABLE "workspace_piece_stages" ADD CONSTRAINT "workspace_piece_stages_id_format" CHECK ("id" ~ '^pstages_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
135
|
-
ALTER TABLE "workspace_piece_stages" ADD CONSTRAINT "workspace_piece_stages_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}$');
|
|
136
|
-
|
|
137
|
-
-- A piece's title is 1–200 characters once trimmed; a stage is a slug. Which
|
|
138
|
-
-- slugs a workspace accepts is its declared list, checked at write time by
|
|
139
|
-
-- the API — never an enum here or in packages/validation.
|
|
140
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_title_length"
|
|
141
|
-
CHECK (char_length(btrim("title")) BETWEEN 1 AND 200);
|
|
142
|
-
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_stage_format"
|
|
143
|
-
CHECK ("stage" ~ '^[a-z0-9][a-z0-9-]{0,39}$');
|
|
144
|
-
|
|
145
|
-
-- One channel and one direction in this slice. An inbound reply widens
|
|
146
|
-
-- interactions_direction_allowed in its own migration.
|
|
147
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_channel_allowed"
|
|
148
|
-
CHECK ("channel" = 'member');
|
|
149
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_direction_allowed"
|
|
150
|
-
CHECK ("direction" = 'outbound');
|
|
151
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_subject_length"
|
|
152
|
-
CHECK (char_length(btrim("subject")) BETWEEN 1 AND 200);
|
|
153
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_body_length"
|
|
154
|
-
CHECK (char_length(btrim("body")) BETWEEN 1 AND 10000);
|
|
155
|
-
|
|
156
|
-
-- A declared list holds 1–20 stages (never NULL: no row is the default).
|
|
157
|
-
ALTER TABLE "workspace_piece_stages" ADD CONSTRAINT "workspace_piece_stages_count"
|
|
158
|
-
CHECK ("stages" IS NOT NULL AND cardinality("stages") BETWEEN 1 AND 20);
|
package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
-- #7878 — an agent key may be granted member-pieces-manage: a client's
|
|
2
|
-
-- pieces, plan and outbound messages (#7877's operator writes).
|
|
3
|
-
--
|
|
4
|
-
-- Widens the agents_grants_allowed CHECK from the six #852 permissions to
|
|
5
|
-
-- seven. The CHECK names the same seven as @working-theory/validation's
|
|
6
|
-
-- AGENT_GRANTABLE_PERMISSIONS; database/__tests__/agents.db.test.ts reads
|
|
7
|
-
-- this file and fails if the two lists differ (SEC-7864-G).
|
|
8
|
-
--
|
|
9
|
-
-- PURELY ADDITIVE in effect: the new CHECK admits every row the old one
|
|
10
|
-
-- admitted, so re-adding it cannot fail on existing data. No row changes.
|
|
11
|
-
--
|
|
12
|
-
-- Rollback: ALTER TABLE "agents" DROP CONSTRAINT "agents_grants_allowed";
|
|
13
|
-
-- then re-add the six-id CHECK from 20261010130000_agent_grants_people_read.
|
|
14
|
-
-- That re-add FAILS while any row holds member-pieces-manage — remove those
|
|
15
|
-
-- grants first.
|
|
16
|
-
|
|
17
|
-
ALTER TABLE "agents" DROP CONSTRAINT "agents_grants_allowed";
|
|
18
|
-
|
|
19
|
-
-- Only the seven grantable permissions may be stored.
|
|
20
|
-
ALTER TABLE "agents" ADD CONSTRAINT "agents_grants_allowed"
|
|
21
|
-
CHECK ("grants" <@ ARRAY['content-edit','content-publish','assets-write','magnets-manage','meeting-types-manage','people-read','member-pieces-manage']::TEXT[]);
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
-- #8168 — the member area data model (spec
|
|
2
|
-
-- docs/specs/8168-member-area-data-model-spec.md D1–D3, D5, D7–D9, D12).
|
|
3
|
-
--
|
|
4
|
-
-- piece_versions (inbox) — one delivery of a piece to its client:
|
|
5
|
-
-- a private library file OR an https
|
|
6
|
-
-- link, numbered from 1 per piece, with
|
|
7
|
-
-- the client's review recorded on it.
|
|
8
|
-
-- NO round count, limit or remaining
|
|
9
|
-
-- column (#8140 disposition 3).
|
|
10
|
-
-- pieces.approved_at — set with an `approved` review; freezes
|
|
11
|
-
-- review (D5).
|
|
12
|
-
-- pieces_id_person_id_workspace_id_key — a unique index over a triple the
|
|
13
|
-
-- PK already makes unique: the target of
|
|
14
|
-
-- piece_versions_piece_fk, so "a piece of
|
|
15
|
-
-- THIS Person in THIS workspace" is one
|
|
16
|
-
-- database fact (D1).
|
|
17
|
-
-- interactions.kind / .payload — `message` · `quote` · `review`, and the
|
|
18
|
-
-- stored payload of a quote or review;
|
|
19
|
-
-- `inbound` joins `outbound` (D3). An
|
|
20
|
-
-- outbound row stays a payload-free
|
|
21
|
-
-- `message` — #7877's rows, unchanged.
|
|
22
|
-
-- flow_definitions.customers_enabled — whether a signed-in client may submit
|
|
23
|
-
-- the magnet from the member area (D7).
|
|
24
|
-
-- the `request-quote` magnet — one draft `contact` magnet with
|
|
25
|
-
-- customers_enabled = true, backfilled
|
|
26
|
-
-- into EVERY existing workspace (D8).
|
|
27
|
-
--
|
|
28
|
-
-- The only new foreign key stays inside the inbox namespace (ADR 0009
|
|
29
|
-
-- invariant 1). asset_id and delivered_by name rows of other namespaces:
|
|
30
|
-
-- plain columns with format CHECKs, no foreign key. The backfill reads
|
|
31
|
-
-- "workspaces" (auth namespace) in SQL only — no relation.
|
|
32
|
-
--
|
|
33
|
-
-- ADDITIVE: every ADD COLUMN is nullable or carries a constant default, so no
|
|
34
|
-
-- existing row fails a new CHECK — every existing interaction is an outbound
|
|
35
|
-
-- `message` with no payload, which the replaced and added CHECKs admit
|
|
36
|
-
-- (interactions_body_length keeps its 1–10000 rule for a `message`). The
|
|
37
|
-
-- unique index on "pieces" builds under the file's transaction, holding a
|
|
38
|
-
-- SHARE lock on "pieces" for one scan of a table that is a few rows per
|
|
39
|
-
-- client. The backfill inserts one row per workspace and NEVER overwrites a
|
|
40
|
-
-- workspace's existing (site_id, slug) row (ON CONFLICT DO NOTHING) —
|
|
41
|
-
-- re-running the block adds nothing.
|
|
42
|
-
--
|
|
43
|
-
-- Rollout: deploy this migration BEFORE any code that writes piece_versions,
|
|
44
|
-
-- pieces.approved_at, an inbound interaction, interactions.kind/payload or
|
|
45
|
-
-- flow_definitions.customers_enabled. Code written before it never names the
|
|
46
|
-
-- new columns, so it keeps working against the migrated database.
|
|
47
|
-
--
|
|
48
|
-
-- Rollback (safe while nothing but #8168's siblings use the new surface):
|
|
49
|
-
-- DELETE FROM "flow_definitions" WHERE "slug" = 'request-quote' AND "status" = 'draft' AND "customers_enabled";
|
|
50
|
-
-- ALTER TABLE "flow_definitions" DROP COLUMN "customers_enabled";
|
|
51
|
-
-- DELETE FROM "interactions" WHERE "direction" = 'inbound';
|
|
52
|
-
-- ALTER TABLE "interactions" DROP CONSTRAINT "interactions_kind_allowed",
|
|
53
|
-
-- DROP CONSTRAINT "interactions_outbound_shape", DROP CONSTRAINT "interactions_payload_by_kind",
|
|
54
|
-
-- DROP CONSTRAINT "interactions_payload_size", DROP CONSTRAINT "interactions_body_length",
|
|
55
|
-
-- DROP CONSTRAINT "interactions_direction_allowed";
|
|
56
|
-
-- ALTER TABLE "interactions" DROP COLUMN "kind", DROP COLUMN "payload";
|
|
57
|
-
-- then re-add #7877's interactions_direction_allowed (direction = 'outbound')
|
|
58
|
-
-- and interactions_body_length (1–10000 once trimmed) from
|
|
59
|
-
-- 20261011120000_member_area;
|
|
60
|
-
-- DROP TABLE "piece_versions"; DROP INDEX "pieces_id_person_id_workspace_id_key";
|
|
61
|
-
-- ALTER TABLE "pieces" DROP COLUMN "approved_at";
|
|
62
|
-
-- The first DELETE also removes an operator's own edits to a still-draft
|
|
63
|
-
-- seeded magnet; check for those before rolling back.
|
|
64
|
-
|
|
65
|
-
-- AlterTable
|
|
66
|
-
ALTER TABLE "flow_definitions" ADD COLUMN "customers_enabled" BOOLEAN NOT NULL DEFAULT false;
|
|
67
|
-
|
|
68
|
-
-- AlterTable
|
|
69
|
-
-- Existing rows and #7877's writer (which names no kind) stay `message`.
|
|
70
|
-
ALTER TABLE "interactions" ADD COLUMN "kind" VARCHAR(16) NOT NULL DEFAULT 'message',
|
|
71
|
-
ADD COLUMN "payload" JSONB;
|
|
72
|
-
|
|
73
|
-
-- AlterTable
|
|
74
|
-
ALTER TABLE "pieces" ADD COLUMN "approved_at" TIMESTAMP(3);
|
|
75
|
-
|
|
76
|
-
-- CreateTable
|
|
77
|
-
CREATE TABLE "piece_versions" (
|
|
78
|
-
"id" TEXT NOT NULL DEFAULT ('pver_'::text || (uuidv7())::text),
|
|
79
|
-
"workspace_id" TEXT NOT NULL,
|
|
80
|
-
"person_id" TEXT NOT NULL,
|
|
81
|
-
"piece_id" TEXT NOT NULL,
|
|
82
|
-
"version" INTEGER NOT NULL,
|
|
83
|
-
"asset_id" TEXT,
|
|
84
|
-
"link" VARCHAR(2048),
|
|
85
|
-
"note" TEXT,
|
|
86
|
-
"delivered_by" TEXT NOT NULL,
|
|
87
|
-
"delivered_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
88
|
-
"review" VARCHAR(24),
|
|
89
|
-
"review_comment" TEXT,
|
|
90
|
-
"reviewed_at" TIMESTAMP(3),
|
|
91
|
-
|
|
92
|
-
CONSTRAINT "piece_versions_pkey" PRIMARY KEY ("id")
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
-- CreateIndex
|
|
96
|
-
-- A client's artifacts: workspace_id = $1 AND person_id = $2 ORDER BY delivered_at DESC.
|
|
97
|
-
CREATE INDEX "piece_versions_workspace_id_person_id_delivered_at_idx" ON "piece_versions"("workspace_id", "person_id", "delivered_at");
|
|
98
|
-
|
|
99
|
-
-- CreateIndex
|
|
100
|
-
-- The public asset read's "is this asset a version file" check (AC-MAA-21).
|
|
101
|
-
CREATE INDEX "piece_versions_asset_id_idx" ON "piece_versions"("asset_id");
|
|
102
|
-
|
|
103
|
-
-- CreateIndex
|
|
104
|
-
-- A version number is a fact per piece; the writer numbers, this is the backstop.
|
|
105
|
-
CREATE UNIQUE INDEX "piece_versions_piece_id_version_key" ON "piece_versions"("piece_id", "version");
|
|
106
|
-
|
|
107
|
-
-- CreateIndex
|
|
108
|
-
-- Redundant with the PK; piece_versions_piece_fk needs it as its target.
|
|
109
|
-
CREATE UNIQUE INDEX "pieces_id_person_id_workspace_id_key" ON "pieces"("id", "person_id", "workspace_id");
|
|
110
|
-
|
|
111
|
-
-- AddForeignKey
|
|
112
|
-
-- A version names a piece of THIS Person in THIS workspace (the piece's own
|
|
113
|
-
-- FK already ties it to a Person of its workspace); deleting a piece with a
|
|
114
|
-
-- version is refused.
|
|
115
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_piece_fk" FOREIGN KEY ("piece_id", "person_id", "workspace_id") REFERENCES "pieces"("id", "person_id", "workspace_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
116
|
-
|
|
117
|
-
-- ADR-0031 rule 3 — piece_versions: pver_ (registered in
|
|
118
|
-
-- packages/ids/src/registry.ts; this migration's path is added to
|
|
119
|
-
-- migration-sync.test.ts's PK_CHECK_MIGRATIONS). Each reference column
|
|
120
|
-
-- carries the format CHECK of the entity it names, in the #7877 shape.
|
|
121
|
-
ALTER TABLE "piece_versions" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
122
|
-
ALTER TABLE "piece_versions" ALTER COLUMN "id" SET DEFAULT ('pver_'::text || (uuidv7())::text);
|
|
123
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_id_format" CHECK ("id" ~ '^pver_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
124
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_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}$');
|
|
125
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_person_id_format" CHECK ("person_id" ~ '^person_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
126
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_piece_id_format" CHECK ("piece_id" ~ '^piece_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
127
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_asset_id_format" CHECK ("asset_id" ~ '^asset_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
128
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_delivered_by_format" CHECK ("delivered_by" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
129
|
-
|
|
130
|
-
-- D2 — a version's shape is held here, not by the writer alone.
|
|
131
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_version_positive"
|
|
132
|
-
CHECK ("version" >= 1);
|
|
133
|
-
-- A delivery is a file or a link: exactly one.
|
|
134
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_one_target"
|
|
135
|
-
CHECK (("asset_id" IS NULL) <> ("link" IS NULL));
|
|
136
|
-
-- An https scheme, a host with no userinfo, no whitespace anywhere — the
|
|
137
|
-
-- database floor under packages/validation's isHttpsLink (SEC-8168-5).
|
|
138
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_link_https"
|
|
139
|
-
CHECK ("link" IS NULL OR ("link" ~ '^https://[^[:space:]/?#@]+([/?#][^[:space:]]*)?$' AND char_length("link") <= 2048));
|
|
140
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_note_length"
|
|
141
|
-
CHECK ("note" IS NULL OR char_length(btrim("note")) BETWEEN 1 AND 2000);
|
|
142
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_review_allowed"
|
|
143
|
-
CHECK ("review" IS NULL OR "review" IN ('approved', 'changes-requested'));
|
|
144
|
-
-- A review and its timestamp are set together or not at all.
|
|
145
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_review_stamped"
|
|
146
|
-
CHECK (("review" IS NULL) = ("reviewed_at" IS NULL));
|
|
147
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_comment_needs_review"
|
|
148
|
-
CHECK ("review_comment" IS NULL OR "review" IS NOT NULL);
|
|
149
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_changes_need_comment"
|
|
150
|
-
CHECK ("review" IS DISTINCT FROM 'changes-requested' OR char_length(btrim(coalesce("review_comment", ''))) >= 1);
|
|
151
|
-
ALTER TABLE "piece_versions" ADD CONSTRAINT "piece_versions_comment_length"
|
|
152
|
-
CHECK ("review_comment" IS NULL OR char_length("review_comment") <= 5000);
|
|
153
|
-
|
|
154
|
-
-- D3 — the second direction and the kinds. Replaced IN PLACE under the same
|
|
155
|
-
-- names, so #7877's tests keep naming the same constraints.
|
|
156
|
-
ALTER TABLE "interactions" DROP CONSTRAINT "interactions_direction_allowed";
|
|
157
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_direction_allowed"
|
|
158
|
-
CHECK ("direction" IN ('outbound', 'inbound'));
|
|
159
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_kind_allowed"
|
|
160
|
-
CHECK ("kind" IN ('message', 'quote', 'review'));
|
|
161
|
-
-- An outbound row is a payload-free `message` — #7877's rows, unchanged.
|
|
162
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_outbound_shape"
|
|
163
|
-
CHECK ("direction" <> 'outbound' OR ("kind" = 'message' AND "payload" IS NULL));
|
|
164
|
-
-- A quote or a review always carries its stored payload.
|
|
165
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_payload_by_kind"
|
|
166
|
-
CHECK ("kind" = 'message' OR "payload" IS NOT NULL);
|
|
167
|
-
-- 64 items of a 200-character label and a 2000-character value fit with room (SEC-8168-4).
|
|
168
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_payload_size"
|
|
169
|
-
CHECK ("payload" IS NULL OR octet_length("payload"::text) <= 262144);
|
|
170
|
-
-- A message body stays 1–10000 characters once trimmed; a quote or review
|
|
171
|
-
-- body may be empty; no body exceeds 10000.
|
|
172
|
-
ALTER TABLE "interactions" DROP CONSTRAINT "interactions_body_length";
|
|
173
|
-
ALTER TABLE "interactions" ADD CONSTRAINT "interactions_body_length"
|
|
174
|
-
CHECK (
|
|
175
|
-
char_length("body") <= 10000
|
|
176
|
-
AND ("kind" <> 'message' OR char_length(btrim("body")) BETWEEN 1 AND 10000)
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
-- D8/D9 — the request-quote magnet in every existing workspace. The config
|
|
180
|
-
-- literal below is test-held to `requestQuoteFlowConfig`
|
|
181
|
-
-- (packages/validation/src/schemas/flow.ts) by
|
|
182
|
-
-- database/__tests__/member-contract-migration.test.ts, and the block is
|
|
183
|
-
-- re-executed verbatim by member-contract.db.test.ts to prove it idempotent.
|
|
184
|
-
-- Do not edit one without the other.
|
|
185
|
-
-- BEGIN request-quote backfill
|
|
186
|
-
INSERT INTO "flow_definitions" ("site_id", "workspace_id", "slug", "config", "kind", "title", "status", "customers_enabled", "updated_at")
|
|
187
|
-
SELECT w."id", w."id", 'request-quote',
|
|
188
|
-
'{"slug":"request-quote","defaultLocale":"en","steps":[{"key":"request","type":"field","copy":{"title":{"en":"Request a quote"}},"fields":[{"name":"need","inputType":"textarea","required":true,"copy":{"label":{"en":"What do you need?"}}},{"name":"timing","inputType":"text","copy":{"label":{"en":"When do you need it?"}}},{"name":"budget","inputType":"text","copy":{"label":{"en":"Budget range"},"help":{"en":"A rough range is fine."}}},{"name":"link","inputType":"url","copy":{"label":{"en":"Link"},"help":{"en":"A brief, a document or an example. Must start with https://."}}}]}]}'::jsonb,
|
|
189
|
-
'contact', 'Request a quote', 'draft', true, CURRENT_TIMESTAMP
|
|
190
|
-
FROM "workspaces" w
|
|
191
|
-
ON CONFLICT ("site_id", "slug") DO NOTHING;
|
|
192
|
-
-- END request-quote backfill
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
-- #8185 — record, at the moment the hub writes it, that a lead is a spoke's
|
|
2
|
-
-- live paid checkout (spec docs/specs/8185-spoke-checkout-purchases-spec.md
|
|
3
|
-
-- D1, D6, D10).
|
|
4
|
-
--
|
|
5
|
-
-- leads.spoke_checkout — set true by apps/api/src/services/lead-routing.ts
|
|
6
|
-
-- only for a spoke-keyed, unrelayed submit passing
|
|
7
|
-
-- the #7877 checkout plan rule's predicate. Written
|
|
8
|
-
-- at creation, never updated. NOT NULL with a
|
|
9
|
-
-- constant default, so existing rows read false and
|
|
10
|
-
-- nothing is rewritten; they are deliberately NOT
|
|
11
|
-
-- backfilled (D6: no stored fact proves an older
|
|
12
|
-
-- lead's provenance).
|
|
13
|
-
--
|
|
14
|
-
-- Rollout order (D10): apply this migration to a deployment's database BEFORE
|
|
15
|
-
-- deploying the API that writes the column. The old API is unaffected by it;
|
|
16
|
-
-- the new API's marked create fails without it.
|
|
17
|
-
--
|
|
18
|
-
-- Rollback: ALTER TABLE "leads" DROP COLUMN "spoke_checkout";
|
|
19
|
-
|
|
20
|
-
ALTER TABLE "leads" ADD COLUMN "spoke_checkout" BOOLEAN NOT NULL DEFAULT false;
|