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,49 @@
|
|
|
1
|
+
-- The verified owner link on `project_listings` (#5295).
|
|
2
|
+
--
|
|
3
|
+
-- A listing carried `founder_email` and `lead_id` and no user link, so there
|
|
4
|
+
-- was no query for "the listings belonging to this signed-in person". The only
|
|
5
|
+
-- join available was a session's email against `founder_email` — and
|
|
6
|
+
-- `founder_email` is an UNVERIFIED string typed into an anonymous form, so that
|
|
7
|
+
-- join hands a stranger someone else's submission the first time two people
|
|
8
|
+
-- type the same address. These two columns are the ownership claim instead.
|
|
9
|
+
--
|
|
10
|
+
-- Plain scalars, no foreign key into `users`: ADR 0009 invariant #1 forbids a
|
|
11
|
+
-- relation across the namespace boundary, and `leads.promoted_user_id` /
|
|
12
|
+
-- `promoted_at` (20260714000000_add_lead_promotion_fields) are the same shape
|
|
13
|
+
-- for the same reason. The join is stable-id matching in the service layer.
|
|
14
|
+
--
|
|
15
|
+
-- `apps/api/src/services/listing-promotion.ts` is the sole writer, and it sets
|
|
16
|
+
-- the pair only when all three of these hold:
|
|
17
|
+
-- 1. the reconciling user's OWN email is verified (`users.email_verified`) —
|
|
18
|
+
-- never a claimed or session-asserted address;
|
|
19
|
+
-- 2. that verified address matches the row's `founder_email`;
|
|
20
|
+
-- 3. the row's `site_id` is one of that user's own tenant workspaces.
|
|
21
|
+
-- Any one failing writes nothing.
|
|
22
|
+
--
|
|
23
|
+
-- NO BACKFILL, deliberately and permanently. Every existing row predates
|
|
24
|
+
-- verification, so deriving `owner_user_id` from `founder_email` here would
|
|
25
|
+
-- assert exactly the link nobody proved — the bug the column exists to remove.
|
|
26
|
+
-- Existing rows stay null, and a listing submitted by someone who never signs
|
|
27
|
+
-- in stays null for the life of the row: that is a legitimate resting state,
|
|
28
|
+
-- not a backlog to clean up.
|
|
29
|
+
--
|
|
30
|
+
-- The index backs the self-scoped read's whole WHERE clause
|
|
31
|
+
-- (`GET /v1/project-listings/me` — `owner_user_id = $1`, and nothing else: the
|
|
32
|
+
-- owner link IS the scope, so no site term joins it). Single-column by design —
|
|
33
|
+
-- the promotion match (`founder_email` + `site_id` + a null owner) is already
|
|
34
|
+
-- served by the existing (site_id, founder_email) index.
|
|
35
|
+
--
|
|
36
|
+
-- Forward-additive only: both columns are nullable with no default, so every
|
|
37
|
+
-- existing read and write is unaffected.
|
|
38
|
+
--
|
|
39
|
+
-- Rollback:
|
|
40
|
+
-- DROP INDEX "project_listings_owner_user_id_idx";
|
|
41
|
+
-- ALTER TABLE "project_listings" DROP COLUMN "owner_linked_at";
|
|
42
|
+
-- ALTER TABLE "project_listings" DROP COLUMN "owner_user_id";
|
|
43
|
+
|
|
44
|
+
-- AlterTable
|
|
45
|
+
ALTER TABLE "project_listings" ADD COLUMN "owner_user_id" TEXT,
|
|
46
|
+
ADD COLUMN "owner_linked_at" TIMESTAMP(3);
|
|
47
|
+
|
|
48
|
+
-- CreateIndex
|
|
49
|
+
CREATE INDEX "project_listings_owner_user_id_idx" ON "project_listings"("owner_user_id");
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ops namespace — AEO scores, audit log, analytics/telemetry (ADR-0009).
|
|
2
|
+
//
|
|
3
|
+
// Generator + datasource live in database/schema.prisma (the folder's single
|
|
4
|
+
// config file); this file holds only model definitions.
|
|
5
|
+
//
|
|
6
|
+
// TelemetryRecord (vendor seat-usage telemetry) moved out of this namespace to
|
|
7
|
+
// apps-paid/license-issuer/prisma/schema.prisma — the vendor service is the
|
|
8
|
+
// table's sole writer and nothing in the product schema reads it, so it is a
|
|
9
|
+
// vendor-owned concern rather than a product-schema model. See
|
|
10
|
+
// docs/internal/proposals/agentic-services-control-plane-proposal.md.
|
|
11
|
+
|
|
12
|
+
/// AuditLog — workspace-scoped "who did what, when" audit trail (queryable + retained).
|
|
13
|
+
model AuditLog {
|
|
14
|
+
id String @id @default(dbgenerated("('audit_'::text || (uuidv7())::text)")) @db.Text
|
|
15
|
+
workspaceId String @map("workspace_id") // tenant scope — stable-id ref, NO @relation (ADR-0009)
|
|
16
|
+
actorId String @map("actor_id") // who acted (a User / agent / system id) — stable-id ref
|
|
17
|
+
actorType String @map("actor_type") // "user" | "agent" | "system"
|
|
18
|
+
action String // e.g. "workspace.settings.updated", "lead.deleted"
|
|
19
|
+
targetType String? @map("target_type") // what was acted on: "workspace" | "lead" | "user" | …
|
|
20
|
+
targetId String? @map("target_id") // stable-id ref to the target (nullable)
|
|
21
|
+
metadata Json? // structured detail (before/after, request context)
|
|
22
|
+
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
|
23
|
+
|
|
24
|
+
@@index([workspaceId, createdAt(sort: Desc)])
|
|
25
|
+
@@index([workspaceId, targetType, targetId])
|
|
26
|
+
@@map("audit_logs")
|
|
27
|
+
}
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@working-theory/database",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"schema.prisma",
|
|
11
|
+
"migrations",
|
|
12
|
+
"config",
|
|
13
|
+
"content",
|
|
14
|
+
"flows",
|
|
15
|
+
"auth",
|
|
16
|
+
"inbox",
|
|
17
|
+
"ops",
|
|
18
|
+
"tenancy.ts",
|
|
19
|
+
"prisma.config.ts"
|
|
20
|
+
],
|
|
4
21
|
"description": "AI Launch Kit database schema (single-tenant Prisma)",
|
|
5
22
|
"type": "module",
|
|
6
23
|
"main": "./dist/client/client.js",
|
|
@@ -15,28 +32,49 @@
|
|
|
15
32
|
"types": "./dist/client/client.d.ts",
|
|
16
33
|
"import": "./dist/client/client.js",
|
|
17
34
|
"default": "./dist/client/client.js"
|
|
35
|
+
},
|
|
36
|
+
"./tenancy": {
|
|
37
|
+
"types": "./dist/tenancy.d.ts",
|
|
38
|
+
"import": "./dist/tenancy.js",
|
|
39
|
+
"default": "./dist/tenancy.js"
|
|
40
|
+
},
|
|
41
|
+
"./flows/presets": {
|
|
42
|
+
"types": "./dist/flows/presets.d.ts",
|
|
43
|
+
"import": "./dist/flows/presets.js",
|
|
44
|
+
"default": "./dist/flows/presets.js"
|
|
45
|
+
},
|
|
46
|
+
"./flows/listing-diagnostic": {
|
|
47
|
+
"types": "./dist/flows/listing-diagnostic.d.ts",
|
|
48
|
+
"import": "./dist/flows/listing-diagnostic.js",
|
|
49
|
+
"default": "./dist/flows/listing-diagnostic.js"
|
|
18
50
|
}
|
|
19
51
|
},
|
|
20
52
|
"scripts": {
|
|
21
|
-
"
|
|
53
|
+
"lint": "tsx ../scripts/lint-package.ts",
|
|
54
|
+
"build": "tsc -b tsconfig.build.json && tsc -b tsconfig.tenancy.json && tsc -b tsconfig.flows.json",
|
|
22
55
|
"db:generate": "prisma generate && pnpm run build",
|
|
23
56
|
"db:migrate": "prisma migrate dev",
|
|
24
57
|
"db:migrate:deploy": "prisma migrate deploy",
|
|
25
58
|
"db:push": "prisma db push",
|
|
26
|
-
"db:seed": "
|
|
59
|
+
"db:seed": "tsx seed.ts",
|
|
27
60
|
"db:seed:test": "tsx seed-test.ts",
|
|
28
61
|
"db:studio": "prisma studio",
|
|
29
62
|
"test": "jest --config jest.config.cjs",
|
|
30
63
|
"test:watch": "jest --config jest.config.cjs --watch"
|
|
31
64
|
},
|
|
32
65
|
"dependencies": {
|
|
33
|
-
"@prisma/
|
|
66
|
+
"@prisma/adapter-pg": "^7.8.0",
|
|
67
|
+
"@prisma/client": "^7.8.0",
|
|
68
|
+
"@working-theory/ids": "workspace:*",
|
|
69
|
+
"@working-theory/validation": "workspace:*"
|
|
34
70
|
},
|
|
35
71
|
"devDependencies": {
|
|
36
72
|
"@types/jest": "^30.0.0",
|
|
37
73
|
"@types/node": "^22.20.0",
|
|
74
|
+
"@types/pg": "^8.20.0",
|
|
38
75
|
"dotenv": "^17.4.2",
|
|
39
76
|
"jest": "^30.4.2",
|
|
77
|
+
"pg": "^8.22.0",
|
|
40
78
|
"prisma": "^7.8.0",
|
|
41
79
|
"ts-jest": "^29.4.11",
|
|
42
80
|
"tsx": "^4.22.4",
|
|
@@ -3,19 +3,12 @@
|
|
|
3
3
|
// MINIMAL BUT EXTENSIBLE - Only stores auth and customer extensions
|
|
4
4
|
// All business data (leads, orders, analytics) lives on the Platform
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// - Inbox (3): Lead, Subscriber, Callback [namespace: database/inbox/]
|
|
13
|
-
//
|
|
14
|
-
// Aggregation strategy: Namespace-local schema files (e.g. database/inbox/schema.prisma)
|
|
15
|
-
// define models canonically for lint and documentation. Those same models are
|
|
16
|
-
// registered here so Prisma can generate from the single root schema.prisma.
|
|
17
|
-
// Phase 2 (ADR 0009 D4) will migrate to prismaSchemaFolder once multi-file
|
|
18
|
-
// generation is adopted repo-wide.
|
|
6
|
+
// Schema layout: prismaSchemaFolder (ADR 0009 D4 Phase 2, #3607). Prisma reads
|
|
7
|
+
// the whole database/ folder — each model is defined ONCE in its namespace file
|
|
8
|
+
// (database/{auth,config,ops,inbox,content}/schema.prisma). This file holds ONLY
|
|
9
|
+
// the single generator + datasource blocks — it is model-free (#3607 AC-1). The
|
|
10
|
+
// former per-User site-config models (TenantTheme/TenantSiteIdentity/TenantSEO)
|
|
11
|
+
// were re-anchored to the config namespace keyed on workspaceId (#3641).
|
|
19
12
|
|
|
20
13
|
generator client {
|
|
21
14
|
provider = "prisma-client"
|
|
@@ -27,327 +20,26 @@ datasource db {
|
|
|
27
20
|
provider = "postgresql"
|
|
28
21
|
}
|
|
29
22
|
|
|
30
|
-
// ============================================================================
|
|
31
|
-
// Better Auth Models (Web Dashboard Authentication — #587)
|
|
32
|
-
// ============================================================================
|
|
33
|
-
|
|
34
|
-
/// User - Dashboard users (site owners, admins, end-users)
|
|
35
|
-
///
|
|
36
|
-
/// emailVerified is a Boolean per Better Auth's contract (NextAuth previously
|
|
37
|
-
/// stored the verification timestamp as DateTime?). The five custom relations
|
|
38
|
-
/// — ApiToken, RefreshToken, OAuthAuthorization, PushToken, UserData — keep
|
|
39
|
-
/// their onDelete: Cascade semantics so user removal cleanly tears down all
|
|
40
|
-
/// dependent rows.
|
|
41
|
-
model User {
|
|
42
|
-
id String @id @default(cuid())
|
|
43
|
-
email String @unique
|
|
44
|
-
name String?
|
|
45
|
-
image String?
|
|
46
|
-
emailVerified Boolean @default(false) @map("email_verified")
|
|
47
|
-
|
|
48
|
-
// Profile extensions
|
|
49
|
-
role String @default("user") // "user", "admin", "owner"
|
|
50
|
-
|
|
51
|
-
// Billing identity — provider-agnostic so Stripe is v1 value, not baked-in name.
|
|
52
|
-
// Webhook is the only writer (see apps/api/src/routes/webhooks/stripe.ts).
|
|
53
|
-
// #771 self-serve dashboard reads billingCustomerId for Stripe customer-portal URL.
|
|
54
|
-
billingProvider String? @map("billing_provider") // "stripe"; future: "lemonsqueezy", "paddle"
|
|
55
|
-
billingCustomerId String? @map("billing_customer_id") // cus_xxx (Stripe) or equivalent
|
|
56
|
-
|
|
57
|
-
// Subscription tier projection — derived from the Stripe webhook's product-aware
|
|
58
|
-
// routing (#898). Defaults to "free" until a customer.subscription.created event
|
|
59
|
-
// fires; flips to "pro" / "pro_plus" / etc. based on the line item's product.
|
|
60
|
-
// hasCarePlan is true only for pro_plus today; seatCount mirrors the line item
|
|
61
|
-
// quantity from Stripe's adjustable-quantity widget (1–50).
|
|
62
|
-
tier String @default("free") // "free" | "pro" | "pro_plus" | "enterprise" (retired "agency"/"commercial" rows migrated to "enterprise" — #3516)
|
|
63
|
-
hasCarePlan Boolean @default(false) @map("has_care_plan")
|
|
64
|
-
seatCount Int @default(1) @map("seat_count")
|
|
65
|
-
|
|
66
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
67
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
68
|
-
|
|
69
|
-
// Better Auth relations
|
|
70
|
-
sessions Session[]
|
|
71
|
-
accounts Account[]
|
|
72
|
-
|
|
73
|
-
// API & OAuth
|
|
74
|
-
apiTokens ApiToken[]
|
|
75
|
-
refreshTokens RefreshToken[]
|
|
76
|
-
oauthAuthorizations OAuthAuthorization[]
|
|
77
|
-
pushTokens PushToken[]
|
|
78
|
-
|
|
79
|
-
// Extensions
|
|
80
|
-
userData UserData[]
|
|
81
|
-
|
|
82
|
-
// Theme Wiring (TWP3-MAT #1359)
|
|
83
|
-
tenantTheme TenantTheme?
|
|
84
|
-
tenantSiteIdentity TenantSiteIdentity?
|
|
85
|
-
tenantSeo TenantSEO?
|
|
86
|
-
|
|
87
|
-
@@unique([billingProvider, billingCustomerId])
|
|
88
|
-
@@map("users")
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/// Session - Active user sessions (Better Auth schema)
|
|
92
|
-
///
|
|
93
|
-
/// Session.token is the opaque cookie value the dual-mode preHandler reads.
|
|
94
|
-
/// Deleting a row revokes the session; deleting the parent User cascades.
|
|
95
|
-
model Session {
|
|
96
|
-
id String @id
|
|
97
|
-
expiresAt DateTime @map("expires_at")
|
|
98
|
-
token String @unique
|
|
99
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
100
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
101
|
-
ipAddress String? @map("ip_address")
|
|
102
|
-
userAgent String? @map("user_agent")
|
|
103
|
-
userId String @map("user_id")
|
|
104
|
-
|
|
105
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
106
|
-
|
|
107
|
-
@@index([userId])
|
|
108
|
-
@@index([token])
|
|
109
|
-
@@map("sessions")
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/// Account - OAuth provider connections (Google, GitHub, etc.)
|
|
113
|
-
///
|
|
114
|
-
/// Better Auth's account shape: one row per (providerId, accountId) pair.
|
|
115
|
-
/// Cascade on User removal keeps OAuth links from orphaning.
|
|
116
|
-
model Account {
|
|
117
|
-
id String @id
|
|
118
|
-
accountId String @map("account_id")
|
|
119
|
-
providerId String @map("provider_id")
|
|
120
|
-
userId String @map("user_id")
|
|
121
|
-
accessToken String? @map("access_token") @db.Text
|
|
122
|
-
refreshToken String? @map("refresh_token") @db.Text
|
|
123
|
-
idToken String? @map("id_token") @db.Text
|
|
124
|
-
accessTokenExpiresAt DateTime? @map("access_token_expires_at")
|
|
125
|
-
refreshTokenExpiresAt DateTime? @map("refresh_token_expires_at")
|
|
126
|
-
scope String?
|
|
127
|
-
password String?
|
|
128
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
129
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
130
|
-
|
|
131
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
132
|
-
|
|
133
|
-
@@unique([providerId, accountId])
|
|
134
|
-
@@index([userId])
|
|
135
|
-
@@map("accounts")
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/// Verification - Email / magic-link verification tokens (Better Auth schema)
|
|
139
|
-
model Verification {
|
|
140
|
-
id String @id
|
|
141
|
-
identifier String
|
|
142
|
-
value String
|
|
143
|
-
expiresAt DateTime @map("expires_at")
|
|
144
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
145
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
146
|
-
|
|
147
|
-
@@index([identifier])
|
|
148
|
-
@@map("verifications")
|
|
149
|
-
}
|
|
150
|
-
|
|
151
23
|
// ============================================================================
|
|
152
24
|
// API Token Authentication (Mobile Apps, CLI, External Clients)
|
|
153
25
|
// ============================================================================
|
|
154
26
|
|
|
155
|
-
/// ApiToken - Bearer tokens for non-web clients (mobile apps, API integrations)
|
|
156
|
-
model ApiToken {
|
|
157
|
-
id String @id @default(cuid())
|
|
158
|
-
userId String @map("user_id")
|
|
159
|
-
|
|
160
|
-
// Token identification
|
|
161
|
-
name String // "iPhone", "Android App", "API Integration"
|
|
162
|
-
token String @unique // Hashed token
|
|
163
|
-
tokenPrefix String @map("token_prefix") // First 8 chars for identification
|
|
164
|
-
|
|
165
|
-
// Client info
|
|
166
|
-
clientType String @default("api") @map("client_type") // "mobile", "api", "cli"
|
|
167
|
-
deviceInfo String? @map("device_info") // "iPhone 15 Pro", "Android 14"
|
|
168
|
-
|
|
169
|
-
// Permissions
|
|
170
|
-
scopes String[] @default([]) // ["read:profile", "write:data"]
|
|
171
|
-
|
|
172
|
-
// Lifecycle
|
|
173
|
-
expiresAt DateTime? @map("expires_at")
|
|
174
|
-
lastUsedAt DateTime? @map("last_used_at")
|
|
175
|
-
lastUsedIp String? @map("last_used_ip")
|
|
176
|
-
revokedAt DateTime? @map("revoked_at")
|
|
177
|
-
|
|
178
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
179
|
-
|
|
180
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
181
|
-
refreshTokens RefreshToken[]
|
|
182
|
-
|
|
183
|
-
@@index([userId])
|
|
184
|
-
@@index([token])
|
|
185
|
-
@@index([tokenPrefix])
|
|
186
|
-
@@map("api_tokens")
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/// RefreshToken - Long-lived tokens for mobile session refresh
|
|
190
|
-
model RefreshToken {
|
|
191
|
-
id String @id @default(cuid())
|
|
192
|
-
userId String @map("user_id")
|
|
193
|
-
apiTokenId String @map("api_token_id")
|
|
194
|
-
|
|
195
|
-
token String @unique // Hashed
|
|
196
|
-
|
|
197
|
-
// Lifecycle
|
|
198
|
-
expiresAt DateTime @map("expires_at")
|
|
199
|
-
usedAt DateTime? @map("used_at") // Last time used to get new access token
|
|
200
|
-
revokedAt DateTime? @map("revoked_at")
|
|
201
|
-
|
|
202
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
203
|
-
|
|
204
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
205
|
-
apiToken ApiToken @relation(fields: [apiTokenId], references: [id], onDelete: Cascade)
|
|
206
|
-
|
|
207
|
-
@@index([userId])
|
|
208
|
-
@@index([apiTokenId])
|
|
209
|
-
@@index([token])
|
|
210
|
-
@@map("refresh_tokens")
|
|
211
|
-
}
|
|
212
|
-
|
|
213
27
|
// ============================================================================
|
|
214
28
|
// OAuth 2.0 (ChatGPT Plugin, Slack Bot, External Integrations)
|
|
215
29
|
// ============================================================================
|
|
216
30
|
|
|
217
|
-
/// OAuthClient - Registered OAuth applications (ChatGPT, Slack, etc.)
|
|
218
|
-
model OAuthClient {
|
|
219
|
-
id String @id @default(cuid())
|
|
220
|
-
|
|
221
|
-
// Client identification
|
|
222
|
-
name String // "ChatGPT Plugin", "Slack Bot"
|
|
223
|
-
description String?
|
|
224
|
-
logoUrl String? @map("logo_url")
|
|
225
|
-
|
|
226
|
-
// OAuth credentials
|
|
227
|
-
clientId String @unique @map("client_id") // Public identifier
|
|
228
|
-
clientSecret String @map("client_secret") // Hashed secret
|
|
229
|
-
|
|
230
|
-
// OAuth config
|
|
231
|
-
redirectUris String[] @map("redirect_uris") // Allowed callback URLs
|
|
232
|
-
scopes String[] @default([]) // Allowed scopes
|
|
233
|
-
|
|
234
|
-
// Settings
|
|
235
|
-
enabled Boolean @default(true)
|
|
236
|
-
trusted Boolean @default(false) // Skip consent screen
|
|
237
|
-
|
|
238
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
239
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
240
|
-
|
|
241
|
-
authorizations OAuthAuthorization[]
|
|
242
|
-
|
|
243
|
-
@@map("oauth_clients")
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/// OAuthAuthorization - User grants to OAuth clients
|
|
247
|
-
model OAuthAuthorization {
|
|
248
|
-
id String @id @default(cuid())
|
|
249
|
-
userId String @map("user_id")
|
|
250
|
-
clientId String @map("client_id")
|
|
251
|
-
|
|
252
|
-
// Granted scopes (may be subset of client's allowed scopes)
|
|
253
|
-
scopes String[]
|
|
254
|
-
|
|
255
|
-
// Tokens
|
|
256
|
-
accessToken String @unique @map("access_token") // Hashed
|
|
257
|
-
refreshToken String? @unique @map("refresh_token") // Hashed
|
|
258
|
-
|
|
259
|
-
// Lifecycle
|
|
260
|
-
expiresAt DateTime @map("expires_at")
|
|
261
|
-
revokedAt DateTime? @map("revoked_at")
|
|
262
|
-
|
|
263
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
264
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
265
|
-
|
|
266
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
267
|
-
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
|
268
|
-
|
|
269
|
-
@@unique([userId, clientId])
|
|
270
|
-
@@index([userId])
|
|
271
|
-
@@index([clientId])
|
|
272
|
-
@@index([accessToken])
|
|
273
|
-
@@map("oauth_authorizations")
|
|
274
|
-
}
|
|
275
|
-
|
|
276
31
|
// ============================================================================
|
|
277
32
|
// Push Notifications (Mobile Apps, Web Push)
|
|
278
33
|
// ============================================================================
|
|
279
34
|
|
|
280
|
-
/// PushToken - Device tokens for push notifications
|
|
281
|
-
model PushToken {
|
|
282
|
-
id String @id @default(cuid())
|
|
283
|
-
userId String @map("user_id")
|
|
284
|
-
|
|
285
|
-
// Token details
|
|
286
|
-
token String @unique // FCM or APNs token
|
|
287
|
-
platform String // "ios", "android", "web"
|
|
288
|
-
|
|
289
|
-
// Device info
|
|
290
|
-
deviceId String? @map("device_id") // Unique device identifier
|
|
291
|
-
deviceName String? @map("device_name") // "iPhone 15 Pro"
|
|
292
|
-
appVersion String? @map("app_version") // "1.2.3"
|
|
293
|
-
|
|
294
|
-
// Status
|
|
295
|
-
enabled Boolean @default(true)
|
|
296
|
-
failedAt DateTime? @map("failed_at") // Last delivery failure
|
|
297
|
-
failCount Int @default(0) @map("fail_count")
|
|
298
|
-
|
|
299
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
300
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
301
|
-
|
|
302
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
303
|
-
|
|
304
|
-
@@index([userId])
|
|
305
|
-
@@index([platform])
|
|
306
|
-
@@map("push_tokens")
|
|
307
|
-
}
|
|
308
|
-
|
|
309
35
|
// ============================================================================
|
|
310
36
|
// User Data Extensions (Customer Customizations)
|
|
311
37
|
// ============================================================================
|
|
312
38
|
|
|
313
|
-
/// UserData - Flexible key-value storage for customer extensions
|
|
314
|
-
/// Use this for: preferences, saved items, custom fields, feature flags
|
|
315
|
-
model UserData {
|
|
316
|
-
id String @id @default(cuid())
|
|
317
|
-
userId String @map("user_id")
|
|
318
|
-
|
|
319
|
-
// Key-value storage
|
|
320
|
-
key String // "preferences", "saved_products", "notification_settings"
|
|
321
|
-
value Json // Flexible JSON storage
|
|
322
|
-
|
|
323
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
324
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
325
|
-
|
|
326
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
327
|
-
|
|
328
|
-
@@unique([userId, key])
|
|
329
|
-
@@index([userId])
|
|
330
|
-
@@index([key])
|
|
331
|
-
@@map("user_data")
|
|
332
|
-
}
|
|
333
|
-
|
|
334
39
|
// ============================================================================
|
|
335
40
|
// Site Settings (Site-wide Configuration)
|
|
336
41
|
// ============================================================================
|
|
337
42
|
|
|
338
|
-
/// SiteSetting - Key-value settings for the customer site
|
|
339
|
-
/// Use for: feature flags, custom config, cached Platform data
|
|
340
|
-
model SiteSetting {
|
|
341
|
-
id String @id @default(cuid())
|
|
342
|
-
key String @unique // "feature_flags", "cached_config", "custom_theme"
|
|
343
|
-
value Json
|
|
344
|
-
|
|
345
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
346
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
347
|
-
|
|
348
|
-
@@map("site_settings")
|
|
349
|
-
}
|
|
350
|
-
|
|
351
43
|
// ============================================================================
|
|
352
44
|
// Inbox Namespace (database/inbox/schema.prisma — B1)
|
|
353
45
|
//
|
|
@@ -356,132 +48,24 @@ model SiteSetting {
|
|
|
356
48
|
// through apps/api/src/services/ (D3).
|
|
357
49
|
// ============================================================================
|
|
358
50
|
|
|
359
|
-
/// Lead - anonymous lead submission (Phase B submit_lead tool / B6 route)
|
|
360
|
-
model Lead {
|
|
361
|
-
id String @id @default(cuid())
|
|
362
|
-
siteId String @map("site_id")
|
|
363
|
-
source String
|
|
364
|
-
email String
|
|
365
|
-
payload Json
|
|
366
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
367
|
-
|
|
368
|
-
@@index([siteId])
|
|
369
|
-
@@index([createdAt])
|
|
370
|
-
@@map("leads")
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/// Subscriber - newsletter subscription (Phase B subscribe_newsletter tool / B6 route)
|
|
374
|
-
model Subscriber {
|
|
375
|
-
id String @id @default(cuid())
|
|
376
|
-
siteId String @map("site_id")
|
|
377
|
-
email String
|
|
378
|
-
source String
|
|
379
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
380
|
-
|
|
381
|
-
@@unique([siteId, email])
|
|
382
|
-
@@index([siteId])
|
|
383
|
-
@@map("subscribers")
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/// Callback - callback request (Phase B request_callback tool / B6 route)
|
|
387
|
-
model Callback {
|
|
388
|
-
id String @id @default(cuid())
|
|
389
|
-
siteId String @map("site_id")
|
|
390
|
-
name String
|
|
391
|
-
phone String
|
|
392
|
-
preferredTime String? @map("preferred_time")
|
|
393
|
-
payload Json
|
|
394
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
395
|
-
|
|
396
|
-
@@index([siteId])
|
|
397
|
-
@@index([createdAt])
|
|
398
|
-
@@map("callbacks")
|
|
399
|
-
}
|
|
400
|
-
|
|
401
51
|
// ============================================================================
|
|
402
|
-
//
|
|
52
|
+
// Tenancy — multi-tenant module (database/auth/schema.prisma — FEAT-042)
|
|
403
53
|
//
|
|
404
|
-
//
|
|
405
|
-
//
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
//
|
|
409
|
-
//
|
|
54
|
+
// Organization → Workspace → Membership. Same-namespace @relation to User is
|
|
55
|
+
// allowed (auth namespace: identity + tenancy membership per ADR 0009).
|
|
56
|
+
// Organization/Membership/Invitation are managed by the Better Auth
|
|
57
|
+
// organization plugin (apps/workspace auth config); Workspace is AILK's own
|
|
58
|
+
// model (plugin teams feature rejected — per-team membership contradicts
|
|
59
|
+
// org-level membership; see docs/research/ploy-capture/lessons/).
|
|
410
60
|
// ============================================================================
|
|
411
61
|
|
|
412
|
-
/// TelemetryRecord - opt-in seat-usage telemetry from customer deployments.
|
|
413
|
-
///
|
|
414
|
-
/// timestamp is the client-side observation time (from the telemetry payload).
|
|
415
|
-
/// recordedAt is the server-side receipt time (default now()).
|
|
416
|
-
/// The (customerId, recordedAt DESC) index supports "latest record per customer"
|
|
417
|
-
/// queries; the recordedAt DESC index supports time-window aggregate queries.
|
|
418
|
-
model TelemetryRecord {
|
|
419
|
-
id String @id @default(cuid())
|
|
420
|
-
customerId String @map("customer_id")
|
|
421
|
-
activeUserCount Int @map("active_user_count")
|
|
422
|
-
seatCount Int @map("seat_count")
|
|
423
|
-
timestamp DateTime
|
|
424
|
-
recordedAt DateTime @default(now()) @map("recorded_at")
|
|
425
|
-
|
|
426
|
-
@@index([customerId, recordedAt(sort: Desc)])
|
|
427
|
-
@@index([recordedAt(sort: Desc)])
|
|
428
|
-
@@map("telemetry_records")
|
|
429
|
-
}
|
|
430
|
-
|
|
431
62
|
// ============================================================================
|
|
432
|
-
//
|
|
433
|
-
//
|
|
434
|
-
// Three tables, one per @working-theory/site-config schema. Each row stores the
|
|
435
|
-
// Zod-validated JSON blob for a single tenant (identified by userId from the
|
|
436
|
-
// Better Auth session). Validation is enforced at the API layer; the DB stores
|
|
437
|
-
// the already-validated blob in a Json column.
|
|
63
|
+
// Chat/Artifact substrate (database/content/schema.prisma)
|
|
438
64
|
//
|
|
439
|
-
//
|
|
440
|
-
//
|
|
441
|
-
//
|
|
442
|
-
//
|
|
443
|
-
//
|
|
444
|
-
// - userId is the Better Auth User id — plain String FK; onDelete Cascade
|
|
445
|
-
// ensures rows are removed when the user account is deleted.
|
|
446
|
-
// - @@unique([userId]) enforces one active record per tenant per config type
|
|
447
|
-
// (upsert semantics at the API layer).
|
|
65
|
+
// Event-sourced conversation transport + artifact persistence per
|
|
66
|
+
// docs/research/ploy-capture/BACKEND-REQUIREMENTS.md. Every table carries a
|
|
67
|
+
// non-null workspaceId tenant scope as a plain String — no cross-namespace
|
|
68
|
+
// FK into auth (ADR 0009 invariant 1). Cross-namespace assembly (tenant
|
|
69
|
+
// guard, unread counts per user) routes through apps/api/src/services/.
|
|
448
70
|
// ============================================================================
|
|
449
71
|
|
|
450
|
-
/// TenantTheme — per-tenant ThemeSchema blob (TWP3-MAT #1359)
|
|
451
|
-
model TenantTheme {
|
|
452
|
-
id String @id @default(cuid())
|
|
453
|
-
userId String @unique @map("user_id")
|
|
454
|
-
data Json
|
|
455
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
456
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
457
|
-
|
|
458
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
459
|
-
|
|
460
|
-
@@map("tenant_themes")
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/// TenantSiteIdentity — per-tenant SiteIdentitySchema blob (TWP3-MAT #1359)
|
|
464
|
-
model TenantSiteIdentity {
|
|
465
|
-
id String @id @default(cuid())
|
|
466
|
-
userId String @unique @map("user_id")
|
|
467
|
-
data Json
|
|
468
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
469
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
470
|
-
|
|
471
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
472
|
-
|
|
473
|
-
@@map("tenant_site_identities")
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/// TenantSEO — per-tenant SEOSchema blob (TWP3-MAT #1359)
|
|
477
|
-
model TenantSEO {
|
|
478
|
-
id String @id @default(cuid())
|
|
479
|
-
userId String @unique @map("user_id")
|
|
480
|
-
data Json
|
|
481
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
482
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
483
|
-
|
|
484
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
485
|
-
|
|
486
|
-
@@map("tenant_seos")
|
|
487
|
-
}
|