create-ailk 0.1.0 → 0.1.1
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 +295 -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 +22 -14
- 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 +75 -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 +231 -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 +547 -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 +742 -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-key.test.ts +364 -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 +105 -0
- package/templates/apps/api/src/routes/project-listings/list.ts +47 -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 +98 -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 +293 -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__/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__/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/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 +1278 -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/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 +490 -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 +1124 -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 +115 -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 +84 -27
- package/templates/apps/web/lib/__tests__/site-brand.test.ts +119 -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 +118 -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 +16 -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 +24 -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 +382 -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 +476 -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/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/scripts/db-generate-locked.sh +0 -0
- 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,663 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module → architecture-slice registry.
|
|
3
|
+
*
|
|
4
|
+
* The single source that turns the `--modules` selection into a scaffolded
|
|
5
|
+
* site's `architecture.yaml` (its code-boundary config — the apps/packages/
|
|
6
|
+
* namespaces the linter walks + the import rules it enforces). Each recognized
|
|
7
|
+
* module maps to the architecture FRAGMENT it contributes; `deriveArchitecture`
|
|
8
|
+
* (derive-architecture.ts) composes a module-independent BASE + the selected
|
|
9
|
+
* slices into one deterministic document.
|
|
10
|
+
*
|
|
11
|
+
* Grounded in the root AILK `architecture.yaml` `composition_model`: a customer
|
|
12
|
+
* site is the three-tier AILK app (data · api · presentation) COMPOSED of the
|
|
13
|
+
* selected modules. `marketing` is the thin presentation default and is
|
|
14
|
+
* validated end-to-end; `docs` (a mountable presentation surface) and
|
|
15
|
+
* `multi-tenant` (a full-stack module) are registry-defined ahead of their
|
|
16
|
+
* template trees (per spec #3787 D3). `scheduling` (#4633) contributes all
|
|
17
|
+
* three tiers — the provider client, the /v1/schedule/* routes, and the
|
|
18
|
+
* booker + confirmation pages — into the marketing surface.
|
|
19
|
+
*
|
|
20
|
+
* Design (spec #3787 D1): a code registry, NOT N hand-maintained per-module
|
|
21
|
+
* `architecture.yaml` template files — a fixed template IS the drift this
|
|
22
|
+
* removes.
|
|
23
|
+
*/
|
|
24
|
+
import { RECOGNIZED_MODULES } from "./parse-args.js";
|
|
25
|
+
/**
|
|
26
|
+
* The standalone-site "no upstream-monorepo import" forbidden pattern, assembled
|
|
27
|
+
* from fragments so this source file does not itself contain the literal
|
|
28
|
+
* substring the repo's own `tools/lint-architecture.ts` forbids (a scaffolded
|
|
29
|
+
* SITE's boundary data, defined here, must not trip the harness's boundary lint
|
|
30
|
+
* — the same technique __tests__/security.test.ts uses for the Stripe-key rule).
|
|
31
|
+
*/
|
|
32
|
+
const NO_UPSTREAM_IMPORT_PATTERN = ["from '", "platform/"].join("");
|
|
33
|
+
/**
|
|
34
|
+
* The scheduling module's three credential-boundary patterns, assembled from
|
|
35
|
+
* fragments for the same reason as NO_UPSTREAM_IMPORT_PATTERN above: these are
|
|
36
|
+
* a scaffolded SITE's boundary DATA, and this repo's own
|
|
37
|
+
* `tools/lint-architecture.ts` matches raw source text — a literal here would
|
|
38
|
+
* read as create-ailk violating the very rules it is declaring.
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* The provider's domain, in any form. Deliberately the whole domain rather
|
|
42
|
+
* than just its REST host: the failure this module exists to prevent reached
|
|
43
|
+
* the provider through its embed script, served from a DIFFERENT subdomain,
|
|
44
|
+
* not through the API host at all.
|
|
45
|
+
*/
|
|
46
|
+
const CAL_DOMAIN_PATTERN = ["cal", "\\.com"].join("");
|
|
47
|
+
/** The provider's browser embed package — the iframe path, by import specifier. */
|
|
48
|
+
const CAL_EMBED_PACKAGE_PATTERN = ["@cal", "com/"].join("");
|
|
49
|
+
/**
|
|
50
|
+
* The credential's NAME, not a particular way of reading it. An earlier version
|
|
51
|
+
* matched `process.env[...]` and was trivially sidestepped by destructuring,
|
|
52
|
+
* optional chaining, or an aliased `env`; naming the variable catches all of
|
|
53
|
+
* them, and a file outside apps/api has no business mentioning it at all.
|
|
54
|
+
*/
|
|
55
|
+
const CAL_KEY_PATTERN = ["CAL", "_API_KEY"].join("");
|
|
56
|
+
/**
|
|
57
|
+
* Any browser-published scheduling variable, not just one spelling. Matching a
|
|
58
|
+
* single prefix missed the obvious variants (the provider's company name run
|
|
59
|
+
* together, "calendar", "booking"); the alternation below covers them while
|
|
60
|
+
* still not matching the locales variable, whose value contains those three
|
|
61
|
+
* letters but never followed by an underscore.
|
|
62
|
+
*/
|
|
63
|
+
const PUBLIC_SCHEDULING_VAR_PATTERN = [
|
|
64
|
+
"NEXT_PUBLIC_[A-Z0-9_]*(",
|
|
65
|
+
"CAL",
|
|
66
|
+
"_|CALCOM|CALENDAR|SCHEDUL|BOOKING)",
|
|
67
|
+
].join("");
|
|
68
|
+
/**
|
|
69
|
+
* The module-independent base: `apps/web` (the Next.js presentation shell every
|
|
70
|
+
* AILK site has) plus the standalone forbidden-pattern floor. `may_import_from`
|
|
71
|
+
* starts EMPTY — the selected modules fill it via `webImports`.
|
|
72
|
+
*/
|
|
73
|
+
export const ARCHITECTURE_BASE = {
|
|
74
|
+
version: 1,
|
|
75
|
+
composition_model: {
|
|
76
|
+
reference: "claude-setup rules/need-to-know.md § Vocabulary (Module / Surface)",
|
|
77
|
+
tiers: {
|
|
78
|
+
data: "database/ — Prisma schema + migrations",
|
|
79
|
+
api: "apps/api (public HTTP API) + apps/mcp (agent tools)",
|
|
80
|
+
presentation: "apps/web — frontend surfaces",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
/** The base apps/web shell. may_import_from is filled from the selected modules' webImports. */
|
|
84
|
+
web: {
|
|
85
|
+
path: "apps/web",
|
|
86
|
+
description: "Next.js — presentation tier. Frontend surfaces composed from the selected modules.",
|
|
87
|
+
may_not_import_from: ["apps/api", "apps/mcp"],
|
|
88
|
+
forbidden_patterns: [
|
|
89
|
+
{
|
|
90
|
+
pattern: NO_UPSTREAM_IMPORT_PATTERN,
|
|
91
|
+
reason: "A scaffolded AILK site is standalone — no upstream-monorepo imports",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
pattern: "@alkit/",
|
|
95
|
+
reason: "Renamed to @working-theory/* on extraction",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
/** Standalone-site forbidden-pattern floor (top-level, always present). */
|
|
100
|
+
forbiddenPatterns: [
|
|
101
|
+
{
|
|
102
|
+
pattern: NO_UPSTREAM_IMPORT_PATTERN,
|
|
103
|
+
reason: "A scaffolded AILK site is standalone — no upstream-monorepo imports anywhere",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
pattern: "import.*from ['\"]@alkit/",
|
|
107
|
+
reason: "Renamed to @working-theory/* on extraction; @alkit/ is a foreign namespace",
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* The per-module slices. Authored for every `RECOGNIZED_MODULES` value; only
|
|
113
|
+
* `marketing` (the default) is validated end-to-end against a golden.
|
|
114
|
+
*/
|
|
115
|
+
export const MODULE_SLICES = {
|
|
116
|
+
// ── marketing — thin presentation module (the default) ───────────────────
|
|
117
|
+
marketing: {
|
|
118
|
+
webImports: [
|
|
119
|
+
"packages/content-adapters",
|
|
120
|
+
"packages/jsonld",
|
|
121
|
+
"packages/metadata",
|
|
122
|
+
"packages/page-renderer",
|
|
123
|
+
"packages/schema",
|
|
124
|
+
"packages/sections-registry",
|
|
125
|
+
"packages/site-config",
|
|
126
|
+
"packages/theme",
|
|
127
|
+
"packages/ui",
|
|
128
|
+
"packages/validation",
|
|
129
|
+
"packages/web-i18n",
|
|
130
|
+
],
|
|
131
|
+
packages: {
|
|
132
|
+
"content-adapters": {
|
|
133
|
+
description: "MDX (default) + pluggable CMS content adapters",
|
|
134
|
+
may_import_from: ["packages/schema", "packages/validation"],
|
|
135
|
+
},
|
|
136
|
+
jsonld: {
|
|
137
|
+
description: "React component rendering schema.org JSON-LD on pages",
|
|
138
|
+
may_import_from: ["packages/schema"],
|
|
139
|
+
},
|
|
140
|
+
metadata: {
|
|
141
|
+
description: "Site metadata builders",
|
|
142
|
+
may_import_from: ["packages/validation"],
|
|
143
|
+
},
|
|
144
|
+
"page-renderer": {
|
|
145
|
+
description: "Composable page-render pipeline (frontmatter → JSON-LD → sections)",
|
|
146
|
+
may_import_from: [
|
|
147
|
+
"packages/content-adapters",
|
|
148
|
+
"packages/jsonld",
|
|
149
|
+
"packages/schema",
|
|
150
|
+
"packages/sections-registry",
|
|
151
|
+
"packages/ui",
|
|
152
|
+
"packages/validation",
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
schema: {
|
|
156
|
+
description: "schema.org JSON-LD builders",
|
|
157
|
+
may_import_from: ["packages/validation"],
|
|
158
|
+
},
|
|
159
|
+
"sections-registry": {
|
|
160
|
+
description: "Typed section catalog for the composable page types",
|
|
161
|
+
may_import_from: [
|
|
162
|
+
"packages/content-adapters",
|
|
163
|
+
"packages/schema",
|
|
164
|
+
"packages/theme",
|
|
165
|
+
"packages/ui",
|
|
166
|
+
"packages/validation",
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
"site-config": {
|
|
170
|
+
description: "Site-level configuration (siteName, baseUrl, site identity)",
|
|
171
|
+
may_import_from: ["packages/validation"],
|
|
172
|
+
},
|
|
173
|
+
theme: {
|
|
174
|
+
description: "Design tokens",
|
|
175
|
+
may_import_from: [],
|
|
176
|
+
},
|
|
177
|
+
ui: {
|
|
178
|
+
description: "React component hierarchy — primitives → blocks → sections",
|
|
179
|
+
may_import_from: [
|
|
180
|
+
"packages/schema",
|
|
181
|
+
"packages/sections-registry",
|
|
182
|
+
"packages/theme",
|
|
183
|
+
"packages/validation",
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
validation: {
|
|
187
|
+
description: "Zod schemas + shared types",
|
|
188
|
+
may_import_from: [],
|
|
189
|
+
},
|
|
190
|
+
"web-i18n": {
|
|
191
|
+
description: "Shared i18n helpers for web surfaces",
|
|
192
|
+
may_import_from: [],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
// ── docs — mountable presentation surface (fumadocs) ─────────────────────
|
|
197
|
+
docs: {
|
|
198
|
+
webImports: ["packages/fumadocs-schema"],
|
|
199
|
+
packages: {
|
|
200
|
+
"fumadocs-schema": {
|
|
201
|
+
description: "Fumadocs ↔ schema.org bridge — BlogList / DocsPage JSON-LD from Fumadocs MDX",
|
|
202
|
+
may_import_from: ["packages/schema", "packages/validation"],
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
// ownedFiles (S1, #5088). packages/fumadocs-schema/** is deliberately NOT
|
|
206
|
+
// listed: it is a JSON-LD bridge over the oss `packages/schema`, consumed
|
|
207
|
+
// by the Free `/blog` route, and was tiered `oss` in architecture.yaml
|
|
208
|
+
// (Sam, 2026-09-10, REL-015 #5182 Q3). The docs module owns its ROUTES,
|
|
209
|
+
// not that helper — the strip keeps the package in the public tree.
|
|
210
|
+
// (`webImports` above still names it, so a docs scaffold still installs it.)
|
|
211
|
+
//
|
|
212
|
+
// apps/web's own `/docs` catch-all route IS module-owned and IS listed
|
|
213
|
+
// (verified against the filesystem — it exists today, contrary to this
|
|
214
|
+
// slice's header comment suggesting docs may have "zero apps/web files
|
|
215
|
+
// today"). Its two closest neighbors are deliberately NOT listed, because
|
|
216
|
+
// both are genuinely mixed with the base `/blog` route rather than
|
|
217
|
+
// docs-exclusive (checked by reading each file in full):
|
|
218
|
+
// - apps/web/lib/source.ts — exports BOTH `blogSource` and
|
|
219
|
+
// `docsSource` from one file; `/blog` (base) needs the former.
|
|
220
|
+
// - apps/web/source.config.ts — defines BOTH the `blog` and `docs`
|
|
221
|
+
// Fumadocs collections in one `defineDocs` pair.
|
|
222
|
+
// A strip tool cannot delete either without breaking `/blog`, which ships
|
|
223
|
+
// in every OSS build regardless of the docs module. apps/web/content/en/docs/
|
|
224
|
+
// (the MDX content itself, not source) is also excluded — content, not code.
|
|
225
|
+
ownedFiles: ["apps/web/app/[locale]/docs/[[...slug]]/page.tsx"],
|
|
226
|
+
},
|
|
227
|
+
// ── multi-tenant — full-stack module (data + api + presentation) ─────────
|
|
228
|
+
//
|
|
229
|
+
// The FEAT-042 Organization → Workspace → Membership tenancy layer:
|
|
230
|
+
// schema (auth/content namespaces) + workspace-scoped API (apps/api) +
|
|
231
|
+
// the authed workspace app surface (apps/workspace). Single-tenant sites
|
|
232
|
+
// (module absent) ship none of this — same base apps/web, fixed scope.
|
|
233
|
+
"multi-tenant": {
|
|
234
|
+
apps: {
|
|
235
|
+
workspace: {
|
|
236
|
+
path: "apps/workspace",
|
|
237
|
+
description: "Next.js — authed workspace app (Organization → Workspace → Membership). Hosts the organization-plugin Better Auth handlers; imports the database only via lib/prisma-for-auth.ts (auth-adapter exception); all domain data via apps/api's workspace-scoped routes over HTTP.",
|
|
238
|
+
may_import_from: [
|
|
239
|
+
"database",
|
|
240
|
+
"packages/templates",
|
|
241
|
+
"packages/theme",
|
|
242
|
+
"packages/ui",
|
|
243
|
+
"packages/validation",
|
|
244
|
+
],
|
|
245
|
+
may_not_import_from: [
|
|
246
|
+
"apps/api",
|
|
247
|
+
"apps/mcp",
|
|
248
|
+
"apps/web",
|
|
249
|
+
"packages/email",
|
|
250
|
+
"packages/stripe-client",
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
api: {
|
|
254
|
+
path: "apps/api",
|
|
255
|
+
description: "Public HTTP API — routes + services (Fastify). Owns webhooks, checkout, email, server-side analytics.",
|
|
256
|
+
may_import_from: [
|
|
257
|
+
"database",
|
|
258
|
+
"packages/analytics",
|
|
259
|
+
"packages/email",
|
|
260
|
+
"packages/license",
|
|
261
|
+
"packages/schema",
|
|
262
|
+
"packages/site-config",
|
|
263
|
+
"packages/stripe-client",
|
|
264
|
+
"packages/validation",
|
|
265
|
+
],
|
|
266
|
+
may_not_import_from: [
|
|
267
|
+
"apps/mcp",
|
|
268
|
+
"apps/web",
|
|
269
|
+
"packages/theme",
|
|
270
|
+
"packages/ui",
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
mcp: {
|
|
274
|
+
path: "apps/mcp",
|
|
275
|
+
description: "MCP server — agent-facing tools. Calls apps/api for writes; never holds Stripe/email secrets.",
|
|
276
|
+
may_import_from: [
|
|
277
|
+
"database",
|
|
278
|
+
"packages/api-client",
|
|
279
|
+
"packages/license",
|
|
280
|
+
"packages/schema",
|
|
281
|
+
"packages/site-config",
|
|
282
|
+
"packages/validation",
|
|
283
|
+
],
|
|
284
|
+
may_not_import_from: [
|
|
285
|
+
"apps/api",
|
|
286
|
+
"apps/web",
|
|
287
|
+
"packages/email",
|
|
288
|
+
"packages/stripe-client",
|
|
289
|
+
"packages/theme",
|
|
290
|
+
"packages/ui",
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
packages: {
|
|
295
|
+
analytics: {
|
|
296
|
+
description: "Event wrapper — client + server analytics",
|
|
297
|
+
may_import_from: ["packages/validation"],
|
|
298
|
+
},
|
|
299
|
+
"api-client": {
|
|
300
|
+
description: "HTTP client (web + mcp → apps/api)",
|
|
301
|
+
may_import_from: ["packages/validation"],
|
|
302
|
+
},
|
|
303
|
+
email: {
|
|
304
|
+
description: "Email send + templates (provider-swappable adapter)",
|
|
305
|
+
may_import_from: ["packages/validation"],
|
|
306
|
+
},
|
|
307
|
+
license: {
|
|
308
|
+
description: "License-validation client",
|
|
309
|
+
may_import_from: ["packages/api-client", "packages/validation"],
|
|
310
|
+
},
|
|
311
|
+
"stripe-client": {
|
|
312
|
+
description: "Stripe SDK wrapper + webhook signature verification",
|
|
313
|
+
may_import_from: ["packages/validation"],
|
|
314
|
+
},
|
|
315
|
+
// apps/workspace presentation deps. templates is net-new here; theme/ui/
|
|
316
|
+
// validation duplicate the marketing slice's definitions VERBATIM so the
|
|
317
|
+
// Object.assign merge in deriveArchitecture is order-independent (a
|
|
318
|
+
// multi-tenant-only selection stays self-consistent).
|
|
319
|
+
templates: {
|
|
320
|
+
description: "Shell/Chrome composition — WorkspaceShell + ArtifactEditorShell (tier-5 shells)",
|
|
321
|
+
may_import_from: ["packages/theme", "packages/ui", "packages/validation"],
|
|
322
|
+
},
|
|
323
|
+
theme: {
|
|
324
|
+
description: "Design tokens",
|
|
325
|
+
may_import_from: [],
|
|
326
|
+
},
|
|
327
|
+
ui: {
|
|
328
|
+
description: "React component hierarchy — primitives → blocks → sections",
|
|
329
|
+
may_import_from: [
|
|
330
|
+
"packages/schema",
|
|
331
|
+
"packages/sections-registry",
|
|
332
|
+
"packages/theme",
|
|
333
|
+
"packages/validation",
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
validation: {
|
|
337
|
+
description: "Zod schemas + shared types",
|
|
338
|
+
may_import_from: [],
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
namespaces: {
|
|
342
|
+
description: "Per-namespace boundaries inside database/. Logical-only isolation; no Postgres-schema-level changes.",
|
|
343
|
+
members: {
|
|
344
|
+
auth: {
|
|
345
|
+
path: "database/auth",
|
|
346
|
+
description: "Identity, sessions, OAuth, agent context, tenancy membership (Organization / Workspace / Membership / Invitation)",
|
|
347
|
+
},
|
|
348
|
+
config: {
|
|
349
|
+
path: "database/config",
|
|
350
|
+
description: "Site-wide settings",
|
|
351
|
+
},
|
|
352
|
+
content: {
|
|
353
|
+
path: "database/content",
|
|
354
|
+
description: "Content-adapter persistence + chat/artifact substrate (AgentSession, ConversationEvent, Artifact — workspaceId-scoped, no cross-namespace FK)",
|
|
355
|
+
},
|
|
356
|
+
ops: {
|
|
357
|
+
path: "database/ops",
|
|
358
|
+
description: "AEO scores, audit log, analytics events",
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
rules: [
|
|
362
|
+
"No cross-namespace Prisma @relation.",
|
|
363
|
+
"No cross-namespace TS imports between database/<a>/ and database/<b>/.",
|
|
364
|
+
"Cross-namespace data assembly routes through apps/api/src/services/.",
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
forbiddenPatterns: [
|
|
368
|
+
{
|
|
369
|
+
pattern: "import.*['\"]stripe['\"]",
|
|
370
|
+
paths_excluded: ["packages/stripe-client/**"],
|
|
371
|
+
reason: "Stripe SDK imports go through packages/stripe-client only — single point of config",
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
pattern: "import.*['\"]resend['\"]|['\"]nodemailer['\"]",
|
|
375
|
+
paths_excluded: ["packages/email/**"],
|
|
376
|
+
reason: "Email provider SDKs go through packages/email — provider swap is a one-package change",
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
// ownedFiles (S1, #5088). Verified against the current filesystem and
|
|
380
|
+
// server.ts's module-conditional registration (isModuleEnabled('multi-tenant')).
|
|
381
|
+
//
|
|
382
|
+
// apps-paid/workspace/** is a single glob — the whole app (43 files as of
|
|
383
|
+
// this pass, excluding __tests__/node_modules), just moved here from
|
|
384
|
+
// apps/workspace by a parallel workstream on this same branch. Unlike
|
|
385
|
+
// every other entry below, this one is intentionally a glob, not an
|
|
386
|
+
// enumeration.
|
|
387
|
+
//
|
|
388
|
+
// apps/api/src/routes/project-listings/ is MIXED (free anonymous surface
|
|
389
|
+
// + tenant dashboard sharing one directory) — only the tenant-guarded
|
|
390
|
+
// trio is listed:
|
|
391
|
+
// - get.ts, list.ts, patch.ts — tenant-guarded (projectListingTenantRoutes)
|
|
392
|
+
// Deliberately EXCLUDED, all confirmed by reading server.ts + grepping
|
|
393
|
+
// every importer:
|
|
394
|
+
// - start.ts, patch-draft.ts, submit.ts, public.ts, resume-token.ts —
|
|
395
|
+
// the free anonymous surface (leadsScope in server.ts).
|
|
396
|
+
// resume-token.ts is imported ONLY by patch-draft.ts + submit.ts
|
|
397
|
+
// (both free) — free-surface-exclusive, not multi-tenant.
|
|
398
|
+
// - index.ts — the barrel BOTH leadsScope and tenantScope import from
|
|
399
|
+
// (projectListingStartRoute etc. AND projectListingTenantRoutes);
|
|
400
|
+
// never edited/deleted on its own per this card's constraint.
|
|
401
|
+
// - respond.ts — a `sendValidated` helper imported by get.ts/list.ts/
|
|
402
|
+
// patch.ts (tenant) AND ALSO by patch-draft.ts/public.ts (free) —
|
|
403
|
+
// shared within the directory across the free/paid split, so it stays.
|
|
404
|
+
//
|
|
405
|
+
// apps/api/src/routes/waitlist-experiments/respond.ts, by contrast, IS
|
|
406
|
+
// listed: grepped every `from "./respond.js"` importer in the repo and
|
|
407
|
+
// it is used ONLY by this directory's own comparison.ts/list.ts/signup.ts/
|
|
408
|
+
// signups.ts — all four tenant-scoped — so unlike its project-listings
|
|
409
|
+
// namesake it is NOT shared with a free route.
|
|
410
|
+
//
|
|
411
|
+
// apps/api/src/middleware/tenant.ts, services/tenant-context.ts,
|
|
412
|
+
// services/waitlist-dashboard.ts: each grepped for every importer
|
|
413
|
+
// repo-wide. tenant.ts is registered only in server.ts's tenantScope;
|
|
414
|
+
// tenant-context.ts backs only workspaces/tenant-guarded routes;
|
|
415
|
+
// waitlist-dashboard.ts backs only the four waitlist-experiments handlers
|
|
416
|
+
// above. None is reachable from a free route.
|
|
417
|
+
//
|
|
418
|
+
// apps/api/src/lib/tenant-db.ts and lib/ws-token.ts are an ADDITION beyond
|
|
419
|
+
// this card's literal checklist, found by tracing workspaces/*.ts's own
|
|
420
|
+
// imports: tenant-db.ts (the per-tenant Prisma-scoped client) is used only
|
|
421
|
+
// by services/tenant-context.ts and the three workspaces/*.ts route files
|
|
422
|
+
// below; ws-token.ts (realtime push-channel token minting) is used only
|
|
423
|
+
// by workspaces/sessions.ts. Both are genuinely tenant-exclusive by the
|
|
424
|
+
// same grep-every-importer standard applied to everything else here.
|
|
425
|
+
//
|
|
426
|
+
// NOT listed, deliberately, despite living in apps/api/src/services/ and
|
|
427
|
+
// being imported ONLY by billing/*.ts today: usage-aggregation.ts,
|
|
428
|
+
// usage-credits.ts, entitlements.ts, usage-metering.ts. Their names don't
|
|
429
|
+
// match this card's "tenant/workspace/org-specific" naming test, and
|
|
430
|
+
// apps/api/CLAUDE.md documents them as a standing "Services
|
|
431
|
+
// (billing-ledger)" concern rather than a module-conditional one (unlike
|
|
432
|
+
// every route registration this slice's other entries trace back to,
|
|
433
|
+
// which server.ts explicitly marks "Module-conditional (S1, #5088)").
|
|
434
|
+
// Their current single-caller status may just be incidental integration,
|
|
435
|
+
// not a documented module boundary — flagged for reviewer judgment
|
|
436
|
+
// rather than asserted here.
|
|
437
|
+
//
|
|
438
|
+
// database/auth/ and database/content/ — investigated, NOT listed.
|
|
439
|
+
// Both namespaces DO have their own schema.prisma file (a real
|
|
440
|
+
// filesystem split via Prisma's multi-file schema feature), but each
|
|
441
|
+
// file's CONTENTS are mixed at the model level, not module-exclusive:
|
|
442
|
+
// - database/auth/schema.prisma mixes base identity/session models
|
|
443
|
+
// (needed by every deployment) with the Organization/Workspace/
|
|
444
|
+
// Membership/Invitation tenancy models (multi-tenant only).
|
|
445
|
+
// - database/content/schema.prisma's models (AgentSession,
|
|
446
|
+
// ConversationEvent, Artifact, UsageEvent, ...) look workspace-scoped
|
|
447
|
+
// but billing-ledger models among them are not confirmed
|
|
448
|
+
// module-exclusive per the same caution as the services above.
|
|
449
|
+
// Consistent with this slice's own namespaces.members[].path (directory
|
|
450
|
+
// grain only): the boundary here is enforced at the Prisma-model level,
|
|
451
|
+
// not file grain, so it stays out of this literal list rather than
|
|
452
|
+
// asserting a split the evidence doesn't cleanly support.
|
|
453
|
+
ownedFiles: [
|
|
454
|
+
"apps/api/src/routes/workspaces/index.ts",
|
|
455
|
+
"apps/api/src/routes/workspaces/sessions.ts",
|
|
456
|
+
"apps/api/src/routes/workspaces/config.ts",
|
|
457
|
+
"apps/api/src/routes/billing/index.ts",
|
|
458
|
+
"apps/api/src/routes/billing/portal.ts",
|
|
459
|
+
"apps/api/src/routes/billing/read.ts",
|
|
460
|
+
"apps/api/src/routes/billing/usage.ts",
|
|
461
|
+
"apps/api/src/routes/waitlist-experiments/index.ts",
|
|
462
|
+
"apps/api/src/routes/waitlist-experiments/list.ts",
|
|
463
|
+
"apps/api/src/routes/waitlist-experiments/comparison.ts",
|
|
464
|
+
"apps/api/src/routes/waitlist-experiments/signup.ts",
|
|
465
|
+
"apps/api/src/routes/waitlist-experiments/signups.ts",
|
|
466
|
+
"apps/api/src/routes/waitlist-experiments/respond.ts",
|
|
467
|
+
"apps/api/src/routes/project-listings/get.ts",
|
|
468
|
+
"apps/api/src/routes/project-listings/list.ts",
|
|
469
|
+
"apps/api/src/routes/project-listings/patch.ts",
|
|
470
|
+
"apps/api/src/middleware/tenant.ts",
|
|
471
|
+
"apps/api/src/services/tenant-context.ts",
|
|
472
|
+
"apps/api/src/services/waitlist-dashboard.ts",
|
|
473
|
+
"apps/api/src/lib/tenant-db.ts",
|
|
474
|
+
"apps/api/src/lib/ws-token.ts",
|
|
475
|
+
"apps-paid/workspace/**",
|
|
476
|
+
],
|
|
477
|
+
},
|
|
478
|
+
// ── scheduling — full-stack module (provider + routes + booker pages) ────
|
|
479
|
+
//
|
|
480
|
+
// The #4416 scheduling seam, made installable. Three tiers into the
|
|
481
|
+
// marketing surface, no access model and no surface class of its own:
|
|
482
|
+
//
|
|
483
|
+
// data apps/api/src/services/scheduling/ — the provider client,
|
|
484
|
+
// the ONLY holder of the scheduling credential.
|
|
485
|
+
// api apps/api's own /v1/schedule/availability + /v1/schedule/book.
|
|
486
|
+
// presentation the `booker` section (packages/ui, no iframe) rendered by
|
|
487
|
+
// the `schedule` route surface, plus the module-owned
|
|
488
|
+
// confirmation page at /schedule/confirmed.
|
|
489
|
+
//
|
|
490
|
+
// The four forbidden patterns below are the module's whole security
|
|
491
|
+
// argument, restated as boundary rules rather than left in a comment: the
|
|
492
|
+
// credential belongs to apps/api and nowhere else, only the server tier
|
|
493
|
+
// addresses the provider, the provider's embed package is never imported at
|
|
494
|
+
// all, and no scheduling value is ever published to the browser as a
|
|
495
|
+
// `NEXT_PUBLIC_` variable.
|
|
496
|
+
//
|
|
497
|
+
// NOTE — a scaffolded site cannot run these yet. It receives
|
|
498
|
+
// `architecture.yaml` and a `package.json` whose `architecture` script names
|
|
499
|
+
// `tools/lint-architecture.ts`, but `build-templates.mjs` snapshots only
|
|
500
|
+
// `apps/` and `database/`, so `tools/` is absent. The rules are declarative
|
|
501
|
+
// there until the scaffold ships its linter; they ARE enforced in the AILK
|
|
502
|
+
// repo, whose own architecture.yaml carries the same four.
|
|
503
|
+
//
|
|
504
|
+
// The `api` block is a VERBATIM copy of multi-tenant's, deliberately. Two
|
|
505
|
+
// reasons: `deriveArchitecture` merges app blocks with `Object.assign`, so
|
|
506
|
+
// two slices declaring `api` differently would make the derivation depend on
|
|
507
|
+
// module order; and it is accurate — `apps/` is snapshotted whole, so a
|
|
508
|
+
// scheduling-bearing scaffold's `apps/api` really does contain the billing,
|
|
509
|
+
// checkout and email routes those imports are for.
|
|
510
|
+
scheduling: {
|
|
511
|
+
apps: {
|
|
512
|
+
api: {
|
|
513
|
+
path: "apps/api",
|
|
514
|
+
description: "Public HTTP API — routes + services (Fastify). Owns webhooks, checkout, email, server-side analytics.",
|
|
515
|
+
may_import_from: [
|
|
516
|
+
"database",
|
|
517
|
+
"packages/analytics",
|
|
518
|
+
"packages/email",
|
|
519
|
+
"packages/license",
|
|
520
|
+
"packages/schema",
|
|
521
|
+
"packages/site-config",
|
|
522
|
+
"packages/stripe-client",
|
|
523
|
+
"packages/validation",
|
|
524
|
+
],
|
|
525
|
+
may_not_import_from: [
|
|
526
|
+
"apps/mcp",
|
|
527
|
+
"apps/web",
|
|
528
|
+
"packages/theme",
|
|
529
|
+
"packages/ui",
|
|
530
|
+
],
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
packages: {
|
|
534
|
+
// Duplicated VERBATIM from the marketing slice for the same
|
|
535
|
+
// order-independence reason the multi-tenant slice states.
|
|
536
|
+
validation: {
|
|
537
|
+
description: "Zod schemas + shared types",
|
|
538
|
+
may_import_from: [],
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
forbiddenPatterns: [
|
|
542
|
+
{
|
|
543
|
+
pattern: CAL_KEY_PATTERN,
|
|
544
|
+
paths_excluded: ["apps/api/**"],
|
|
545
|
+
reason: "The scheduling credential belongs to apps/api. A file outside it has no reason to name the variable, let alone read it",
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
pattern: CAL_DOMAIN_PATTERN,
|
|
549
|
+
// The two server-side apps: apps/api holds the provider client, and
|
|
550
|
+
// apps/mcp's tools name booking links in their fixtures. Everything
|
|
551
|
+
// else — apps/web above all — is browser-reachable.
|
|
552
|
+
paths_excluded: ["apps/api/**", "apps/mcp/**"],
|
|
553
|
+
reason: "Only this site's server tier addresses the provider; every browser call goes to this site's own /v1/schedule/* routes instead",
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
pattern: CAL_EMBED_PACKAGE_PATTERN,
|
|
557
|
+
reason: "The provider's embed package is the iframe booker this module replaces — it hands the visitor to the provider's domain at the moment they convert",
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
pattern: PUBLIC_SCHEDULING_VAR_PATTERN,
|
|
561
|
+
reason: "A NEXT_PUBLIC_ variable is serialized into the page — no scheduling credential or provider config may ever be one",
|
|
562
|
+
},
|
|
563
|
+
],
|
|
564
|
+
// ownedFiles (S1, #5088). Verified against the current filesystem,
|
|
565
|
+
// server.ts's module-conditional registration (isModuleEnabled('scheduling')),
|
|
566
|
+
// and a repo-wide grep of every importer of each candidate file.
|
|
567
|
+
//
|
|
568
|
+
// apps/api/src/services/scheduling/index.ts, cal-provider.ts, types.ts —
|
|
569
|
+
// the whole directory; grepped `services/scheduling` repo-wide and the
|
|
570
|
+
// ONLY importer outside its own __tests__/ is routes/schedule/index.ts,
|
|
571
|
+
// so no sibling error-type file exists elsewhere to add.
|
|
572
|
+
//
|
|
573
|
+
// packages/ui's Booker* components ARE listed individually (not a glob):
|
|
574
|
+
// every non-test, non-stories file whose name starts `Booker` under
|
|
575
|
+
// packages/ui/src/sections/ and packages/ui/src/blocks/. These live
|
|
576
|
+
// inside a package that marketing ALSO imports wholesale, but each of
|
|
577
|
+
// these particular files is scheduling-exclusive UI with no other
|
|
578
|
+
// consumer — unlike packages/validation below, a strip tool CAN delete
|
|
579
|
+
// exactly these files without touching anything another module needs.
|
|
580
|
+
//
|
|
581
|
+
// BOTH apps/web/app/[locale]/schedule pages are listed (#5182 Q9, disposed
|
|
582
|
+
// 2026-09-11). confirmed/page.tsx says outright in its own doc comment that
|
|
583
|
+
// "The module OWNS this page... a scaffold without the module has no such
|
|
584
|
+
// route", and its sibling page.tsx is the SOLE production constructor of a
|
|
585
|
+
// `booker` section: it builds the section literally in TypeScript
|
|
586
|
+
// (page.tsx:60, `type: "booker"`) rather than reading it from content, and
|
|
587
|
+
// its own header calls the route API-backed with "no content file that
|
|
588
|
+
// could disagree with the calendar". The create-ailk scaffolder already
|
|
589
|
+
// gates the whole `schedule` route surface (src/surfaces.ts), so the two
|
|
590
|
+
// pages arrive and depart together.
|
|
591
|
+
//
|
|
592
|
+
// packages/sections-registry/src/registry.ts (the `booker:` entry) and
|
|
593
|
+
// packages/validation/src/schemas/page-sections.ts (BookerSectionDataSchema,
|
|
594
|
+
// line ~2870) are investigated and EXCLUDED for the same reason as
|
|
595
|
+
// packages/validation below: each is one shared, multi-hundred-schema
|
|
596
|
+
// file serving every section type across every module, not a
|
|
597
|
+
// scheduling-owned file.
|
|
598
|
+
//
|
|
599
|
+
// packages/validation/src/schemas/scheduling.ts is the canonical home of
|
|
600
|
+
// listAvailabilityShape / createBookingShape / getEventMetaShape (its own
|
|
601
|
+
// doc comment names it as the shared vocabulary across apps/api, apps/mcp,
|
|
602
|
+
// packages/api-client, and packages/ui) — found via
|
|
603
|
+
// `grep -rl BookerSectionDataSchema\|listAvailabilityShape... packages/validation/src`.
|
|
604
|
+
// Per this card's explicit instruction it is NOT added to ownedFiles even
|
|
605
|
+
// though it is single-purpose: packages/validation is declared a shared
|
|
606
|
+
// kernel package (see this slice's own `packages.validation` entry above,
|
|
607
|
+
// "duplicated VERBATIM across slices for order-independence") and a strip
|
|
608
|
+
// tool must not delete a file another module also needs at runtime.
|
|
609
|
+
//
|
|
610
|
+
// packages/api-client/src/schedule.ts — found while reading
|
|
611
|
+
// list_availability.ts's imports; the MCP twins call apps/api through it.
|
|
612
|
+
// Treated the SAME as packages/validation/src/schemas/scheduling.ts and
|
|
613
|
+
// excluded for the same reason (packages/api-client is declared as
|
|
614
|
+
// shared HTTP-client infrastructure — see multi-tenant.packages["api-client"]
|
|
615
|
+
// above — not scheduling-owned), even though this file's content is
|
|
616
|
+
// scheduling-specific. This is a judgment call, not covered by this
|
|
617
|
+
// card's explicit checklist: flagged for reviewer confirmation.
|
|
618
|
+
//
|
|
619
|
+
// `packages/ui/src/sections/slices/scheduling.ts` (#5214) is the slice's own
|
|
620
|
+
// registration entry point: it statically imports Booker and registers it as
|
|
621
|
+
// the `booker` renderer, so it is the one file inside packages/ui that may
|
|
622
|
+
// reach a scheduling component — because it strips alongside them. The three
|
|
623
|
+
// files that path added on the OSS side — `SectionRenderer.tsx`,
|
|
624
|
+
// `slice-renderers.ts` and `ModuleAbsent.tsx` — are deliberately NOT listed
|
|
625
|
+
// here: they ship, and listing one would take the whole dispatch table with it.
|
|
626
|
+
ownedFiles: [
|
|
627
|
+
"apps/api/src/routes/schedule/index.ts",
|
|
628
|
+
"apps/api/src/services/scheduling/index.ts",
|
|
629
|
+
"apps/api/src/services/scheduling/cal-provider.ts",
|
|
630
|
+
"apps/api/src/services/scheduling/types.ts",
|
|
631
|
+
"apps/mcp/src/tools/list_availability.ts",
|
|
632
|
+
"apps/mcp/src/tools/get_event_meta.ts",
|
|
633
|
+
"apps/mcp/src/tools/create_booking.ts",
|
|
634
|
+
"packages/ui/src/sections/Booker.tsx",
|
|
635
|
+
"packages/ui/src/sections/BookerIsland.tsx",
|
|
636
|
+
"packages/ui/src/blocks/BookerPanel.tsx",
|
|
637
|
+
"packages/ui/src/blocks/BookerSlotGrid.tsx",
|
|
638
|
+
"packages/ui/src/blocks/BookerAttendeeFields.tsx",
|
|
639
|
+
"packages/ui/src/blocks/BookerEventHeader.tsx",
|
|
640
|
+
"packages/ui/src/blocks/BookerDateStrip.tsx",
|
|
641
|
+
"packages/ui/src/sections/slices/scheduling.ts",
|
|
642
|
+
"apps/web/app/[locale]/schedule/page.tsx",
|
|
643
|
+
"apps/web/app/[locale]/schedule/confirmed/page.tsx",
|
|
644
|
+
],
|
|
645
|
+
},
|
|
646
|
+
};
|
|
647
|
+
/**
|
|
648
|
+
* Normalize a requested module list to the unique set, ordered by the canonical
|
|
649
|
+
* `RECOGNIZED_MODULES` sequence — so the derivation is a pure function of the
|
|
650
|
+
* SET, independent of input order (`['docs','marketing']` ≡ `['marketing','docs']`).
|
|
651
|
+
*
|
|
652
|
+
* @throws Error on an unrecognized module (a defensive backstop; `parse-args`
|
|
653
|
+
* rejects unrecognized values upstream before they reach derivation).
|
|
654
|
+
*/
|
|
655
|
+
export function normalizeModules(modules) {
|
|
656
|
+
const requested = new Set(modules.map((m) => m.trim().toLowerCase()));
|
|
657
|
+
for (const m of requested) {
|
|
658
|
+
if (!RECOGNIZED_MODULES.includes(m)) {
|
|
659
|
+
throw new Error(`unknown module "${m}". Recognized: ${RECOGNIZED_MODULES.join(", ")}`);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return RECOGNIZED_MODULES.filter((m) => requested.has(m));
|
|
663
|
+
}
|