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.
Files changed (605) hide show
  1. package/README.md +124 -3
  2. package/component-catalog.md +295 -0
  3. package/dist/cli.js +92 -16
  4. package/dist/component-catalog.d.ts +11 -0
  5. package/dist/component-catalog.js +39 -0
  6. package/dist/copy.d.ts +7 -0
  7. package/dist/copy.js +24 -0
  8. package/dist/derive-architecture.d.ts +13 -0
  9. package/dist/derive-architecture.js +238 -0
  10. package/dist/index.d.ts +7 -2
  11. package/dist/index.js +19 -2
  12. package/dist/lib/extract-module-bundle.d.ts +16 -0
  13. package/dist/lib/extract-module-bundle.js +184 -0
  14. package/dist/lib/fetch-module.d.ts +55 -0
  15. package/dist/lib/fetch-module.js +125 -0
  16. package/dist/lib/module-license-gate.d.ts +48 -0
  17. package/dist/lib/module-license-gate.js +67 -0
  18. package/dist/lib/module-tier.d.ts +35 -0
  19. package/dist/lib/module-tier.js +37 -0
  20. package/dist/module-architecture.d.ts +175 -0
  21. package/dist/module-architecture.js +663 -0
  22. package/dist/parse-args.d.ts +47 -1
  23. package/dist/parse-args.js +143 -2
  24. package/dist/programmatic.d.ts +160 -3
  25. package/dist/programmatic.js +196 -7
  26. package/dist/surfaces.d.ts +211 -0
  27. package/dist/surfaces.js +532 -0
  28. package/dist/sync-routes.d.ts +92 -0
  29. package/dist/sync-routes.js +350 -0
  30. package/package.json +22 -14
  31. package/templates/.claude/rules/architecture.md +6 -2
  32. package/templates/.claude/skills/README.md +9 -9
  33. package/templates/.claude/skills/add-schema/SKILL.md +14 -7
  34. package/templates/.claude/skills/add-schema/references/schema-types.md +109 -6
  35. package/templates/.claude/skills/provision-config/SKILL.md +1 -1
  36. package/templates/.claude/skills/scaffold-commerce/SKILL.md +498 -1
  37. package/templates/.claude/skills/scaffold-commerce/templates/checkout-route.template.ts +370 -0
  38. package/templates/.claude/skills/scaffold-commerce/templates/invoice-route.template.ts +376 -0
  39. package/templates/.claude/skills/scaffold-commerce/templates/payment-link-route.template.ts +471 -0
  40. package/templates/.claude/skills/scaffold-commerce/templates/portal-route.template.ts +365 -0
  41. package/templates/.claude/skills/scaffold-commerce/templates/stripe-config.template.ts +60 -0
  42. package/templates/.claude/skills/scaffold-commerce/templates/subscription-route.template.ts +446 -0
  43. package/templates/.claude/skills/suggest-site-pages/references/categories.md +4 -4
  44. package/templates/.env.example +126 -2
  45. package/templates/CLAUDE.md +11 -5
  46. package/templates/README.md +1 -1
  47. package/templates/apps/api/.env.example +38 -0
  48. package/templates/apps/api/CLAUDE.md +75 -1
  49. package/templates/apps/api/LICENSE +201 -0
  50. package/templates/apps/api/api/index.ts +6 -141
  51. package/templates/apps/api/jest.config.cjs +16 -0
  52. package/templates/apps/api/package.json +22 -6
  53. package/templates/apps/api/src/__tests__/module-exclusion.test.ts +141 -0
  54. package/templates/apps/api/src/__tests__/server.test.ts +46 -0
  55. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +211 -0
  56. package/templates/apps/api/src/bin/abandon-sweep.ts +42 -0
  57. package/templates/apps/api/src/bin/deliverable-resend.ts +144 -0
  58. package/templates/apps/api/src/bin/deliverable-upload.ts +114 -0
  59. package/templates/apps/api/src/bin/followup-sweep.ts +44 -0
  60. package/templates/apps/api/src/bin/listing-csv-sweep.ts +46 -0
  61. package/templates/apps/api/src/bin/seed-presets.ts +58 -0
  62. package/templates/apps/api/src/bin/seed-waitlist-experiments.ts +104 -0
  63. package/templates/apps/api/src/bin/session-retention-sweep.ts +46 -0
  64. package/templates/apps/api/src/cli.ts +5 -11
  65. package/templates/apps/api/src/config/index.ts +35 -0
  66. package/templates/apps/api/src/config/modules.ts +43 -0
  67. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +11 -0
  68. package/templates/apps/api/src/lib/__mocks__/prisma.ts +231 -0
  69. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +2 -2
  70. package/templates/apps/api/src/lib/site.ts +16 -0
  71. package/templates/apps/api/src/lib/stripe.ts +22 -0
  72. package/templates/apps/api/src/lib/tenant-db.ts +225 -0
  73. package/templates/apps/api/src/lib/ws-token.ts +91 -0
  74. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +7 -1
  75. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +7 -1
  76. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +91 -4
  77. package/templates/apps/api/src/middleware/auth.ts +43 -8
  78. package/templates/apps/api/src/middleware/rate-limit.ts +78 -3
  79. package/templates/apps/api/src/middleware/tenant.ts +99 -0
  80. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +92 -0
  81. package/templates/apps/api/src/openapi/spec.ts +312 -3
  82. package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +175 -0
  83. package/templates/apps/api/src/routes/aeo/index.ts +107 -0
  84. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +5 -2
  85. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +22 -3
  86. package/templates/apps/api/src/routes/auth/tokens.ts +13 -1
  87. package/templates/apps/api/src/routes/billing/__tests__/portal.test.ts +450 -0
  88. package/templates/apps/api/src/routes/billing/__tests__/read.test.ts +262 -0
  89. package/templates/apps/api/src/routes/billing/__tests__/usage.test.ts +436 -0
  90. package/templates/apps/api/src/routes/billing/index.ts +36 -0
  91. package/templates/apps/api/src/routes/billing/portal.ts +182 -0
  92. package/templates/apps/api/src/routes/billing/read.ts +75 -0
  93. package/templates/apps/api/src/routes/billing/usage.ts +153 -0
  94. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +99 -0
  95. package/templates/apps/api/src/routes/checkout/sessions.ts +20 -8
  96. package/templates/apps/api/src/routes/content/create.ts +1 -0
  97. package/templates/apps/api/src/routes/content/delete.ts +1 -0
  98. package/templates/apps/api/src/routes/content/index.ts +42 -6
  99. package/templates/apps/api/src/routes/content/update.ts +1 -0
  100. package/templates/apps/api/src/routes/deliverables/__tests__/index.test.ts +393 -0
  101. package/templates/apps/api/src/routes/deliverables/index.ts +200 -0
  102. package/templates/apps/api/src/routes/flow-checkouts/__tests__/index.test.ts +443 -0
  103. package/templates/apps/api/src/routes/flow-checkouts/index.ts +82 -0
  104. package/templates/apps/api/src/routes/flows/README.md +147 -0
  105. package/templates/apps/api/src/routes/flows/__tests__/index.test.ts +752 -0
  106. package/templates/apps/api/src/routes/flows/__tests__/recommender.test.ts +671 -0
  107. package/templates/apps/api/src/routes/flows/index.ts +202 -0
  108. package/templates/apps/api/src/routes/flows/recommender.ts +443 -0
  109. package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +438 -31
  110. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +10 -10
  111. package/templates/apps/api/src/routes/leads/index.ts +43 -9
  112. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +547 -0
  113. package/templates/apps/api/src/routes/project-listings/__tests__/copy-edit.test.ts +815 -0
  114. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +742 -0
  115. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +424 -0
  116. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +364 -0
  117. package/templates/apps/api/src/routes/project-listings/__tests__/tenant-isolation.test.ts +566 -0
  118. package/templates/apps/api/src/routes/project-listings/get.ts +70 -0
  119. package/templates/apps/api/src/routes/project-listings/index.ts +105 -0
  120. package/templates/apps/api/src/routes/project-listings/list.ts +47 -0
  121. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +222 -0
  122. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +97 -0
  123. package/templates/apps/api/src/routes/project-listings/patch.ts +136 -0
  124. package/templates/apps/api/src/routes/project-listings/public.ts +52 -0
  125. package/templates/apps/api/src/routes/project-listings/respond.ts +37 -0
  126. package/templates/apps/api/src/routes/project-listings/resume-token.ts +22 -0
  127. package/templates/apps/api/src/routes/project-listings/start.ts +98 -0
  128. package/templates/apps/api/src/routes/project-listings/submit.ts +122 -0
  129. package/templates/apps/api/src/routes/schedule/__tests__/index.test.ts +490 -0
  130. package/templates/apps/api/src/routes/schedule/index.ts +249 -0
  131. package/templates/apps/api/src/routes/slack/__tests__/actions.test.ts +385 -0
  132. package/templates/apps/api/src/routes/slack/actions.ts +177 -0
  133. package/templates/apps/api/src/routes/slack/index.ts +38 -0
  134. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +16 -6
  135. package/templates/apps/api/src/routes/test/auth/session.ts +8 -6
  136. package/templates/apps/api/src/routes/waitlist-experiments/__tests__/tenant-isolation.test.ts +577 -0
  137. package/templates/apps/api/src/routes/waitlist-experiments/comparison.ts +78 -0
  138. package/templates/apps/api/src/routes/waitlist-experiments/index.ts +41 -0
  139. package/templates/apps/api/src/routes/waitlist-experiments/list.ts +64 -0
  140. package/templates/apps/api/src/routes/waitlist-experiments/respond.ts +42 -0
  141. package/templates/apps/api/src/routes/waitlist-experiments/signup.ts +84 -0
  142. package/templates/apps/api/src/routes/waitlist-experiments/signups.ts +119 -0
  143. package/templates/apps/api/src/routes/waitlist-signups/__tests__/index.test.ts +238 -0
  144. package/templates/apps/api/src/routes/waitlist-signups/index.ts +101 -0
  145. package/templates/apps/api/src/routes/webhooks/README.md +35 -12
  146. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +315 -0
  147. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +270 -0
  148. package/templates/apps/api/src/routes/webhooks/stripe.ts +248 -20
  149. package/templates/apps/api/src/routes/workspaces/__tests__/config-tenant-isolation.test.ts +356 -0
  150. package/templates/apps/api/src/routes/workspaces/__tests__/tenant-isolation.test.ts +671 -0
  151. package/templates/apps/api/src/routes/workspaces/config.ts +125 -0
  152. package/templates/apps/api/src/routes/workspaces/index.ts +194 -0
  153. package/templates/apps/api/src/routes/workspaces/sessions.ts +218 -0
  154. package/templates/apps/api/src/server.ts +293 -7
  155. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +489 -0
  156. package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +475 -0
  157. package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +132 -0
  158. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +523 -0
  159. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +359 -0
  160. package/templates/apps/api/src/services/__tests__/entitlements.test.ts +142 -0
  161. package/templates/apps/api/src/services/__tests__/flow-aggregate.test.ts +425 -0
  162. package/templates/apps/api/src/services/__tests__/flow-engine.test.ts +2840 -0
  163. package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +393 -0
  164. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +8 -8
  165. package/templates/apps/api/src/services/__tests__/listing-csv-sweep.test.ts +560 -0
  166. package/templates/apps/api/src/services/__tests__/playbook-compile.test.ts +406 -0
  167. package/templates/apps/api/src/services/__tests__/playbook-render.test.ts +290 -0
  168. package/templates/apps/api/src/services/__tests__/project-listing-decision.test.ts +736 -0
  169. package/templates/apps/api/src/services/__tests__/project-listing-flow.test.ts +475 -0
  170. package/templates/apps/api/src/services/__tests__/project-listing-issue.test.ts +340 -0
  171. package/templates/apps/api/src/services/__tests__/recommender-capture.test.ts +983 -0
  172. package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +278 -0
  173. package/templates/apps/api/src/services/__tests__/tenant-context-cascade.test.ts +71 -0
  174. package/templates/apps/api/src/services/__tests__/tenant-context.test.ts +379 -0
  175. package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +941 -0
  176. package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +588 -0
  177. package/templates/apps/api/src/services/__tests__/usage-metering.test.ts +768 -0
  178. package/templates/apps/api/src/services/__tests__/waitlist-dashboard.test.ts +1314 -0
  179. package/templates/apps/api/src/services/__tests__/waitlist-experiments.test.ts +341 -0
  180. package/templates/apps/api/src/services/__tests__/waitlist-followup.test.ts +567 -0
  181. package/templates/apps/api/src/services/__tests__/waitlist-scoring.test.ts +474 -0
  182. package/templates/apps/api/src/services/__tests__/waitlist-signups.test.ts +354 -0
  183. package/templates/apps/api/src/services/abandon-email.ts +307 -0
  184. package/templates/apps/api/src/services/aeo-score.ts +288 -0
  185. package/templates/apps/api/src/services/answer-distributions.ts +138 -0
  186. package/templates/apps/api/src/services/deliverable-fulfillment.ts +523 -0
  187. package/templates/apps/api/src/services/entitlements.ts +102 -0
  188. package/templates/apps/api/src/services/flow-aggregate.ts +232 -0
  189. package/templates/apps/api/src/services/flow-checkouts.ts +123 -0
  190. package/templates/apps/api/src/services/flow-engine.ts +1278 -0
  191. package/templates/apps/api/src/services/lead-promotion.ts +176 -0
  192. package/templates/apps/api/src/services/lead-routing.ts +3 -3
  193. package/templates/apps/api/src/services/listing-config.ts +102 -0
  194. package/templates/apps/api/src/services/listing-csv-sweep.ts +455 -0
  195. package/templates/apps/api/src/services/playbook-compile.ts +398 -0
  196. package/templates/apps/api/src/services/playbook-render.ts +263 -0
  197. package/templates/apps/api/src/services/project-listing-decision.ts +490 -0
  198. package/templates/apps/api/src/services/project-listing-flow.ts +426 -0
  199. package/templates/apps/api/src/services/project-listing-issue.ts +251 -0
  200. package/templates/apps/api/src/services/project-listings.ts +1124 -0
  201. package/templates/apps/api/src/services/recommender-capture.ts +835 -0
  202. package/templates/apps/api/src/services/scheduling/cal-provider.ts +392 -0
  203. package/templates/apps/api/src/services/scheduling/index.ts +63 -0
  204. package/templates/apps/api/src/services/scheduling/types.ts +88 -0
  205. package/templates/apps/api/src/services/slack-notify.ts +240 -0
  206. package/templates/apps/api/src/services/tenant-context.ts +451 -0
  207. package/templates/apps/api/src/services/usage-aggregation.ts +516 -0
  208. package/templates/apps/api/src/services/usage-credits.ts +340 -0
  209. package/templates/apps/api/src/services/usage-metering.ts +699 -0
  210. package/templates/apps/api/src/services/waitlist-dashboard.ts +947 -0
  211. package/templates/apps/api/src/services/waitlist-experiments.ts +213 -0
  212. package/templates/apps/api/src/services/waitlist-followup.ts +486 -0
  213. package/templates/apps/api/src/services/waitlist-scoring.ts +166 -0
  214. package/templates/apps/api/src/services/waitlist-signups.ts +165 -0
  215. package/templates/apps/api/src/vercel-handler.ts +165 -0
  216. package/templates/apps/api/tsconfig.json +0 -12
  217. package/templates/apps/mcp/CLAUDE.md +19 -9
  218. package/templates/apps/mcp/LICENSE +201 -0
  219. package/templates/apps/mcp/__tests__/create_page.test.ts +1 -0
  220. package/templates/apps/mcp/__tests__/delete_page.test.ts +1 -0
  221. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +105 -0
  222. package/templates/apps/mcp/__tests__/parity.test.ts +70 -6
  223. package/templates/apps/mcp/__tests__/request_callback.test.ts +4 -4
  224. package/templates/apps/mcp/__tests__/schedule_tools.test.ts +242 -0
  225. package/templates/apps/mcp/__tests__/submit_lead.test.ts +4 -4
  226. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +4 -4
  227. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +47 -0
  228. package/templates/apps/mcp/__tests__/update_page.test.ts +1 -0
  229. package/templates/apps/mcp/package.json +6 -4
  230. package/templates/apps/mcp/src/config/modules.ts +37 -0
  231. package/templates/apps/mcp/src/server.ts +109 -18
  232. package/templates/apps/mcp/src/tools/capture_lead.ts +1 -1
  233. package/templates/apps/mcp/src/tools/create_booking.ts +58 -0
  234. package/templates/apps/mcp/src/tools/create_page.ts +1 -0
  235. package/templates/apps/mcp/src/tools/delete_page.ts +1 -0
  236. package/templates/apps/mcp/src/tools/get_event_meta.ts +55 -0
  237. package/templates/apps/mcp/src/tools/get_flow.ts +61 -0
  238. package/templates/apps/mcp/src/tools/index.ts +25 -0
  239. package/templates/apps/mcp/src/tools/list_availability.ts +67 -0
  240. package/templates/apps/mcp/src/tools/purchase.ts +3 -0
  241. package/templates/apps/mcp/src/tools/submit_flow_step.ts +83 -0
  242. package/templates/apps/mcp/src/tools/update_page.ts +1 -0
  243. package/templates/apps/mcp/tsconfig.json +1 -9
  244. package/templates/apps/web/.env.example +44 -0
  245. package/templates/apps/web/CLAUDE.md +28 -0
  246. package/templates/apps/web/LICENSE +201 -0
  247. package/templates/apps/web/__tests__/__mocks__/code-highlight.jest-stub.ts +24 -0
  248. package/templates/apps/web/__tests__/__mocks__/next-intl-server.ts +33 -0
  249. package/templates/apps/web/__tests__/__mocks__/next-intl.ts +18 -0
  250. package/templates/apps/web/__tests__/__mocks__/server-only.ts +13 -0
  251. package/templates/apps/web/__tests__/__mocks__/style-mock.js +4 -0
  252. package/templates/apps/web/__tests__/__mocks__/vercel-analytics-server.ts +9 -0
  253. package/templates/apps/web/__tests__/jest-support/import-meta-transformer.cjs +90 -0
  254. package/templates/apps/web/__tests__/setup.ts +22 -32
  255. package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +6 -3
  256. package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +8 -2
  257. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +260 -0
  258. package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +263 -0
  259. package/templates/apps/web/app/[locale]/(authed)/account/sign-out-button.tsx +39 -0
  260. package/templates/apps/web/app/[locale]/(authed)/layout.tsx +54 -0
  261. package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +96 -0
  262. package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/page.tsx +309 -0
  263. package/templates/apps/web/app/[locale]/(authed)/waitlist/[experimentId]/signups/[leadId]/page.tsx +149 -0
  264. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/comparison.test.tsx +273 -0
  265. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/gate.test.tsx +172 -0
  266. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/list.test.tsx +171 -0
  267. package/templates/apps/web/app/[locale]/(authed)/waitlist/__tests__/signup.test.tsx +179 -0
  268. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ExperimentsTable.tsx +116 -0
  269. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ForbiddenState.tsx +24 -0
  270. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/OfferFunnelTable.tsx +66 -0
  271. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/RollupTicker.tsx +61 -0
  272. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/ScoreTrace.tsx +114 -0
  273. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx +139 -0
  274. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx +85 -0
  275. package/templates/apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx +67 -0
  276. package/templates/apps/web/app/[locale]/(authed)/waitlist/format.ts +111 -0
  277. package/templates/apps/web/app/[locale]/(authed)/waitlist/page.tsx +179 -0
  278. package/templates/apps/web/app/[locale]/about/page.tsx +10 -1
  279. package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +6 -1
  280. package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +9 -0
  281. package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +3 -3
  282. package/templates/apps/web/app/[locale]/careers/page.tsx +9 -1
  283. package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +9 -0
  284. package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +3 -3
  285. package/templates/apps/web/app/[locale]/case-studies/page.tsx +13 -1
  286. package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +11 -1
  287. package/templates/apps/web/app/[locale]/clients/page.tsx +9 -1
  288. package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +21 -1
  289. package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +188 -0
  290. package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +242 -0
  291. package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +29 -0
  292. package/templates/apps/web/app/[locale]/contact/__tests__/intake-analytics.test.ts +51 -0
  293. package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +39 -15
  294. package/templates/apps/web/app/[locale]/contact/contact.actions.ts +21 -3
  295. package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +49 -0
  296. package/templates/apps/web/app/[locale]/contact/intake-script.ts +66 -0
  297. package/templates/apps/web/app/[locale]/contact/page.tsx +14 -4
  298. package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +13 -1
  299. package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +3 -3
  300. package/templates/apps/web/app/[locale]/courses/page.tsx +9 -1
  301. package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +1 -0
  302. package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +11 -1
  303. package/templates/apps/web/app/[locale]/downloads/page.tsx +13 -1
  304. package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +9 -0
  305. package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +12 -2
  306. package/templates/apps/web/app/[locale]/events/page.tsx +9 -1
  307. package/templates/apps/web/app/[locale]/faq/page.tsx +10 -1
  308. package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +265 -0
  309. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +445 -0
  310. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +341 -0
  311. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/checkout.actions.test.ts +287 -0
  312. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/flow.actions.test.ts +302 -0
  313. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/two-route-tool.test.tsx +128 -0
  314. package/templates/apps/web/app/[locale]/flows/[slug]/checkout.actions.ts +254 -0
  315. package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +144 -0
  316. package/templates/apps/web/app/[locale]/flows/[slug]/page.tsx +108 -0
  317. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx +532 -0
  318. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsEmailStep.tsx +121 -0
  319. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/ResultsClient.checkout.test.tsx +457 -0
  320. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/page.test.tsx +396 -0
  321. package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx +114 -0
  322. package/templates/apps/web/app/[locale]/flows/[slug]/start/page.tsx +52 -0
  323. package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +13 -1
  324. package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
  325. package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +9 -0
  326. package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +3 -3
  327. package/templates/apps/web/app/[locale]/integrations/page.tsx +13 -1
  328. package/templates/apps/web/app/[locale]/launch-service/page.tsx +14 -1
  329. package/templates/apps/web/app/[locale]/layout.tsx +115 -16
  330. package/templates/apps/web/app/[locale]/page.tsx +10 -1
  331. package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +9 -0
  332. package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +3 -3
  333. package/templates/apps/web/app/[locale]/partners/page.tsx +9 -1
  334. package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +9 -0
  335. package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +3 -3
  336. package/templates/apps/web/app/[locale]/products/page.tsx +9 -1
  337. package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +13 -1
  338. package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +10 -0
  339. package/templates/apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx +110 -0
  340. package/templates/apps/web/app/[locale]/projects/apply/__tests__/ListingApplicationClient.test.tsx +96 -0
  341. package/templates/apps/web/app/[locale]/projects/page.tsx +13 -1
  342. package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +9 -0
  343. package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +12 -2
  344. package/templates/apps/web/app/[locale]/resources/page.tsx +13 -1
  345. package/templates/apps/web/app/[locale]/schedule/__tests__/page.test.tsx +117 -0
  346. package/templates/apps/web/app/[locale]/schedule/confirmed/__tests__/page.test.tsx +96 -0
  347. package/templates/apps/web/app/[locale]/schedule/confirmed/page.tsx +92 -0
  348. package/templates/apps/web/app/[locale]/schedule/page.tsx +82 -0
  349. package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +9 -0
  350. package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +3 -3
  351. package/templates/apps/web/app/[locale]/services/page.tsx +9 -1
  352. package/templates/apps/web/app/[locale]/sign-in/__tests__/next-path.test.ts +31 -0
  353. package/templates/apps/web/app/[locale]/sign-in/__tests__/page.test.tsx +152 -0
  354. package/templates/apps/web/app/[locale]/sign-in/next-path.ts +0 -0
  355. package/templates/apps/web/app/[locale]/sign-in/page.tsx +83 -0
  356. package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +123 -0
  357. package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +13 -1
  358. package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
  359. package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +13 -1
  360. package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
  361. package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +11 -1
  362. package/templates/apps/web/app/[locale]/testimonials/page.tsx +13 -1
  363. package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/page.test.tsx +93 -0
  364. package/templates/apps/web/app/[locale]/thanks/[slug]/page.tsx +48 -0
  365. package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +11 -1
  366. package/templates/apps/web/app/[locale]/use-cases/page.tsx +13 -1
  367. package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +13 -1
  368. package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
  369. package/templates/apps/web/app/globals.css +35 -0
  370. package/templates/apps/web/app/llms.txt/route.ts +2 -1
  371. package/templates/apps/web/app/og/route.tsx +10 -2
  372. package/templates/apps/web/auth.ts +8 -0
  373. package/templates/apps/web/components/sign-out-trigger.tsx +42 -0
  374. package/templates/apps/web/content/en/blog/README.txt +25 -0
  375. package/templates/apps/web/content/en/docs/index.mdx +28 -0
  376. package/templates/apps/web/jest.config.cjs +84 -27
  377. package/templates/apps/web/lib/__tests__/site-brand.test.ts +119 -0
  378. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +499 -0
  379. package/templates/apps/web/lib/account-config.ts +13 -0
  380. package/templates/apps/web/lib/server-api.ts +85 -0
  381. package/templates/apps/web/lib/site-brand.tsx +118 -0
  382. package/templates/apps/web/messages/en.json +275 -7
  383. package/templates/apps/web/middleware.ts +11 -3
  384. package/templates/apps/web/next.config.mjs +8 -2
  385. package/templates/apps/web/package.json +16 -7
  386. package/templates/apps/web/postcss.config.mjs +23 -0
  387. package/templates/apps/web/public/.well-known/security.txt +3 -3
  388. package/templates/apps/web/src/lib/routes.ts +15 -2
  389. package/templates/apps/web/tsconfig.json +1 -16
  390. package/templates/content/_site.mdx +24 -25
  391. package/templates/content/en/AboutPage/about.mdx +24 -14
  392. package/templates/content/en/ContactPage/contact.mdx +23 -14
  393. package/templates/content/en/FAQPage/faq.mdx +10 -392
  394. package/templates/content/en/HomePage/home.mdx +14 -285
  395. package/templates/database/CHANGELOG.md +382 -0
  396. package/templates/database/LICENSE +201 -0
  397. package/templates/database/README.md +3 -1
  398. package/templates/database/__tests__/flows-listing-diagnostic.test.ts +392 -0
  399. package/templates/database/__tests__/flows-presets.test.ts +173 -0
  400. package/templates/database/__tests__/prefixed-ids.db.test.ts +146 -0
  401. package/templates/database/__tests__/seed.test.ts +88 -0
  402. package/templates/database/__tests__/user-cascade.test.ts +19 -4
  403. package/templates/database/auth/schema.prisma +521 -0
  404. package/templates/database/config/schema.prisma +234 -0
  405. package/templates/database/content/schema.prisma +263 -0
  406. package/templates/database/flows/listing-diagnostic.ts +182 -0
  407. package/templates/database/flows/presets.ts +315 -0
  408. package/templates/database/inbox/__tests__/schema.test.ts +4 -0
  409. package/templates/database/inbox/schema.prisma +476 -3
  410. package/templates/database/jest.config.cjs +8 -0
  411. package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +201 -0
  412. package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +67 -0
  413. package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +46 -0
  414. package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +25 -0
  415. package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +49 -0
  416. package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +197 -0
  417. package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +32 -0
  418. package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +22 -0
  419. package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +151 -0
  420. package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +223 -0
  421. package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +22 -0
  422. package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +32 -0
  423. package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +40 -0
  424. package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +4 -0
  425. package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +2 -0
  426. package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +2 -0
  427. package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +29 -0
  428. package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +6 -0
  429. package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +39 -0
  430. package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +24 -0
  431. package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +3 -0
  432. package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +33 -0
  433. package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +30 -0
  434. package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +47 -0
  435. package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +16 -0
  436. package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +47 -0
  437. package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +10 -0
  438. package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +26 -0
  439. package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +90 -0
  440. package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +174 -0
  441. package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +14 -0
  442. package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +25 -0
  443. package/templates/database/ops/schema.prisma +27 -0
  444. package/templates/database/package.json +42 -4
  445. package/templates/database/prisma.config.ts +1 -1
  446. package/templates/database/schema.prisma +19 -435
  447. package/templates/database/scripts/db-generate-locked.sh +0 -0
  448. package/templates/database/seed-test.ts +14 -4
  449. package/templates/database/seed.ts +148 -0
  450. package/templates/database/tenancy.ts +45 -0
  451. package/templates/database/tsconfig.flows.json +15 -0
  452. package/templates/database/tsconfig.json +7 -1
  453. package/templates/database/tsconfig.tenancy.json +14 -0
  454. package/templates/package.json +30 -55
  455. package/templates/pnpm-workspace.yaml +0 -3
  456. package/templates/project.yaml +1 -1
  457. package/templates/tsconfig.json +1 -37
  458. package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +0 -94
  459. package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +0 -75
  460. package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +0 -82
  461. package/templates/apps/web/__tests__/auth/env-helpers.test.ts +0 -168
  462. package/templates/apps/web/__tests__/authority-list-routes.test.tsx +0 -208
  463. package/templates/apps/web/__tests__/better-stack.test.ts +0 -66
  464. package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +0 -87
  465. package/templates/apps/web/__tests__/blog-source-populated.test.ts +0 -130
  466. package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +0 -60
  467. package/templates/apps/web/__tests__/google-analytics.test.tsx +0 -104
  468. package/templates/apps/web/__tests__/i18n/middleware.test.ts +0 -119
  469. package/templates/apps/web/__tests__/i18n/routing.test.ts +0 -114
  470. package/templates/apps/web/__tests__/i18n/translations.test.ts +0 -191
  471. package/templates/apps/web/__tests__/json-ld.test.ts +0 -98
  472. package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +0 -580
  473. package/templates/apps/web/__tests__/layout-stealth.test.ts +0 -39
  474. package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +0 -103
  475. package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +0 -114
  476. package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +0 -94
  477. package/templates/apps/web/__tests__/page.test.tsx +0 -230
  478. package/templates/apps/web/__tests__/products-services-phase1.test.tsx +0 -321
  479. package/templates/apps/web/__tests__/projects-routes.test.tsx +0 -392
  480. package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +0 -475
  481. package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +0 -53
  482. package/templates/apps/web/__tests__/routes/blog-route.test.tsx +0 -191
  483. package/templates/apps/web/__tests__/routes/llms-txt.test.ts +0 -123
  484. package/templates/apps/web/__tests__/routes/robots-txt.test.ts +0 -52
  485. package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +0 -78
  486. package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +0 -203
  487. package/templates/apps/web/__tests__/section-routes.test.tsx +0 -693
  488. package/templates/apps/web/__tests__/security-headers.test.ts +0 -201
  489. package/templates/apps/web/__tests__/sentry-config.test.ts +0 -116
  490. package/templates/apps/web/__tests__/sitemap-locales.test.ts +0 -415
  491. package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +0 -844
  492. package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +0 -120
  493. package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +0 -202
  494. package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +0 -152
  495. package/templates/apps/web/content/en/blog/index.mdx +0 -15
  496. package/templates/apps/web/content/en/blog/launching-ailk.mdx +0 -20
  497. package/templates/apps/web/content/en/docs/getting-started.mdx +0 -30
  498. package/templates/content/.gitkeep +0 -0
  499. package/templates/content/CLAUDE.md +0 -85
  500. package/templates/content/ar/HomePage/home.mdx +0 -123
  501. package/templates/content/ar/_site.mdx +0 -35
  502. package/templates/content/de/_site.mdx +0 -29
  503. package/templates/content/en/.gitkeep +0 -0
  504. package/templates/content/en/AboutPage/about.schema.json +0 -82
  505. package/templates/content/en/BookCall/book-call.mdx +0 -19
  506. package/templates/content/en/BookCall/book-call.schema.json +0 -121
  507. package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +0 -20
  508. package/templates/content/en/CareersList/careers.mdx +0 -24
  509. package/templates/content/en/CaseStudiesList/case-studies.mdx +0 -22
  510. package/templates/content/en/CaseStudiesList/showcase.mdx +0 -8
  511. package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +0 -32
  512. package/templates/content/en/CaseStudy/schema-builder-migration.mdx +0 -41
  513. package/templates/content/en/ClientsList/clients.mdx +0 -38
  514. package/templates/content/en/ContactPage/contact.schema.json +0 -100
  515. package/templates/content/en/ContactPoint/primary.mdx +0 -14
  516. package/templates/content/en/Course/aeo-fundamentals.mdx +0 -37
  517. package/templates/content/en/Course/schema-builder-workshop.mdx +0 -62
  518. package/templates/content/en/CoursesList/courses.mdx +0 -22
  519. package/templates/content/en/DownloadsList/downloads.mdx +0 -22
  520. package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +0 -39
  521. package/templates/content/en/Event/ailk-launch-day-2026.mdx +0 -35
  522. package/templates/content/en/EventsList/events.mdx +0 -26
  523. package/templates/content/en/FAQPage/faq.schema.json +0 -231
  524. package/templates/content/en/GlossaryList/glossary.mdx +0 -19
  525. package/templates/content/en/GlossaryList/glossary.schema.json +0 -300
  526. package/templates/content/en/HomePage/home.schema.json +0 -88
  527. package/templates/content/en/HomePage/launch-service.mdx +0 -475
  528. package/templates/content/en/HomePage/launch-service.schema.json +0 -138
  529. package/templates/content/en/HowTo/add-mdx-content.mdx +0 -38
  530. package/templates/content/en/HowTo/configure-aeo-scoring.mdx +0 -35
  531. package/templates/content/en/HowTo/set-up-json-ld.mdx +0 -36
  532. package/templates/content/en/Integration/github-actions.mdx +0 -31
  533. package/templates/content/en/Integration/openai-api.mdx +0 -26
  534. package/templates/content/en/Integration/vercel.mdx +0 -32
  535. package/templates/content/en/IntegrationsList/integrations.mdx +0 -22
  536. package/templates/content/en/JobPosting/content-strategist.mdx +0 -46
  537. package/templates/content/en/JobPosting/developer-advocate.mdx +0 -47
  538. package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +0 -57
  539. package/templates/content/en/LandingPage/aeo-audit.mdx +0 -19
  540. package/templates/content/en/LandingPage/aeo-audit.schema.json +0 -92
  541. package/templates/content/en/LandingPage/agency-waitlist.mdx +0 -340
  542. package/templates/content/en/LandingPage/agency-waitlist.schema.json +0 -152
  543. package/templates/content/en/LandingPage/developers.mdx +0 -19
  544. package/templates/content/en/LandingPage/developers.schema.json +0 -109
  545. package/templates/content/en/LandingPage/for-agencies.mdx +0 -390
  546. package/templates/content/en/LandingPage/for-agencies.schema.json +0 -107
  547. package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +0 -417
  548. package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +0 -105
  549. package/templates/content/en/LandingPage/for-businesses.mdx +0 -19
  550. package/templates/content/en/LandingPage/for-businesses.schema.json +0 -96
  551. package/templates/content/en/LandingPage/platform.mdx +0 -369
  552. package/templates/content/en/LandingPage/platform.schema.json +0 -166
  553. package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +0 -19
  554. package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +0 -102
  555. package/templates/content/en/LandingPage/vs-wordpress.mdx +0 -19
  556. package/templates/content/en/LandingPage/vs-wordpress.schema.json +0 -53
  557. package/templates/content/en/NewsletterSignup/newsletter.mdx +0 -236
  558. package/templates/content/en/NewsletterSignup/newsletter.schema.json +0 -91
  559. package/templates/content/en/Organization/site-owner.mdx +0 -16
  560. package/templates/content/en/Partner/prisma.mdx +0 -31
  561. package/templates/content/en/Partner/supabase.mdx +0 -30
  562. package/templates/content/en/Partner/vercel.mdx +0 -28
  563. package/templates/content/en/PartnersList/partners.mdx +0 -22
  564. package/templates/content/en/Person/founder.mdx +0 -18
  565. package/templates/content/en/Pricing/pricing.mdx +0 -538
  566. package/templates/content/en/Pricing/pricing.schema.json +0 -209
  567. package/templates/content/en/PrivacyPage/privacy.mdx +0 -165
  568. package/templates/content/en/PrivacyPage/privacy.schema.json +0 -64
  569. package/templates/content/en/Product/ailk.mdx +0 -19
  570. package/templates/content/en/Product/ailk.schema.json +0 -94
  571. package/templates/content/en/Product/api-launch-kit.mdx +0 -26
  572. package/templates/content/en/Product/launch-kit.mdx +0 -28
  573. package/templates/content/en/ProductsList/products.mdx +0 -26
  574. package/templates/content/en/Project/ailk-phase-2.mdx +0 -54
  575. package/templates/content/en/ProjectsList/projects.mdx +0 -25
  576. package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +0 -27
  577. package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +0 -28
  578. package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +0 -39
  579. package/templates/content/en/ResourcesHub/resources.mdx +0 -22
  580. package/templates/content/en/Service/consulting.mdx +0 -22
  581. package/templates/content/en/Service/implementation.mdx +0 -30
  582. package/templates/content/en/Service/launch-service.mdx +0 -232
  583. package/templates/content/en/Service/launch.mdx +0 -228
  584. package/templates/content/en/ServicesList/services.mdx +0 -84
  585. package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +0 -44
  586. package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +0 -47
  587. package/templates/content/en/SoftwareProduct/ailk-schema.mdx +0 -49
  588. package/templates/content/en/TeamList/team.mdx +0 -63
  589. package/templates/content/en/TeamMember/founder.mdx +0 -72
  590. package/templates/content/en/TermsPage/terms.mdx +0 -19
  591. package/templates/content/en/TermsPage/terms.schema.json +0 -99
  592. package/templates/content/en/TestimonialsList/testimonials.mdx +0 -44
  593. package/templates/content/en/UseCasesList/use-cases.mdx +0 -30
  594. package/templates/content/en/Whitepaper/ax-first-product-development.mdx +0 -27
  595. package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +0 -27
  596. package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +0 -31
  597. package/templates/content/en-XA/AboutPage/about.mdx +0 -8
  598. package/templates/content/en-XA/FAQPage/faq.mdx +0 -8
  599. package/templates/content/en-XA/HomePage/home.mdx +0 -8
  600. package/templates/content/es/_site.mdx +0 -30
  601. package/templates/content/fr/_site.mdx +0 -30
  602. package/templates/content/ja/_site.mdx +0 -30
  603. package/templates/content/pt-BR/AboutPage/about.mdx +0 -8
  604. package/templates/content/pt-BR/FAQPage/faq.mdx +0 -8
  605. 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
+ }