create-ailk 0.1.0 → 0.2.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 +124 -3
- package/component-catalog.md +456 -0
- package/dist/cli.js +92 -16
- package/dist/component-catalog.d.ts +11 -0
- package/dist/component-catalog.js +39 -0
- package/dist/copy.d.ts +7 -0
- package/dist/copy.js +24 -0
- package/dist/derive-architecture.d.ts +13 -0
- package/dist/derive-architecture.js +238 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +19 -2
- package/dist/lib/extract-module-bundle.d.ts +16 -0
- package/dist/lib/extract-module-bundle.js +184 -0
- package/dist/lib/fetch-module.d.ts +55 -0
- package/dist/lib/fetch-module.js +125 -0
- package/dist/lib/module-license-gate.d.ts +48 -0
- package/dist/lib/module-license-gate.js +67 -0
- package/dist/lib/module-tier.d.ts +35 -0
- package/dist/lib/module-tier.js +37 -0
- package/dist/module-architecture.d.ts +175 -0
- package/dist/module-architecture.js +663 -0
- package/dist/parse-args.d.ts +47 -1
- package/dist/parse-args.js +143 -2
- package/dist/programmatic.d.ts +160 -3
- package/dist/programmatic.js +196 -7
- package/dist/surfaces.d.ts +211 -0
- package/dist/surfaces.js +532 -0
- package/dist/sync-routes.d.ts +92 -0
- package/dist/sync-routes.js +350 -0
- package/package.json +12 -5
- package/templates/.claude/rules/architecture.md +6 -2
- package/templates/.claude/skills/README.md +9 -9
- package/templates/.claude/skills/add-schema/SKILL.md +14 -7
- package/templates/.claude/skills/add-schema/references/schema-types.md +109 -6
- package/templates/.claude/skills/provision-config/SKILL.md +1 -1
- package/templates/.claude/skills/scaffold-commerce/SKILL.md +498 -1
- package/templates/.claude/skills/scaffold-commerce/templates/checkout-route.template.ts +370 -0
- package/templates/.claude/skills/scaffold-commerce/templates/invoice-route.template.ts +376 -0
- package/templates/.claude/skills/scaffold-commerce/templates/payment-link-route.template.ts +471 -0
- package/templates/.claude/skills/scaffold-commerce/templates/portal-route.template.ts +365 -0
- package/templates/.claude/skills/scaffold-commerce/templates/stripe-config.template.ts +60 -0
- package/templates/.claude/skills/scaffold-commerce/templates/subscription-route.template.ts +446 -0
- package/templates/.claude/skills/suggest-site-pages/references/categories.md +4 -4
- package/templates/.env.example +126 -2
- package/templates/CLAUDE.md +11 -5
- package/templates/README.md +1 -1
- package/templates/apps/api/.env.example +38 -0
- package/templates/apps/api/CLAUDE.md +78 -1
- package/templates/apps/api/LICENSE +201 -0
- package/templates/apps/api/api/index.ts +6 -141
- package/templates/apps/api/jest.config.cjs +16 -0
- package/templates/apps/api/package.json +22 -6
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +141 -0
- package/templates/apps/api/src/__tests__/server.test.ts +46 -0
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +211 -0
- package/templates/apps/api/src/bin/abandon-sweep.ts +42 -0
- package/templates/apps/api/src/bin/deliverable-resend.ts +144 -0
- package/templates/apps/api/src/bin/deliverable-upload.ts +114 -0
- package/templates/apps/api/src/bin/followup-sweep.ts +44 -0
- package/templates/apps/api/src/bin/listing-csv-sweep.ts +46 -0
- package/templates/apps/api/src/bin/seed-presets.ts +58 -0
- package/templates/apps/api/src/bin/seed-waitlist-experiments.ts +104 -0
- package/templates/apps/api/src/bin/session-retention-sweep.ts +46 -0
- package/templates/apps/api/src/cli.ts +5 -11
- package/templates/apps/api/src/config/index.ts +35 -0
- package/templates/apps/api/src/config/modules.ts +43 -0
- package/templates/apps/api/src/lib/__mocks__/prisma-client.js +11 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +241 -0
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +2 -2
- package/templates/apps/api/src/lib/site.ts +16 -0
- package/templates/apps/api/src/lib/stripe.ts +22 -0
- package/templates/apps/api/src/lib/tenant-db.ts +225 -0
- package/templates/apps/api/src/lib/ws-token.ts +91 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +7 -1
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +7 -1
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +91 -4
- package/templates/apps/api/src/middleware/auth.ts +43 -8
- package/templates/apps/api/src/middleware/rate-limit.ts +78 -3
- package/templates/apps/api/src/middleware/tenant.ts +99 -0
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +92 -0
- package/templates/apps/api/src/openapi/spec.ts +312 -3
- package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +175 -0
- package/templates/apps/api/src/routes/aeo/index.ts +107 -0
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +5 -2
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +22 -3
- package/templates/apps/api/src/routes/auth/tokens.ts +13 -1
- package/templates/apps/api/src/routes/billing/__tests__/portal.test.ts +450 -0
- package/templates/apps/api/src/routes/billing/__tests__/read.test.ts +262 -0
- package/templates/apps/api/src/routes/billing/__tests__/usage.test.ts +436 -0
- package/templates/apps/api/src/routes/billing/index.ts +36 -0
- package/templates/apps/api/src/routes/billing/portal.ts +182 -0
- package/templates/apps/api/src/routes/billing/read.ts +75 -0
- package/templates/apps/api/src/routes/billing/usage.ts +153 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +99 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +20 -8
- package/templates/apps/api/src/routes/content/create.ts +1 -0
- package/templates/apps/api/src/routes/content/delete.ts +1 -0
- package/templates/apps/api/src/routes/content/index.ts +42 -6
- package/templates/apps/api/src/routes/content/update.ts +1 -0
- package/templates/apps/api/src/routes/deliverables/__tests__/index.test.ts +393 -0
- package/templates/apps/api/src/routes/deliverables/index.ts +200 -0
- package/templates/apps/api/src/routes/flow-checkouts/__tests__/index.test.ts +443 -0
- package/templates/apps/api/src/routes/flow-checkouts/index.ts +82 -0
- package/templates/apps/api/src/routes/flows/README.md +147 -0
- package/templates/apps/api/src/routes/flows/__tests__/index.test.ts +752 -0
- package/templates/apps/api/src/routes/flows/__tests__/recommender.test.ts +671 -0
- package/templates/apps/api/src/routes/flows/index.ts +202 -0
- package/templates/apps/api/src/routes/flows/recommender.ts +443 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +438 -31
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +10 -10
- package/templates/apps/api/src/routes/leads/index.ts +43 -9
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +558 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/copy-edit.test.ts +815 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +869 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me-route-precedence.test.ts +221 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +468 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +424 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +707 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +375 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +467 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/tenant-isolation.test.ts +566 -0
- package/templates/apps/api/src/routes/project-listings/get.ts +70 -0
- package/templates/apps/api/src/routes/project-listings/index.ts +120 -0
- package/templates/apps/api/src/routes/project-listings/list.ts +47 -0
- package/templates/apps/api/src/routes/project-listings/me.ts +76 -0
- package/templates/apps/api/src/routes/project-listings/patch-copy.ts +222 -0
- package/templates/apps/api/src/routes/project-listings/patch-draft.ts +97 -0
- package/templates/apps/api/src/routes/project-listings/patch.ts +136 -0
- package/templates/apps/api/src/routes/project-listings/public.ts +52 -0
- package/templates/apps/api/src/routes/project-listings/respond.ts +37 -0
- package/templates/apps/api/src/routes/project-listings/resume-token.ts +22 -0
- package/templates/apps/api/src/routes/project-listings/start.ts +106 -0
- package/templates/apps/api/src/routes/project-listings/submit.ts +122 -0
- package/templates/apps/api/src/routes/schedule/__tests__/index.test.ts +490 -0
- package/templates/apps/api/src/routes/schedule/index.ts +249 -0
- package/templates/apps/api/src/routes/slack/__tests__/actions.test.ts +385 -0
- package/templates/apps/api/src/routes/slack/actions.ts +177 -0
- package/templates/apps/api/src/routes/slack/index.ts +38 -0
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +16 -6
- package/templates/apps/api/src/routes/test/auth/session.ts +8 -6
- package/templates/apps/api/src/routes/waitlist-experiments/__tests__/tenant-isolation.test.ts +577 -0
- package/templates/apps/api/src/routes/waitlist-experiments/comparison.ts +78 -0
- package/templates/apps/api/src/routes/waitlist-experiments/index.ts +41 -0
- package/templates/apps/api/src/routes/waitlist-experiments/list.ts +64 -0
- package/templates/apps/api/src/routes/waitlist-experiments/respond.ts +42 -0
- package/templates/apps/api/src/routes/waitlist-experiments/signup.ts +84 -0
- package/templates/apps/api/src/routes/waitlist-experiments/signups.ts +119 -0
- package/templates/apps/api/src/routes/waitlist-signups/__tests__/index.test.ts +238 -0
- package/templates/apps/api/src/routes/waitlist-signups/index.ts +101 -0
- package/templates/apps/api/src/routes/webhooks/README.md +35 -12
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +315 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +270 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +248 -20
- package/templates/apps/api/src/routes/workspaces/__tests__/config-tenant-isolation.test.ts +356 -0
- package/templates/apps/api/src/routes/workspaces/__tests__/tenant-isolation.test.ts +671 -0
- package/templates/apps/api/src/routes/workspaces/config.ts +125 -0
- package/templates/apps/api/src/routes/workspaces/index.ts +194 -0
- package/templates/apps/api/src/routes/workspaces/sessions.ts +218 -0
- package/templates/apps/api/src/server.ts +307 -7
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +489 -0
- package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +475 -0
- package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +132 -0
- package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +65 -0
- package/templates/apps/api/src/services/__tests__/consent.test.ts +282 -0
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +523 -0
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +359 -0
- package/templates/apps/api/src/services/__tests__/entitlements.test.ts +142 -0
- package/templates/apps/api/src/services/__tests__/flow-aggregate.test.ts +425 -0
- package/templates/apps/api/src/services/__tests__/flow-engine.test.ts +2840 -0
- package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +393 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +8 -8
- package/templates/apps/api/src/services/__tests__/listing-csv-sweep.test.ts +560 -0
- package/templates/apps/api/src/services/__tests__/listing-promotion.test.ts +684 -0
- package/templates/apps/api/src/services/__tests__/playbook-compile.test.ts +406 -0
- package/templates/apps/api/src/services/__tests__/playbook-render.test.ts +290 -0
- package/templates/apps/api/src/services/__tests__/project-listing-decision.test.ts +736 -0
- package/templates/apps/api/src/services/__tests__/project-listing-flow.test.ts +475 -0
- package/templates/apps/api/src/services/__tests__/project-listing-issue.test.ts +340 -0
- package/templates/apps/api/src/services/__tests__/recommender-capture.test.ts +983 -0
- package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +278 -0
- package/templates/apps/api/src/services/__tests__/tenant-context-cascade.test.ts +71 -0
- package/templates/apps/api/src/services/__tests__/tenant-context.test.ts +379 -0
- package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +941 -0
- package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +588 -0
- package/templates/apps/api/src/services/__tests__/usage-metering.test.ts +768 -0
- package/templates/apps/api/src/services/__tests__/waitlist-dashboard.test.ts +1314 -0
- package/templates/apps/api/src/services/__tests__/waitlist-experiments.test.ts +341 -0
- package/templates/apps/api/src/services/__tests__/waitlist-followup.test.ts +567 -0
- package/templates/apps/api/src/services/__tests__/waitlist-scoring.test.ts +474 -0
- package/templates/apps/api/src/services/__tests__/waitlist-signups.test.ts +354 -0
- package/templates/apps/api/src/services/abandon-email.ts +307 -0
- package/templates/apps/api/src/services/aeo-score.ts +288 -0
- package/templates/apps/api/src/services/answer-distributions.ts +138 -0
- package/templates/apps/api/src/services/consent.ts +236 -0
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +523 -0
- package/templates/apps/api/src/services/entitlements.ts +102 -0
- package/templates/apps/api/src/services/flow-aggregate.ts +232 -0
- package/templates/apps/api/src/services/flow-checkouts.ts +123 -0
- package/templates/apps/api/src/services/flow-engine.ts +1296 -0
- package/templates/apps/api/src/services/lead-promotion.ts +176 -0
- package/templates/apps/api/src/services/lead-routing.ts +3 -3
- package/templates/apps/api/src/services/listing-config.ts +102 -0
- package/templates/apps/api/src/services/listing-csv-sweep.ts +455 -0
- package/templates/apps/api/src/services/listing-promotion.ts +342 -0
- package/templates/apps/api/src/services/playbook-compile.ts +398 -0
- package/templates/apps/api/src/services/playbook-render.ts +263 -0
- package/templates/apps/api/src/services/project-listing-decision.ts +510 -0
- package/templates/apps/api/src/services/project-listing-flow.ts +426 -0
- package/templates/apps/api/src/services/project-listing-issue.ts +251 -0
- package/templates/apps/api/src/services/project-listings.ts +1472 -0
- package/templates/apps/api/src/services/recommender-capture.ts +835 -0
- package/templates/apps/api/src/services/scheduling/cal-provider.ts +392 -0
- package/templates/apps/api/src/services/scheduling/index.ts +63 -0
- package/templates/apps/api/src/services/scheduling/types.ts +88 -0
- package/templates/apps/api/src/services/slack-notify.ts +240 -0
- package/templates/apps/api/src/services/tenant-context.ts +451 -0
- package/templates/apps/api/src/services/usage-aggregation.ts +516 -0
- package/templates/apps/api/src/services/usage-credits.ts +340 -0
- package/templates/apps/api/src/services/usage-metering.ts +699 -0
- package/templates/apps/api/src/services/waitlist-dashboard.ts +947 -0
- package/templates/apps/api/src/services/waitlist-experiments.ts +213 -0
- package/templates/apps/api/src/services/waitlist-followup.ts +486 -0
- package/templates/apps/api/src/services/waitlist-scoring.ts +166 -0
- package/templates/apps/api/src/services/waitlist-signups.ts +165 -0
- package/templates/apps/api/src/vercel-handler.ts +165 -0
- package/templates/apps/api/tsconfig.json +0 -12
- package/templates/apps/mcp/CLAUDE.md +19 -9
- package/templates/apps/mcp/LICENSE +201 -0
- package/templates/apps/mcp/__tests__/create_page.test.ts +1 -0
- package/templates/apps/mcp/__tests__/delete_page.test.ts +1 -0
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +105 -0
- package/templates/apps/mcp/__tests__/parity.test.ts +70 -6
- package/templates/apps/mcp/__tests__/request_callback.test.ts +4 -4
- package/templates/apps/mcp/__tests__/schedule_tools.test.ts +242 -0
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +4 -4
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +4 -4
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +47 -0
- package/templates/apps/mcp/__tests__/update_page.test.ts +1 -0
- package/templates/apps/mcp/package.json +6 -4
- package/templates/apps/mcp/src/config/modules.ts +37 -0
- package/templates/apps/mcp/src/server.ts +109 -18
- package/templates/apps/mcp/src/tools/capture_lead.ts +1 -1
- package/templates/apps/mcp/src/tools/create_booking.ts +58 -0
- package/templates/apps/mcp/src/tools/create_page.ts +1 -0
- package/templates/apps/mcp/src/tools/delete_page.ts +1 -0
- package/templates/apps/mcp/src/tools/get_event_meta.ts +55 -0
- package/templates/apps/mcp/src/tools/get_flow.ts +61 -0
- package/templates/apps/mcp/src/tools/index.ts +25 -0
- package/templates/apps/mcp/src/tools/list_availability.ts +67 -0
- package/templates/apps/mcp/src/tools/purchase.ts +3 -0
- package/templates/apps/mcp/src/tools/submit_flow_step.ts +83 -0
- package/templates/apps/mcp/src/tools/update_page.ts +1 -0
- package/templates/apps/mcp/tsconfig.json +1 -9
- package/templates/apps/web/.env.example +44 -0
- package/templates/apps/web/CLAUDE.md +28 -0
- package/templates/apps/web/LICENSE +201 -0
- package/templates/apps/web/__tests__/__mocks__/code-highlight.jest-stub.ts +24 -0
- package/templates/apps/web/__tests__/__mocks__/next-intl-server.ts +33 -0
- package/templates/apps/web/__tests__/__mocks__/next-intl.ts +18 -0
- package/templates/apps/web/__tests__/__mocks__/server-only.ts +13 -0
- package/templates/apps/web/__tests__/__mocks__/style-mock.js +4 -0
- package/templates/apps/web/__tests__/__mocks__/vercel-analytics-server.ts +9 -0
- package/templates/apps/web/__tests__/jest-support/import-meta-transformer.cjs +90 -0
- package/templates/apps/web/__tests__/setup.ts +22 -32
- package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +6 -3
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +8 -2
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +260 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +263 -0
- package/templates/apps/web/app/[locale]/(authed)/account/sign-out-button.tsx +39 -0
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +54 -0
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +96 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/page.tsx +309 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/signups/[leadId]/page.tsx +149 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/comparison.test.tsx +273 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/gate.test.tsx +172 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/list.test.tsx +171 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/signup.test.tsx +179 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ExperimentsTable.tsx +116 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ForbiddenState.tsx +24 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/OfferFunnelTable.tsx +66 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/RollupTicker.tsx +61 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ScoreTrace.tsx +114 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx +139 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx +85 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx +67 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/format.ts +111 -0
- package/templates/apps/web/app/[locale]/(authed)/waitlist/page.tsx +179 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +10 -1
- package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +6 -1
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/careers/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/case-studies/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/clients/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +21 -1
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +188 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +242 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +29 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/intake-analytics.test.ts +51 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +39 -15
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +21 -3
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +49 -0
- package/templates/apps/web/app/[locale]/contact/intake-script.ts +66 -0
- package/templates/apps/web/app/[locale]/contact/page.tsx +14 -4
- package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/courses/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +1 -0
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/downloads/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +12 -2
- package/templates/apps/web/app/[locale]/events/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/faq/page.tsx +10 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +265 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +445 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +341 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/checkout.actions.test.ts +287 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/flow.actions.test.ts +302 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/two-route-tool.test.tsx +128 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/checkout.actions.ts +254 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +144 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/page.tsx +108 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx +532 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsEmailStep.tsx +121 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/ResultsClient.checkout.test.tsx +457 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/page.test.tsx +396 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx +114 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/start/page.tsx +52 -0
- package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/integrations/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/launch-service/page.tsx +14 -1
- package/templates/apps/web/app/[locale]/layout.tsx +127 -16
- package/templates/apps/web/app/[locale]/page.tsx +10 -1
- package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/partners/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/products/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +10 -0
- package/templates/apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx +110 -0
- package/templates/apps/web/app/[locale]/projects/apply/__tests__/ListingApplicationClient.test.tsx +96 -0
- package/templates/apps/web/app/[locale]/projects/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +12 -2
- package/templates/apps/web/app/[locale]/resources/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/schedule/__tests__/page.test.tsx +117 -0
- package/templates/apps/web/app/[locale]/schedule/confirmed/__tests__/page.test.tsx +96 -0
- package/templates/apps/web/app/[locale]/schedule/confirmed/page.tsx +92 -0
- package/templates/apps/web/app/[locale]/schedule/page.tsx +82 -0
- package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
- package/templates/apps/web/app/[locale]/services/page.tsx +9 -1
- package/templates/apps/web/app/[locale]/sign-in/__tests__/next-path.test.ts +31 -0
- package/templates/apps/web/app/[locale]/sign-in/__tests__/page.test.tsx +152 -0
- package/templates/apps/web/app/[locale]/sign-in/next-path.ts +0 -0
- package/templates/apps/web/app/[locale]/sign-in/page.tsx +83 -0
- package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +123 -0
- package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/testimonials/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/page.test.tsx +93 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/page.tsx +48 -0
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/use-cases/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/globals.css +35 -0
- package/templates/apps/web/app/llms.txt/route.ts +2 -1
- package/templates/apps/web/app/og/route.tsx +10 -2
- package/templates/apps/web/auth.ts +8 -0
- package/templates/apps/web/components/sign-out-trigger.tsx +42 -0
- package/templates/apps/web/content/en/blog/README.txt +25 -0
- package/templates/apps/web/content/en/docs/index.mdx +28 -0
- package/templates/apps/web/jest.config.cjs +90 -27
- package/templates/apps/web/lib/__tests__/site-brand.test.ts +119 -0
- package/templates/apps/web/lib/__tests__/site-theme.test.ts +112 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +499 -0
- package/templates/apps/web/lib/account-config.ts +13 -0
- package/templates/apps/web/lib/server-api.ts +85 -0
- package/templates/apps/web/lib/site-brand.tsx +121 -0
- package/templates/apps/web/lib/site-theme.ts +74 -0
- package/templates/apps/web/messages/en.json +275 -7
- package/templates/apps/web/middleware.ts +11 -3
- package/templates/apps/web/next.config.mjs +8 -2
- package/templates/apps/web/package.json +17 -7
- package/templates/apps/web/postcss.config.mjs +23 -0
- package/templates/apps/web/public/.well-known/security.txt +3 -3
- package/templates/apps/web/src/lib/routes.ts +15 -2
- package/templates/apps/web/tsconfig.json +1 -16
- package/templates/content/_site.mdx +36 -25
- package/templates/content/en/AboutPage/about.mdx +24 -14
- package/templates/content/en/ContactPage/contact.mdx +23 -14
- package/templates/content/en/FAQPage/faq.mdx +10 -392
- package/templates/content/en/HomePage/home.mdx +14 -285
- package/templates/database/CHANGELOG.md +443 -0
- package/templates/database/LICENSE +201 -0
- package/templates/database/README.md +3 -1
- package/templates/database/__tests__/flows-listing-diagnostic.test.ts +392 -0
- package/templates/database/__tests__/flows-presets.test.ts +173 -0
- package/templates/database/__tests__/prefixed-ids.db.test.ts +146 -0
- package/templates/database/__tests__/seed.test.ts +88 -0
- package/templates/database/__tests__/user-cascade.test.ts +19 -4
- package/templates/database/auth/schema.prisma +521 -0
- package/templates/database/config/schema.prisma +234 -0
- package/templates/database/content/schema.prisma +263 -0
- package/templates/database/flows/listing-diagnostic.ts +182 -0
- package/templates/database/flows/presets.ts +315 -0
- package/templates/database/inbox/__tests__/schema.test.ts +4 -0
- package/templates/database/inbox/schema.prisma +574 -3
- package/templates/database/jest.config.cjs +8 -0
- package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +201 -0
- package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +67 -0
- package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +46 -0
- package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +25 -0
- package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +49 -0
- package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +197 -0
- package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +32 -0
- package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +22 -0
- package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +151 -0
- package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +223 -0
- package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +22 -0
- package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +32 -0
- package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +40 -0
- package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +4 -0
- package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +2 -0
- package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +2 -0
- package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +29 -0
- package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +6 -0
- package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +39 -0
- package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +24 -0
- package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +3 -0
- package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +33 -0
- package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +30 -0
- package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +47 -0
- package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +16 -0
- package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +47 -0
- package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +10 -0
- package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +26 -0
- package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +90 -0
- package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +174 -0
- package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +14 -0
- package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +25 -0
- package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +32 -0
- package/templates/database/migrations/20260911180000_consent_grants/migration.sql +71 -0
- package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +30 -0
- package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +49 -0
- package/templates/database/ops/schema.prisma +27 -0
- package/templates/database/package.json +42 -4
- package/templates/database/prisma.config.ts +1 -1
- package/templates/database/schema.prisma +19 -435
- package/templates/database/seed-test.ts +14 -4
- package/templates/database/seed.ts +148 -0
- package/templates/database/tenancy.ts +45 -0
- package/templates/database/tsconfig.flows.json +15 -0
- package/templates/database/tsconfig.json +7 -1
- package/templates/database/tsconfig.tenancy.json +14 -0
- package/templates/package.json +30 -55
- package/templates/pnpm-workspace.yaml +0 -3
- package/templates/project.yaml +1 -1
- package/templates/tsconfig.json +1 -37
- package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +0 -94
- package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +0 -75
- package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +0 -82
- package/templates/apps/web/__tests__/auth/env-helpers.test.ts +0 -168
- package/templates/apps/web/__tests__/authority-list-routes.test.tsx +0 -208
- package/templates/apps/web/__tests__/better-stack.test.ts +0 -66
- package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +0 -87
- package/templates/apps/web/__tests__/blog-source-populated.test.ts +0 -130
- package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +0 -60
- package/templates/apps/web/__tests__/google-analytics.test.tsx +0 -104
- package/templates/apps/web/__tests__/i18n/middleware.test.ts +0 -119
- package/templates/apps/web/__tests__/i18n/routing.test.ts +0 -114
- package/templates/apps/web/__tests__/i18n/translations.test.ts +0 -191
- package/templates/apps/web/__tests__/json-ld.test.ts +0 -98
- package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +0 -580
- package/templates/apps/web/__tests__/layout-stealth.test.ts +0 -39
- package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +0 -103
- package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +0 -114
- package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +0 -94
- package/templates/apps/web/__tests__/page.test.tsx +0 -230
- package/templates/apps/web/__tests__/products-services-phase1.test.tsx +0 -321
- package/templates/apps/web/__tests__/projects-routes.test.tsx +0 -392
- package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +0 -475
- package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +0 -53
- package/templates/apps/web/__tests__/routes/blog-route.test.tsx +0 -191
- package/templates/apps/web/__tests__/routes/llms-txt.test.ts +0 -123
- package/templates/apps/web/__tests__/routes/robots-txt.test.ts +0 -52
- package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +0 -78
- package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +0 -203
- package/templates/apps/web/__tests__/section-routes.test.tsx +0 -693
- package/templates/apps/web/__tests__/security-headers.test.ts +0 -201
- package/templates/apps/web/__tests__/sentry-config.test.ts +0 -116
- package/templates/apps/web/__tests__/sitemap-locales.test.ts +0 -415
- package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +0 -844
- package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +0 -120
- package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +0 -202
- package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +0 -152
- package/templates/apps/web/content/en/blog/index.mdx +0 -15
- package/templates/apps/web/content/en/blog/launching-ailk.mdx +0 -20
- package/templates/apps/web/content/en/docs/getting-started.mdx +0 -30
- package/templates/content/.gitkeep +0 -0
- package/templates/content/CLAUDE.md +0 -85
- package/templates/content/ar/HomePage/home.mdx +0 -123
- package/templates/content/ar/_site.mdx +0 -35
- package/templates/content/de/_site.mdx +0 -29
- package/templates/content/en/.gitkeep +0 -0
- package/templates/content/en/AboutPage/about.schema.json +0 -82
- package/templates/content/en/BookCall/book-call.mdx +0 -19
- package/templates/content/en/BookCall/book-call.schema.json +0 -121
- package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +0 -20
- package/templates/content/en/CareersList/careers.mdx +0 -24
- package/templates/content/en/CaseStudiesList/case-studies.mdx +0 -22
- package/templates/content/en/CaseStudiesList/showcase.mdx +0 -8
- package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +0 -32
- package/templates/content/en/CaseStudy/schema-builder-migration.mdx +0 -41
- package/templates/content/en/ClientsList/clients.mdx +0 -38
- package/templates/content/en/ContactPage/contact.schema.json +0 -100
- package/templates/content/en/ContactPoint/primary.mdx +0 -14
- package/templates/content/en/Course/aeo-fundamentals.mdx +0 -37
- package/templates/content/en/Course/schema-builder-workshop.mdx +0 -62
- package/templates/content/en/CoursesList/courses.mdx +0 -22
- package/templates/content/en/DownloadsList/downloads.mdx +0 -22
- package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +0 -39
- package/templates/content/en/Event/ailk-launch-day-2026.mdx +0 -35
- package/templates/content/en/EventsList/events.mdx +0 -26
- package/templates/content/en/FAQPage/faq.schema.json +0 -231
- package/templates/content/en/GlossaryList/glossary.mdx +0 -19
- package/templates/content/en/GlossaryList/glossary.schema.json +0 -300
- package/templates/content/en/HomePage/home.schema.json +0 -88
- package/templates/content/en/HomePage/launch-service.mdx +0 -475
- package/templates/content/en/HomePage/launch-service.schema.json +0 -138
- package/templates/content/en/HowTo/add-mdx-content.mdx +0 -38
- package/templates/content/en/HowTo/configure-aeo-scoring.mdx +0 -35
- package/templates/content/en/HowTo/set-up-json-ld.mdx +0 -36
- package/templates/content/en/Integration/github-actions.mdx +0 -31
- package/templates/content/en/Integration/openai-api.mdx +0 -26
- package/templates/content/en/Integration/vercel.mdx +0 -32
- package/templates/content/en/IntegrationsList/integrations.mdx +0 -22
- package/templates/content/en/JobPosting/content-strategist.mdx +0 -46
- package/templates/content/en/JobPosting/developer-advocate.mdx +0 -47
- package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +0 -57
- package/templates/content/en/LandingPage/aeo-audit.mdx +0 -19
- package/templates/content/en/LandingPage/aeo-audit.schema.json +0 -92
- package/templates/content/en/LandingPage/agency-waitlist.mdx +0 -340
- package/templates/content/en/LandingPage/agency-waitlist.schema.json +0 -152
- package/templates/content/en/LandingPage/developers.mdx +0 -19
- package/templates/content/en/LandingPage/developers.schema.json +0 -109
- package/templates/content/en/LandingPage/for-agencies.mdx +0 -390
- package/templates/content/en/LandingPage/for-agencies.schema.json +0 -107
- package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +0 -417
- package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +0 -105
- package/templates/content/en/LandingPage/for-businesses.mdx +0 -19
- package/templates/content/en/LandingPage/for-businesses.schema.json +0 -96
- package/templates/content/en/LandingPage/platform.mdx +0 -369
- package/templates/content/en/LandingPage/platform.schema.json +0 -166
- package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +0 -19
- package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +0 -102
- package/templates/content/en/LandingPage/vs-wordpress.mdx +0 -19
- package/templates/content/en/LandingPage/vs-wordpress.schema.json +0 -53
- package/templates/content/en/NewsletterSignup/newsletter.mdx +0 -236
- package/templates/content/en/NewsletterSignup/newsletter.schema.json +0 -91
- package/templates/content/en/Organization/site-owner.mdx +0 -16
- package/templates/content/en/Partner/prisma.mdx +0 -31
- package/templates/content/en/Partner/supabase.mdx +0 -30
- package/templates/content/en/Partner/vercel.mdx +0 -28
- package/templates/content/en/PartnersList/partners.mdx +0 -22
- package/templates/content/en/Person/founder.mdx +0 -18
- package/templates/content/en/Pricing/pricing.mdx +0 -538
- package/templates/content/en/Pricing/pricing.schema.json +0 -209
- package/templates/content/en/PrivacyPage/privacy.mdx +0 -165
- package/templates/content/en/PrivacyPage/privacy.schema.json +0 -64
- package/templates/content/en/Product/ailk.mdx +0 -19
- package/templates/content/en/Product/ailk.schema.json +0 -94
- package/templates/content/en/Product/api-launch-kit.mdx +0 -26
- package/templates/content/en/Product/launch-kit.mdx +0 -28
- package/templates/content/en/ProductsList/products.mdx +0 -26
- package/templates/content/en/Project/ailk-phase-2.mdx +0 -54
- package/templates/content/en/ProjectsList/projects.mdx +0 -25
- package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +0 -27
- package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +0 -28
- package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +0 -39
- package/templates/content/en/ResourcesHub/resources.mdx +0 -22
- package/templates/content/en/Service/consulting.mdx +0 -22
- package/templates/content/en/Service/implementation.mdx +0 -30
- package/templates/content/en/Service/launch-service.mdx +0 -232
- package/templates/content/en/Service/launch.mdx +0 -228
- package/templates/content/en/ServicesList/services.mdx +0 -84
- package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +0 -44
- package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +0 -47
- package/templates/content/en/SoftwareProduct/ailk-schema.mdx +0 -49
- package/templates/content/en/TeamList/team.mdx +0 -63
- package/templates/content/en/TeamMember/founder.mdx +0 -72
- package/templates/content/en/TermsPage/terms.mdx +0 -19
- package/templates/content/en/TermsPage/terms.schema.json +0 -99
- package/templates/content/en/TestimonialsList/testimonials.mdx +0 -44
- package/templates/content/en/UseCasesList/use-cases.mdx +0 -30
- package/templates/content/en/Whitepaper/ax-first-product-development.mdx +0 -27
- package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +0 -27
- package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +0 -31
- package/templates/content/en-XA/AboutPage/about.mdx +0 -8
- package/templates/content/en-XA/FAQPage/faq.mdx +0 -8
- package/templates/content/en-XA/HomePage/home.mdx +0 -8
- package/templates/content/es/_site.mdx +0 -30
- package/templates/content/fr/_site.mdx +0 -30
- package/templates/content/ja/_site.mdx +0 -30
- package/templates/content/pt-BR/AboutPage/about.mdx +0 -8
- package/templates/content/pt-BR/FAQPage/faq.mdx +0 -8
- package/templates/content/pt-BR/HomePage/home.mdx +0 -23
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
-- CreateEnum
|
|
2
|
+
CREATE TYPE "Role" AS ENUM ('owner', 'admin', 'member');
|
|
3
|
+
|
|
4
|
+
-- AlterTable
|
|
5
|
+
ALTER TABLE "sessions" ADD COLUMN "active_organization_id" TEXT,
|
|
6
|
+
ADD COLUMN "active_workspace_id" TEXT;
|
|
7
|
+
|
|
8
|
+
-- CreateTable
|
|
9
|
+
CREATE TABLE "organizations" (
|
|
10
|
+
"id" TEXT NOT NULL,
|
|
11
|
+
"name" TEXT NOT NULL,
|
|
12
|
+
"slug" TEXT NOT NULL,
|
|
13
|
+
"logo" TEXT,
|
|
14
|
+
"metadata" TEXT,
|
|
15
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
17
|
+
|
|
18
|
+
CONSTRAINT "organizations_pkey" PRIMARY KEY ("id")
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
-- CreateTable
|
|
22
|
+
CREATE TABLE "workspaces" (
|
|
23
|
+
"id" TEXT NOT NULL,
|
|
24
|
+
"organization_id" TEXT NOT NULL,
|
|
25
|
+
"name" TEXT NOT NULL,
|
|
26
|
+
"slug" TEXT NOT NULL,
|
|
27
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
29
|
+
|
|
30
|
+
CONSTRAINT "workspaces_pkey" PRIMARY KEY ("id")
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
-- CreateTable
|
|
34
|
+
CREATE TABLE "memberships" (
|
|
35
|
+
"id" TEXT NOT NULL,
|
|
36
|
+
"organization_id" TEXT NOT NULL,
|
|
37
|
+
"user_id" TEXT NOT NULL,
|
|
38
|
+
"role" "Role" NOT NULL DEFAULT 'member',
|
|
39
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
40
|
+
|
|
41
|
+
CONSTRAINT "memberships_pkey" PRIMARY KEY ("id")
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- CreateTable
|
|
45
|
+
CREATE TABLE "invitations" (
|
|
46
|
+
"id" TEXT NOT NULL,
|
|
47
|
+
"organization_id" TEXT NOT NULL,
|
|
48
|
+
"email" TEXT NOT NULL,
|
|
49
|
+
"role" "Role" NOT NULL DEFAULT 'member',
|
|
50
|
+
"status" TEXT NOT NULL DEFAULT 'pending',
|
|
51
|
+
"expires_at" TIMESTAMP(3),
|
|
52
|
+
"inviter_id" TEXT NOT NULL,
|
|
53
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
54
|
+
|
|
55
|
+
CONSTRAINT "invitations_pkey" PRIMARY KEY ("id")
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
-- CreateTable
|
|
59
|
+
CREATE TABLE "agent_sessions" (
|
|
60
|
+
"id" TEXT NOT NULL,
|
|
61
|
+
"workspace_id" TEXT NOT NULL,
|
|
62
|
+
"title" TEXT,
|
|
63
|
+
"status" TEXT NOT NULL DEFAULT 'idle',
|
|
64
|
+
"last_seq" INTEGER NOT NULL DEFAULT 0,
|
|
65
|
+
"last_message_at" TIMESTAMP(3),
|
|
66
|
+
"draft_message" TEXT,
|
|
67
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
68
|
+
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
69
|
+
|
|
70
|
+
CONSTRAINT "agent_sessions_pkey" PRIMARY KEY ("id")
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
-- CreateTable
|
|
74
|
+
CREATE TABLE "conversation_events" (
|
|
75
|
+
"id" TEXT NOT NULL,
|
|
76
|
+
"session_id" TEXT NOT NULL,
|
|
77
|
+
"workspace_id" TEXT NOT NULL,
|
|
78
|
+
"agent_id" TEXT NOT NULL,
|
|
79
|
+
"seq" INTEGER NOT NULL,
|
|
80
|
+
"type" TEXT NOT NULL,
|
|
81
|
+
"turn_id" TEXT,
|
|
82
|
+
"payload" JSONB NOT NULL,
|
|
83
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
84
|
+
|
|
85
|
+
CONSTRAINT "conversation_events_pkey" PRIMARY KEY ("id")
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
-- CreateTable
|
|
89
|
+
CREATE TABLE "session_read_receipts" (
|
|
90
|
+
"id" TEXT NOT NULL,
|
|
91
|
+
"session_id" TEXT NOT NULL,
|
|
92
|
+
"workspace_id" TEXT NOT NULL,
|
|
93
|
+
"user_id" TEXT NOT NULL,
|
|
94
|
+
"last_read_seq" INTEGER NOT NULL DEFAULT 0,
|
|
95
|
+
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
96
|
+
|
|
97
|
+
CONSTRAINT "session_read_receipts_pkey" PRIMARY KEY ("id")
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
-- CreateTable
|
|
101
|
+
CREATE TABLE "artifacts" (
|
|
102
|
+
"id" TEXT NOT NULL,
|
|
103
|
+
"session_id" TEXT NOT NULL,
|
|
104
|
+
"workspace_id" TEXT NOT NULL,
|
|
105
|
+
"type" TEXT NOT NULL DEFAULT 'text/document',
|
|
106
|
+
"title" TEXT NOT NULL,
|
|
107
|
+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
108
|
+
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
109
|
+
|
|
110
|
+
CONSTRAINT "artifacts_pkey" PRIMARY KEY ("id")
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
-- CreateTable
|
|
114
|
+
CREATE TABLE "artifact_versions" (
|
|
115
|
+
"id" TEXT NOT NULL,
|
|
116
|
+
"artifact_id" TEXT NOT NULL,
|
|
117
|
+
"workspace_id" TEXT NOT NULL,
|
|
118
|
+
"content" JSONB NOT NULL,
|
|
119
|
+
"is_current" BOOLEAN NOT NULL DEFAULT true,
|
|
120
|
+
"saved_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
121
|
+
|
|
122
|
+
CONSTRAINT "artifact_versions_pkey" PRIMARY KEY ("id")
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
-- CreateIndex
|
|
126
|
+
CREATE UNIQUE INDEX "organizations_slug_key" ON "organizations"("slug");
|
|
127
|
+
|
|
128
|
+
-- CreateIndex
|
|
129
|
+
CREATE INDEX "workspaces_organization_id_idx" ON "workspaces"("organization_id");
|
|
130
|
+
|
|
131
|
+
-- CreateIndex
|
|
132
|
+
CREATE UNIQUE INDEX "workspaces_organization_id_slug_key" ON "workspaces"("organization_id", "slug");
|
|
133
|
+
|
|
134
|
+
-- CreateIndex
|
|
135
|
+
CREATE INDEX "memberships_user_id_idx" ON "memberships"("user_id");
|
|
136
|
+
|
|
137
|
+
-- CreateIndex
|
|
138
|
+
CREATE INDEX "memberships_organization_id_idx" ON "memberships"("organization_id");
|
|
139
|
+
|
|
140
|
+
-- CreateIndex
|
|
141
|
+
CREATE UNIQUE INDEX "memberships_organization_id_user_id_key" ON "memberships"("organization_id", "user_id");
|
|
142
|
+
|
|
143
|
+
-- CreateIndex
|
|
144
|
+
CREATE INDEX "invitations_organization_id_idx" ON "invitations"("organization_id");
|
|
145
|
+
|
|
146
|
+
-- CreateIndex
|
|
147
|
+
CREATE INDEX "invitations_email_idx" ON "invitations"("email");
|
|
148
|
+
|
|
149
|
+
-- CreateIndex
|
|
150
|
+
CREATE INDEX "agent_sessions_workspace_id_last_message_at_idx" ON "agent_sessions"("workspace_id", "last_message_at" DESC);
|
|
151
|
+
|
|
152
|
+
-- CreateIndex
|
|
153
|
+
CREATE INDEX "conversation_events_workspace_id_idx" ON "conversation_events"("workspace_id");
|
|
154
|
+
|
|
155
|
+
-- CreateIndex
|
|
156
|
+
CREATE UNIQUE INDEX "conversation_events_session_id_seq_key" ON "conversation_events"("session_id", "seq");
|
|
157
|
+
|
|
158
|
+
-- CreateIndex
|
|
159
|
+
CREATE INDEX "session_read_receipts_workspace_id_idx" ON "session_read_receipts"("workspace_id");
|
|
160
|
+
|
|
161
|
+
-- CreateIndex
|
|
162
|
+
CREATE UNIQUE INDEX "session_read_receipts_session_id_user_id_key" ON "session_read_receipts"("session_id", "user_id");
|
|
163
|
+
|
|
164
|
+
-- CreateIndex
|
|
165
|
+
CREATE INDEX "artifacts_session_id_idx" ON "artifacts"("session_id");
|
|
166
|
+
|
|
167
|
+
-- CreateIndex
|
|
168
|
+
CREATE INDEX "artifacts_workspace_id_idx" ON "artifacts"("workspace_id");
|
|
169
|
+
|
|
170
|
+
-- CreateIndex
|
|
171
|
+
CREATE INDEX "artifact_versions_artifact_id_saved_at_idx" ON "artifact_versions"("artifact_id", "saved_at" DESC);
|
|
172
|
+
|
|
173
|
+
-- CreateIndex
|
|
174
|
+
CREATE INDEX "artifact_versions_workspace_id_idx" ON "artifact_versions"("workspace_id");
|
|
175
|
+
|
|
176
|
+
-- AddForeignKey
|
|
177
|
+
ALTER TABLE "workspaces" ADD CONSTRAINT "workspaces_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
178
|
+
|
|
179
|
+
-- AddForeignKey
|
|
180
|
+
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
181
|
+
|
|
182
|
+
-- AddForeignKey
|
|
183
|
+
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
184
|
+
|
|
185
|
+
-- AddForeignKey
|
|
186
|
+
ALTER TABLE "invitations" ADD CONSTRAINT "invitations_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
187
|
+
|
|
188
|
+
-- AddForeignKey
|
|
189
|
+
ALTER TABLE "invitations" ADD CONSTRAINT "invitations_inviter_id_fkey" FOREIGN KEY ("inviter_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
190
|
+
|
|
191
|
+
-- AddForeignKey
|
|
192
|
+
ALTER TABLE "conversation_events" ADD CONSTRAINT "conversation_events_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "agent_sessions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
193
|
+
|
|
194
|
+
-- AddForeignKey
|
|
195
|
+
ALTER TABLE "session_read_receipts" ADD CONSTRAINT "session_read_receipts_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "agent_sessions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
196
|
+
|
|
197
|
+
-- AddForeignKey
|
|
198
|
+
ALTER TABLE "artifacts" ADD CONSTRAINT "artifacts_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "agent_sessions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
199
|
+
|
|
200
|
+
-- AddForeignKey
|
|
201
|
+
ALTER TABLE "artifact_versions" ADD CONSTRAINT "artifact_versions_artifact_id_fkey" FOREIGN KEY ("artifact_id") REFERENCES "artifacts"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Warnings:
|
|
3
|
+
|
|
4
|
+
- You are about to drop the `tenant_seos` table. If the table is not empty, all the data it contains will be lost.
|
|
5
|
+
- You are about to drop the `tenant_site_identities` table. If the table is not empty, all the data it contains will be lost.
|
|
6
|
+
- You are about to drop the `tenant_themes` table. If the table is not empty, all the data it contains will be lost.
|
|
7
|
+
|
|
8
|
+
*/
|
|
9
|
+
-- DropForeignKey
|
|
10
|
+
ALTER TABLE "tenant_seos" DROP CONSTRAINT "tenant_seos_user_id_fkey";
|
|
11
|
+
|
|
12
|
+
-- DropForeignKey
|
|
13
|
+
ALTER TABLE "tenant_site_identities" DROP CONSTRAINT "tenant_site_identities_user_id_fkey";
|
|
14
|
+
|
|
15
|
+
-- DropForeignKey
|
|
16
|
+
ALTER TABLE "tenant_themes" DROP CONSTRAINT "tenant_themes_user_id_fkey";
|
|
17
|
+
|
|
18
|
+
-- DropTable
|
|
19
|
+
DROP TABLE "tenant_seos";
|
|
20
|
+
|
|
21
|
+
-- DropTable
|
|
22
|
+
DROP TABLE "tenant_site_identities";
|
|
23
|
+
|
|
24
|
+
-- DropTable
|
|
25
|
+
DROP TABLE "tenant_themes";
|
|
26
|
+
|
|
27
|
+
-- CreateTable
|
|
28
|
+
CREATE TABLE "workspace_themes" (
|
|
29
|
+
"id" TEXT NOT NULL,
|
|
30
|
+
"workspace_id" TEXT NOT NULL,
|
|
31
|
+
"data" JSONB NOT NULL,
|
|
32
|
+
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
33
|
+
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
34
|
+
|
|
35
|
+
CONSTRAINT "workspace_themes_pkey" PRIMARY KEY ("id")
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
-- CreateTable
|
|
39
|
+
CREATE TABLE "workspace_site_identities" (
|
|
40
|
+
"id" TEXT NOT NULL,
|
|
41
|
+
"workspace_id" TEXT NOT NULL,
|
|
42
|
+
"data" JSONB NOT NULL,
|
|
43
|
+
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
44
|
+
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
45
|
+
|
|
46
|
+
CONSTRAINT "workspace_site_identities_pkey" PRIMARY KEY ("id")
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
-- CreateTable
|
|
50
|
+
CREATE TABLE "workspace_seos" (
|
|
51
|
+
"id" TEXT NOT NULL,
|
|
52
|
+
"workspace_id" TEXT NOT NULL,
|
|
53
|
+
"data" JSONB NOT NULL,
|
|
54
|
+
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
55
|
+
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
56
|
+
|
|
57
|
+
CONSTRAINT "workspace_seos_pkey" PRIMARY KEY ("id")
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
-- CreateIndex
|
|
61
|
+
CREATE UNIQUE INDEX "workspace_themes_workspace_id_key" ON "workspace_themes"("workspace_id");
|
|
62
|
+
|
|
63
|
+
-- CreateIndex
|
|
64
|
+
CREATE UNIQUE INDEX "workspace_site_identities_workspace_id_key" ON "workspace_site_identities"("workspace_id");
|
|
65
|
+
|
|
66
|
+
-- CreateIndex
|
|
67
|
+
CREATE UNIQUE INDEX "workspace_seos_workspace_id_key" ON "workspace_seos"("workspace_id");
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
-- Add audit_logs table (ops namespace) — workspace-scoped "who did what,
|
|
2
|
+
-- when" audit trail.
|
|
3
|
+
--
|
|
4
|
+
-- The ops namespace header already declares an "audit log" as part of its
|
|
5
|
+
-- intent; this fills it. Zero-data, pre-launch addition — no backfill.
|
|
6
|
+
--
|
|
7
|
+
-- Columns:
|
|
8
|
+
-- id — CUID primary key
|
|
9
|
+
-- workspace_id — tenant scope (stable-id ref, no FK — ADR-0009 D2)
|
|
10
|
+
-- actor_id — who acted (a User / agent / system id) — stable-id ref
|
|
11
|
+
-- actor_type — "user" | "agent" | "system"
|
|
12
|
+
-- action — e.g. "workspace.settings.updated", "lead.deleted"
|
|
13
|
+
-- target_type — what was acted on: "workspace" | "lead" | "user" | … (nullable)
|
|
14
|
+
-- target_id — stable-id ref to the target (nullable)
|
|
15
|
+
-- metadata — structured detail (before/after, request context)
|
|
16
|
+
-- created_at — server-side record time (default now())
|
|
17
|
+
--
|
|
18
|
+
-- Indexes:
|
|
19
|
+
-- (workspace_id, created_at DESC) — "recent activity for this workspace" queries
|
|
20
|
+
-- (workspace_id, target_type, target_id) — "history for this target" queries
|
|
21
|
+
--
|
|
22
|
+
-- Rollback:
|
|
23
|
+
-- DROP INDEX "audit_logs_workspace_id_target_type_target_id_idx";
|
|
24
|
+
-- DROP INDEX "audit_logs_workspace_id_created_at_idx";
|
|
25
|
+
-- DROP TABLE "audit_logs";
|
|
26
|
+
|
|
27
|
+
-- CreateTable
|
|
28
|
+
CREATE TABLE "audit_logs" (
|
|
29
|
+
"id" TEXT NOT NULL,
|
|
30
|
+
"workspace_id" TEXT NOT NULL,
|
|
31
|
+
"actor_id" TEXT NOT NULL,
|
|
32
|
+
"actor_type" TEXT NOT NULL,
|
|
33
|
+
"action" TEXT NOT NULL,
|
|
34
|
+
"target_type" TEXT,
|
|
35
|
+
"target_id" TEXT,
|
|
36
|
+
"metadata" JSONB,
|
|
37
|
+
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
38
|
+
|
|
39
|
+
CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id")
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
-- CreateIndex
|
|
43
|
+
CREATE INDEX "audit_logs_workspace_id_created_at_idx" ON "audit_logs"("workspace_id", "created_at" DESC);
|
|
44
|
+
|
|
45
|
+
-- CreateIndex
|
|
46
|
+
CREATE INDEX "audit_logs_workspace_id_target_type_target_id_idx" ON "audit_logs"("workspace_id", "target_type", "target_id");
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Drop telemetry_records — the model moves to apps-paid/license-issuer's own
|
|
2
|
+
-- schema (apps-paid/license-issuer/prisma/schema.prisma).
|
|
3
|
+
--
|
|
4
|
+
-- license-issuer was always the table's sole writer (POST /telemetry, via its
|
|
5
|
+
-- own DATABASE_URL connection, independent of the product database) and
|
|
6
|
+
-- nothing in the product schema ever read it — so it was a vendor-owned
|
|
7
|
+
-- concern living in the wrong schema. Relocating it de-leaks vendor
|
|
8
|
+
-- seat-metering out of the product schema and the create-ailk scaffold: every
|
|
9
|
+
-- OSS/customer database was carrying a dead telemetry_records table that only
|
|
10
|
+
-- this one vendor service ever touched.
|
|
11
|
+
--
|
|
12
|
+
-- Zero data pre-launch: the product database has never had a row in this
|
|
13
|
+
-- table (license-issuer writes to its own vendor database, not this one), so
|
|
14
|
+
-- this drop is a no-op read but formally forward-only per this repo's
|
|
15
|
+
-- migration discipline (history is never rewritten — see the
|
|
16
|
+
-- 20260713143320_reanchor_site_config_to_workspace migration for the
|
|
17
|
+
-- established drop-and-recreate pattern this mirrors).
|
|
18
|
+
--
|
|
19
|
+
-- Rollback: not reversible via a down-migration — the table structure would
|
|
20
|
+
-- need to be re-created via a fresh CreateTable migration (see the original
|
|
21
|
+
-- 20260518000000_add_telemetry_records migration for the exact shape, still
|
|
22
|
+
-- retained in history). No data loss risk: zero rows ever existed here.
|
|
23
|
+
|
|
24
|
+
-- DropTable
|
|
25
|
+
DROP TABLE "telemetry_records";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
-- VETTED pure-SQL UUIDv7 generator — staged in-tree input for the prefixed-UUID
|
|
2
|
+
-- id migration (docs/internal/cloud-prompts/prefixed-uuid-migration-cloud-prompt.md,
|
|
3
|
+
-- rule c). Use this VERBATIM in the first migration; do NOT fetch one (the cloud
|
|
4
|
+
-- run is egress-blocked) and do NOT re-derive the bit math.
|
|
5
|
+
--
|
|
6
|
+
-- Source: Kyle Hubert's community-standard implementation
|
|
7
|
+
-- (https://gist.github.com/kjmph/5bd772b2c2df145aa645b837da7eca74) — the de-facto
|
|
8
|
+
-- pre-Postgres-18 pure-SQL UUIDv7, widely adopted and RFC-9562-validator-passing.
|
|
9
|
+
-- Reproduced here as an in-tree input; the run's property tests are the gate.
|
|
10
|
+
--
|
|
11
|
+
-- How it is correct (RFC 9562 §5.7 layout — 48-bit ms timestamp · ver=7 · rand):
|
|
12
|
+
-- 1. gen_random_uuid() gives a v4 uuid (random bits + a correct variant field in
|
|
13
|
+
-- byte 8, which we LEAVE untouched — so the variant `10xx` is inherited, valid).
|
|
14
|
+
-- 2. overlay(... placing <6 bytes of big-endian Unix-ms> from 1 for 6) replaces
|
|
15
|
+
-- bytes 1..6 with the millisecond timestamp (the time-ordered prefix → index
|
|
16
|
+
-- locality).
|
|
17
|
+
-- 3. The two set_bit calls turn the version nibble from v4 (0100) into v7 (0111):
|
|
18
|
+
-- Postgres bytea set_bit numbers bits LSB-first within each byte, so byte 6's
|
|
19
|
+
-- high (version) nibble is bits 55..52; the v4 base already has bit 54 set
|
|
20
|
+
-- (0100 = 4); setting bits 52 and 53 yields bits 54|53|52 = 0111 = 7.
|
|
21
|
+
--
|
|
22
|
+
-- Property tests the run MUST run against it (rule c / verification):
|
|
23
|
+
-- * version nibble == 7 (the 13th hex char of every generated id is '7')
|
|
24
|
+
-- * RFC-4122 variant (the 17th hex char is one of 8,9,a,b)
|
|
25
|
+
-- * non-decreasing across a millisecond boundary (two ids minted >1ms apart sort
|
|
26
|
+
-- in mint order — the time-ordered guarantee; NOT strict within-ms monotonicity,
|
|
27
|
+
-- which this method does not claim and we do not need)
|
|
28
|
+
-- If any property test fails, that is a STAGING bug to surface to Sam — not a signal
|
|
29
|
+
-- to hand-rewrite the bit math.
|
|
30
|
+
|
|
31
|
+
create or replace function uuidv7() returns uuid
|
|
32
|
+
as $$
|
|
33
|
+
begin
|
|
34
|
+
return encode(
|
|
35
|
+
set_bit(
|
|
36
|
+
set_bit(
|
|
37
|
+
overlay(
|
|
38
|
+
uuid_send(gen_random_uuid())
|
|
39
|
+
placing substring(int8send(floor(extract(epoch from clock_timestamp()) * 1000)::bigint) from 3)
|
|
40
|
+
from 1 for 6
|
|
41
|
+
),
|
|
42
|
+
52, 1
|
|
43
|
+
),
|
|
44
|
+
53, 1
|
|
45
|
+
),
|
|
46
|
+
'hex'
|
|
47
|
+
)::uuid;
|
|
48
|
+
end
|
|
49
|
+
$$ language plpgsql volatile;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
-- Prefixed-UUIDv7 entity ids (ADR-0031).
|
|
2
|
+
--
|
|
3
|
+
-- Every generated primary key becomes `<prefix>_<uuidv7>`, minted IN THE
|
|
4
|
+
-- DATABASE by the uuidv7() function shipped in the previous migration
|
|
5
|
+
-- (20260713192000_add_uuidv7_function) and format-enforced by a CHECK
|
|
6
|
+
-- constraint. Three changes per primary key, in order:
|
|
7
|
+
--
|
|
8
|
+
-- 1. COLLATE "C" — byte-ordering for the ASCII id (correct + faster
|
|
9
|
+
-- than libc locale collation on a managed host).
|
|
10
|
+
-- 2. SET DEFAULT — ('<prefix>_' || uuidv7()::text); covers EVERY insert
|
|
11
|
+
-- path (nested creates, upserts, raw SQL, seeds,
|
|
12
|
+
-- Better Auth with generateId:false).
|
|
13
|
+
-- 3. CHECK — id ~ '^<prefix>_<v7-uuid>$'; the mechanical tier —
|
|
14
|
+
-- a malformed id cannot exist, whatever the caller.
|
|
15
|
+
--
|
|
16
|
+
-- Relation-free scope/id reference columns (the cross-namespace stable-id
|
|
17
|
+
-- refs ADR-0009 leaves without FKs, e.g. workspace_id on config/content
|
|
18
|
+
-- tables) get the same COLLATE "C" + CHECK. The CHECK regex admits the
|
|
19
|
+
-- reserved sentinel range (00000000-0000-7000-8000-…, database/tenancy.ts).
|
|
20
|
+
-- CHECK regexes are kept in sync with @working-theory/ids by
|
|
21
|
+
-- packages/ids/src/__tests__/migration-sync.test.ts.
|
|
22
|
+
|
|
23
|
+
-- ── Primary keys (27 — the full ADR-0031 rule-3 registry) ──
|
|
24
|
+
|
|
25
|
+
-- users: user_
|
|
26
|
+
ALTER TABLE "users" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
27
|
+
ALTER TABLE "users" ALTER COLUMN "id" SET DEFAULT ('user_'::text || (uuidv7())::text);
|
|
28
|
+
ALTER TABLE "users" ADD CONSTRAINT "users_id_format" CHECK ("id" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
29
|
+
|
|
30
|
+
-- organizations: org_
|
|
31
|
+
ALTER TABLE "organizations" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
32
|
+
ALTER TABLE "organizations" ALTER COLUMN "id" SET DEFAULT ('org_'::text || (uuidv7())::text);
|
|
33
|
+
ALTER TABLE "organizations" ADD CONSTRAINT "organizations_id_format" CHECK ("id" ~ '^org_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
34
|
+
|
|
35
|
+
-- workspaces: wksp_
|
|
36
|
+
ALTER TABLE "workspaces" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
37
|
+
ALTER TABLE "workspaces" ALTER COLUMN "id" SET DEFAULT ('wksp_'::text || (uuidv7())::text);
|
|
38
|
+
ALTER TABLE "workspaces" ADD CONSTRAINT "workspaces_id_format" CHECK ("id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
39
|
+
|
|
40
|
+
-- memberships: member_
|
|
41
|
+
ALTER TABLE "memberships" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
42
|
+
ALTER TABLE "memberships" ALTER COLUMN "id" SET DEFAULT ('member_'::text || (uuidv7())::text);
|
|
43
|
+
ALTER TABLE "memberships" ADD CONSTRAINT "memberships_id_format" CHECK ("id" ~ '^member_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
44
|
+
|
|
45
|
+
-- invitations: invite_
|
|
46
|
+
ALTER TABLE "invitations" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
47
|
+
ALTER TABLE "invitations" ALTER COLUMN "id" SET DEFAULT ('invite_'::text || (uuidv7())::text);
|
|
48
|
+
ALTER TABLE "invitations" ADD CONSTRAINT "invitations_id_format" CHECK ("id" ~ '^invite_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
49
|
+
|
|
50
|
+
-- sessions: sess_
|
|
51
|
+
ALTER TABLE "sessions" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
52
|
+
ALTER TABLE "sessions" ALTER COLUMN "id" SET DEFAULT ('sess_'::text || (uuidv7())::text);
|
|
53
|
+
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_id_format" CHECK ("id" ~ '^sess_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
54
|
+
|
|
55
|
+
-- accounts: acct_
|
|
56
|
+
ALTER TABLE "accounts" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
57
|
+
ALTER TABLE "accounts" ALTER COLUMN "id" SET DEFAULT ('acct_'::text || (uuidv7())::text);
|
|
58
|
+
ALTER TABLE "accounts" ADD CONSTRAINT "accounts_id_format" CHECK ("id" ~ '^acct_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
59
|
+
|
|
60
|
+
-- verifications: verify_
|
|
61
|
+
ALTER TABLE "verifications" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
62
|
+
ALTER TABLE "verifications" ALTER COLUMN "id" SET DEFAULT ('verify_'::text || (uuidv7())::text);
|
|
63
|
+
ALTER TABLE "verifications" ADD CONSTRAINT "verifications_id_format" CHECK ("id" ~ '^verify_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
64
|
+
|
|
65
|
+
-- api_tokens: apitok_
|
|
66
|
+
ALTER TABLE "api_tokens" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
67
|
+
ALTER TABLE "api_tokens" ALTER COLUMN "id" SET DEFAULT ('apitok_'::text || (uuidv7())::text);
|
|
68
|
+
ALTER TABLE "api_tokens" ADD CONSTRAINT "api_tokens_id_format" CHECK ("id" ~ '^apitok_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
69
|
+
|
|
70
|
+
-- refresh_tokens: reftok_
|
|
71
|
+
ALTER TABLE "refresh_tokens" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
72
|
+
ALTER TABLE "refresh_tokens" ALTER COLUMN "id" SET DEFAULT ('reftok_'::text || (uuidv7())::text);
|
|
73
|
+
ALTER TABLE "refresh_tokens" ADD CONSTRAINT "refresh_tokens_id_format" CHECK ("id" ~ '^reftok_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
74
|
+
|
|
75
|
+
-- oauth_clients: oauthc_
|
|
76
|
+
ALTER TABLE "oauth_clients" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
77
|
+
ALTER TABLE "oauth_clients" ALTER COLUMN "id" SET DEFAULT ('oauthc_'::text || (uuidv7())::text);
|
|
78
|
+
ALTER TABLE "oauth_clients" ADD CONSTRAINT "oauth_clients_id_format" CHECK ("id" ~ '^oauthc_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
79
|
+
|
|
80
|
+
-- oauth_authorizations: oautha_
|
|
81
|
+
ALTER TABLE "oauth_authorizations" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
82
|
+
ALTER TABLE "oauth_authorizations" ALTER COLUMN "id" SET DEFAULT ('oautha_'::text || (uuidv7())::text);
|
|
83
|
+
ALTER TABLE "oauth_authorizations" ADD CONSTRAINT "oauth_authorizations_id_format" CHECK ("id" ~ '^oautha_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
84
|
+
|
|
85
|
+
-- push_tokens: pushtok_
|
|
86
|
+
ALTER TABLE "push_tokens" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
87
|
+
ALTER TABLE "push_tokens" ALTER COLUMN "id" SET DEFAULT ('pushtok_'::text || (uuidv7())::text);
|
|
88
|
+
ALTER TABLE "push_tokens" ADD CONSTRAINT "push_tokens_id_format" CHECK ("id" ~ '^pushtok_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
89
|
+
|
|
90
|
+
-- user_data: userd_
|
|
91
|
+
ALTER TABLE "user_data" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
92
|
+
ALTER TABLE "user_data" ALTER COLUMN "id" SET DEFAULT ('userd_'::text || (uuidv7())::text);
|
|
93
|
+
ALTER TABLE "user_data" ADD CONSTRAINT "user_data_id_format" CHECK ("id" ~ '^userd_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
94
|
+
|
|
95
|
+
-- site_settings: siteset_
|
|
96
|
+
ALTER TABLE "site_settings" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
97
|
+
ALTER TABLE "site_settings" ALTER COLUMN "id" SET DEFAULT ('siteset_'::text || (uuidv7())::text);
|
|
98
|
+
ALTER TABLE "site_settings" ADD CONSTRAINT "site_settings_id_format" CHECK ("id" ~ '^siteset_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
99
|
+
|
|
100
|
+
-- workspace_themes: theme_
|
|
101
|
+
ALTER TABLE "workspace_themes" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
102
|
+
ALTER TABLE "workspace_themes" ALTER COLUMN "id" SET DEFAULT ('theme_'::text || (uuidv7())::text);
|
|
103
|
+
ALTER TABLE "workspace_themes" ADD CONSTRAINT "workspace_themes_id_format" CHECK ("id" ~ '^theme_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
104
|
+
|
|
105
|
+
-- workspace_site_identities: siteid_
|
|
106
|
+
ALTER TABLE "workspace_site_identities" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
107
|
+
ALTER TABLE "workspace_site_identities" ALTER COLUMN "id" SET DEFAULT ('siteid_'::text || (uuidv7())::text);
|
|
108
|
+
ALTER TABLE "workspace_site_identities" ADD CONSTRAINT "workspace_site_identities_id_format" CHECK ("id" ~ '^siteid_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
109
|
+
|
|
110
|
+
-- workspace_seos: seo_
|
|
111
|
+
ALTER TABLE "workspace_seos" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
112
|
+
ALTER TABLE "workspace_seos" ALTER COLUMN "id" SET DEFAULT ('seo_'::text || (uuidv7())::text);
|
|
113
|
+
ALTER TABLE "workspace_seos" ADD CONSTRAINT "workspace_seos_id_format" CHECK ("id" ~ '^seo_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
114
|
+
|
|
115
|
+
-- agent_sessions: agsess_
|
|
116
|
+
ALTER TABLE "agent_sessions" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
117
|
+
ALTER TABLE "agent_sessions" ALTER COLUMN "id" SET DEFAULT ('agsess_'::text || (uuidv7())::text);
|
|
118
|
+
ALTER TABLE "agent_sessions" ADD CONSTRAINT "agent_sessions_id_format" CHECK ("id" ~ '^agsess_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
119
|
+
|
|
120
|
+
-- conversation_events: convev_
|
|
121
|
+
ALTER TABLE "conversation_events" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
122
|
+
ALTER TABLE "conversation_events" ALTER COLUMN "id" SET DEFAULT ('convev_'::text || (uuidv7())::text);
|
|
123
|
+
ALTER TABLE "conversation_events" ADD CONSTRAINT "conversation_events_id_format" CHECK ("id" ~ '^convev_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
124
|
+
|
|
125
|
+
-- session_read_receipts: receipt_
|
|
126
|
+
ALTER TABLE "session_read_receipts" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
127
|
+
ALTER TABLE "session_read_receipts" ALTER COLUMN "id" SET DEFAULT ('receipt_'::text || (uuidv7())::text);
|
|
128
|
+
ALTER TABLE "session_read_receipts" ADD CONSTRAINT "session_read_receipts_id_format" CHECK ("id" ~ '^receipt_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
129
|
+
|
|
130
|
+
-- artifacts: artif_
|
|
131
|
+
ALTER TABLE "artifacts" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
132
|
+
ALTER TABLE "artifacts" ALTER COLUMN "id" SET DEFAULT ('artif_'::text || (uuidv7())::text);
|
|
133
|
+
ALTER TABLE "artifacts" ADD CONSTRAINT "artifacts_id_format" CHECK ("id" ~ '^artif_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
134
|
+
|
|
135
|
+
-- artifact_versions: artiv_
|
|
136
|
+
ALTER TABLE "artifact_versions" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
137
|
+
ALTER TABLE "artifact_versions" ALTER COLUMN "id" SET DEFAULT ('artiv_'::text || (uuidv7())::text);
|
|
138
|
+
ALTER TABLE "artifact_versions" ADD CONSTRAINT "artifact_versions_id_format" CHECK ("id" ~ '^artiv_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
139
|
+
|
|
140
|
+
-- leads: lead_
|
|
141
|
+
ALTER TABLE "leads" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
142
|
+
ALTER TABLE "leads" ALTER COLUMN "id" SET DEFAULT ('lead_'::text || (uuidv7())::text);
|
|
143
|
+
ALTER TABLE "leads" ADD CONSTRAINT "leads_id_format" CHECK ("id" ~ '^lead_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
144
|
+
|
|
145
|
+
-- subscribers: subscr_
|
|
146
|
+
ALTER TABLE "subscribers" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
147
|
+
ALTER TABLE "subscribers" ALTER COLUMN "id" SET DEFAULT ('subscr_'::text || (uuidv7())::text);
|
|
148
|
+
ALTER TABLE "subscribers" ADD CONSTRAINT "subscribers_id_format" CHECK ("id" ~ '^subscr_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
149
|
+
|
|
150
|
+
-- callbacks: callbk_
|
|
151
|
+
ALTER TABLE "callbacks" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
152
|
+
ALTER TABLE "callbacks" ALTER COLUMN "id" SET DEFAULT ('callbk_'::text || (uuidv7())::text);
|
|
153
|
+
ALTER TABLE "callbacks" ADD CONSTRAINT "callbacks_id_format" CHECK ("id" ~ '^callbk_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
154
|
+
|
|
155
|
+
-- audit_logs: audit_
|
|
156
|
+
ALTER TABLE "audit_logs" ALTER COLUMN "id" TYPE text COLLATE "C";
|
|
157
|
+
ALTER TABLE "audit_logs" ALTER COLUMN "id" SET DEFAULT ('audit_'::text || (uuidv7())::text);
|
|
158
|
+
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_id_format" CHECK ("id" ~ '^audit_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
159
|
+
|
|
160
|
+
-- ── Relation-free scope/id reference columns (12) ──
|
|
161
|
+
-- NULL passes a CHECK (three-valued logic), so nullable columns need no IS NULL guard.
|
|
162
|
+
|
|
163
|
+
ALTER TABLE "sessions" ALTER COLUMN "active_organization_id" TYPE text COLLATE "C";
|
|
164
|
+
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_active_organization_id_format" CHECK ("active_organization_id" ~ '^org_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
165
|
+
|
|
166
|
+
ALTER TABLE "sessions" ALTER COLUMN "active_workspace_id" TYPE text COLLATE "C";
|
|
167
|
+
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_active_workspace_id_format" CHECK ("active_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}$');
|
|
168
|
+
|
|
169
|
+
ALTER TABLE "workspace_themes" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
170
|
+
ALTER TABLE "workspace_themes" ADD CONSTRAINT "workspace_themes_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}$');
|
|
171
|
+
|
|
172
|
+
ALTER TABLE "workspace_site_identities" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
173
|
+
ALTER TABLE "workspace_site_identities" ADD CONSTRAINT "workspace_site_identities_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}$');
|
|
174
|
+
|
|
175
|
+
ALTER TABLE "workspace_seos" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
176
|
+
ALTER TABLE "workspace_seos" ADD CONSTRAINT "workspace_seos_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}$');
|
|
177
|
+
|
|
178
|
+
ALTER TABLE "audit_logs" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
179
|
+
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_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}$');
|
|
180
|
+
|
|
181
|
+
ALTER TABLE "agent_sessions" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
182
|
+
ALTER TABLE "agent_sessions" ADD CONSTRAINT "agent_sessions_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}$');
|
|
183
|
+
|
|
184
|
+
ALTER TABLE "conversation_events" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
185
|
+
ALTER TABLE "conversation_events" ADD CONSTRAINT "conversation_events_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}$');
|
|
186
|
+
|
|
187
|
+
ALTER TABLE "session_read_receipts" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
188
|
+
ALTER TABLE "session_read_receipts" ADD CONSTRAINT "session_read_receipts_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}$');
|
|
189
|
+
|
|
190
|
+
ALTER TABLE "session_read_receipts" ALTER COLUMN "user_id" TYPE text COLLATE "C";
|
|
191
|
+
ALTER TABLE "session_read_receipts" ADD CONSTRAINT "session_read_receipts_user_id_format" CHECK ("user_id" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
|
|
192
|
+
|
|
193
|
+
ALTER TABLE "artifacts" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
194
|
+
ALTER TABLE "artifacts" ADD CONSTRAINT "artifacts_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}$');
|
|
195
|
+
|
|
196
|
+
ALTER TABLE "artifact_versions" ALTER COLUMN "workspace_id" TYPE text COLLATE "C";
|
|
197
|
+
ALTER TABLE "artifact_versions" ADD CONSTRAINT "artifact_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}$');
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Add Organization billing identity + tier/seat projection (#3601)
|
|
2
|
+
--
|
|
3
|
+
-- Org-scoped billing for the multi-tenant module: the Organization becomes the
|
|
4
|
+
-- billing entity (mirroring the users billing shape added in
|
|
5
|
+
-- 20260515000000_add_user_billing_fields). The Stripe webhook links
|
|
6
|
+
-- billing_provider/billing_customer_id keyed on checkout metadata.organizationId
|
|
7
|
+
-- (apps/api/src/routes/webhooks/stripe.ts); the per-org entitlement resolver
|
|
8
|
+
-- reads tier/seat_count (apps/api/src/services/entitlements.ts).
|
|
9
|
+
--
|
|
10
|
+
-- Forward-additive ONLY: every column is nullable or DEFAULT-ed, so existing
|
|
11
|
+
-- organizations rows need no backfill. Single-tenant deployments keep
|
|
12
|
+
-- User-scoped billing untouched.
|
|
13
|
+
--
|
|
14
|
+
-- Rollback: drop the index then the five columns.
|
|
15
|
+
-- DROP INDEX "organizations_billing_provider_billing_customer_id_key";
|
|
16
|
+
-- ALTER TABLE "organizations" DROP COLUMN "seat_count";
|
|
17
|
+
-- ALTER TABLE "organizations" DROP COLUMN "has_care_plan";
|
|
18
|
+
-- ALTER TABLE "organizations" DROP COLUMN "tier";
|
|
19
|
+
-- ALTER TABLE "organizations" DROP COLUMN "billing_customer_id";
|
|
20
|
+
-- ALTER TABLE "organizations" DROP COLUMN "billing_provider";
|
|
21
|
+
|
|
22
|
+
-- AlterTable
|
|
23
|
+
ALTER TABLE "organizations" ADD COLUMN "billing_provider" TEXT,
|
|
24
|
+
ADD COLUMN "billing_customer_id" TEXT,
|
|
25
|
+
ADD COLUMN "tier" TEXT NOT NULL DEFAULT 'free',
|
|
26
|
+
ADD COLUMN "has_care_plan" BOOLEAN NOT NULL DEFAULT false,
|
|
27
|
+
ADD COLUMN "seat_count" INTEGER NOT NULL DEFAULT 1;
|
|
28
|
+
|
|
29
|
+
-- CreateIndex
|
|
30
|
+
-- Composite unique allows (NULL, NULL) for un-billed orgs (SQL NULL ≠ NULL).
|
|
31
|
+
CREATE UNIQUE INDEX "organizations_billing_provider_billing_customer_id_key"
|
|
32
|
+
ON "organizations"("billing_provider", "billing_customer_id");
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Add Lead → user promotion fields (#3586)
|
|
2
|
+
--
|
|
3
|
+
-- Reconciles an anonymous inbox.Lead with an auth.User once the user's email
|
|
4
|
+
-- is verified (spec D2) and the lead's siteId resolves to one of that user's
|
|
5
|
+
-- own workspaces (tenant-safety, spec D3). apps/api/src/services/lead-promotion.ts
|
|
6
|
+
-- is the sole writer. Plain scalars — no cross-namespace FK into auth.User
|
|
7
|
+
-- (ADR 0009 invariant #1); the join is stable-id matching in the service.
|
|
8
|
+
--
|
|
9
|
+
-- Forward-additive ONLY: both columns are nullable, no backfill needed. The
|
|
10
|
+
-- email index supports the promotion match (email + un-promoted leads).
|
|
11
|
+
--
|
|
12
|
+
-- Rollback:
|
|
13
|
+
-- DROP INDEX "leads_email_idx";
|
|
14
|
+
-- ALTER TABLE "leads" DROP COLUMN "promoted_at";
|
|
15
|
+
-- ALTER TABLE "leads" DROP COLUMN "promoted_user_id";
|
|
16
|
+
|
|
17
|
+
-- AlterTable
|
|
18
|
+
ALTER TABLE "leads" ADD COLUMN "promoted_user_id" TEXT,
|
|
19
|
+
ADD COLUMN "promoted_at" TIMESTAMP(3);
|
|
20
|
+
|
|
21
|
+
-- CreateIndex
|
|
22
|
+
CREATE INDEX "leads_email_idx" ON "leads"("email");
|