create-ailk 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (638) hide show
  1. package/README.md +53 -22
  2. package/component-catalog.json +3 -3
  3. package/component-catalog.md +3 -3
  4. package/dist/add-module.js +4 -2
  5. package/dist/add-route.d.ts +12 -1
  6. package/dist/add-route.js +31 -3
  7. package/dist/cli.js +12 -7
  8. package/dist/derive-architecture.d.ts +3 -4
  9. package/dist/derive-architecture.js +65 -29
  10. package/dist/lib/design-checks.d.ts +9 -4
  11. package/dist/lib/design-checks.js +13 -7
  12. package/dist/lib/extract-module-bundle.js +29 -2
  13. package/dist/lib/fetch-template-snapshot.d.ts +2 -1
  14. package/dist/lib/fetch-template-snapshot.js +8 -3
  15. package/dist/lib/import-graph.d.ts +1 -1
  16. package/dist/lib/import-graph.js +4 -4
  17. package/dist/lib/module-license-gate.d.ts +12 -1
  18. package/dist/lib/module-license-gate.js +36 -15
  19. package/dist/lib/module-tier.d.ts +2 -8
  20. package/dist/lib/module-tier.js +13 -12
  21. package/dist/module-architecture.d.ts +20 -3
  22. package/dist/module-architecture.js +129 -552
  23. package/dist/paid-sections.d.ts +25 -1
  24. package/dist/paid-sections.js +88 -3
  25. package/dist/starter-grid.d.ts +6 -6
  26. package/dist/starter-grid.js +12 -5
  27. package/dist/surfaces.js +39 -2
  28. package/dist/template-record.d.ts +21 -3
  29. package/dist/template-record.js +38 -7
  30. package/dist/topology.d.ts +16 -3
  31. package/dist/topology.js +54 -23
  32. package/dist/update.d.ts +10 -1
  33. package/dist/update.js +715 -21
  34. package/package.json +3 -3
  35. package/release-scope.json +2 -2
  36. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +8 -2
  37. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +2 -2
  38. package/site-templates/marketing-site/ailk-template.json +7 -1
  39. package/site-templates/marketing-site/provenance.json +7 -1
  40. package/site-templates/saas-product/ailk-template.json +2 -1
  41. package/site-templates/saas-product/provenance.json +1 -0
  42. package/templates/.claude/cloudparity-repo-hooks.json +5 -0
  43. package/templates/.claude/hooks/template-guard.sh +137 -0
  44. package/templates/.claude/rules/extending.md +106 -0
  45. package/templates/.claude/rules/loop-contract.md +2 -2
  46. package/templates/.claude/settings.json +11 -0
  47. package/templates/.env.example +20 -5
  48. package/templates/.github/workflows/ci.yml +7 -4
  49. package/templates/CLAUDE.md +11 -1
  50. package/templates/CONVENTIONS.md +8 -10
  51. package/templates/README.md +14 -13
  52. package/templates/apps/api/.env.example +23 -2
  53. package/templates/apps/api/CLAUDE.md +119 -83
  54. package/templates/apps/api/jest.config.cjs +15 -5
  55. package/templates/apps/api/package.json +16 -20
  56. package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
  57. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
  58. package/templates/apps/api/src/index.ts +1 -1
  59. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +16 -0
  60. package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
  61. package/templates/apps/api/src/modules/commerce.ts +10 -0
  62. package/templates/apps/api/src/modules/content-write.ts +10 -0
  63. package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
  64. package/templates/apps/api/src/modules/scheduling.ts +10 -0
  65. package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
  66. package/templates/apps/api/src/modules/workspace.ts +10 -0
  67. package/templates/apps/api/src/server.ts +117 -1882
  68. package/templates/apps/api/vercel.json +2 -2
  69. package/templates/apps/mcp/CLAUDE.md +90 -26
  70. package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
  71. package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
  72. package/templates/apps/mcp/jest.config.cjs +6 -1
  73. package/templates/apps/mcp/package.json +5 -13
  74. package/templates/apps/mcp/src/app.ts +8 -7
  75. package/templates/apps/mcp/src/index.ts +6 -34
  76. package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
  77. package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
  78. package/templates/apps/mcp/src/site.ts +12 -0
  79. package/templates/apps/web/.env.example +1 -1
  80. package/templates/apps/web/CLAUDE.md +31 -3
  81. package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
  82. package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +43 -4
  83. package/templates/apps/web/app/[locale]/(auth)/legal-footnote.tsx +35 -0
  84. package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +117 -8
  85. package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +14 -37
  86. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +6 -6
  87. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +20 -35
  88. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +108 -0
  89. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +111 -5
  90. package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +78 -16
  91. package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +132 -12
  92. package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +53 -1
  93. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +38 -0
  94. package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +4 -2
  95. package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +47 -24
  96. package/templates/apps/web/app/[locale]/(authed)/signed-out-gate.generated.tsx +23 -4
  97. package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
  98. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
  99. package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
  100. package/templates/apps/web/app/[locale]/layout.tsx +33 -13
  101. package/templates/apps/web/app/[locale]/meet/confirmed/BookingHandOff.tsx +128 -0
  102. package/templates/apps/web/app/[locale]/meet/confirmed/__tests__/BookingHandOff.test.tsx +126 -0
  103. package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
  104. package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
  105. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
  106. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
  107. package/templates/apps/web/app/api/revalidate/route.ts +3 -3
  108. package/templates/apps/web/auth.ts +10 -6
  109. package/templates/apps/web/i18n/request.ts +49 -1
  110. package/templates/apps/web/jest.config.cjs +1 -0
  111. package/templates/apps/web/lib/__tests__/account-config.test.ts +7 -0
  112. package/templates/apps/web/lib/__tests__/auth-email.test.ts +276 -0
  113. package/templates/apps/web/lib/auth-email.ts +103 -21
  114. package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +72 -23
  115. package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +94 -70
  116. package/templates/apps/web/lib/prisma-for-auth.ts +5 -2
  117. package/templates/apps/web/lib/relay.ts +2 -2
  118. package/templates/apps/web/lib/release-scope.ts +47 -0
  119. package/templates/apps/web/lib/server-api.ts +1 -1
  120. package/templates/apps/web/lib/sign-up-agreements.ts +291 -28
  121. package/templates/apps/web/lib/site-contributions.ts +18 -0
  122. package/templates/apps/web/messages/en.json +186 -20
  123. package/templates/apps/web/messages/site/en.json +1 -0
  124. package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
  125. package/templates/customizations.yaml +37 -0
  126. package/templates/database/prisma.config.ts +10 -14
  127. package/templates/database/seed-test.ts +2 -2
  128. package/templates/database/seed.ts +5 -5
  129. package/templates/package.json +12 -6
  130. package/templates/pnpm-workspace.yaml +0 -1
  131. package/templates/project.yaml +16 -8
  132. package/templates/tools/jest/reporters.cjs +65 -0
  133. package/templates/tools/lint-architecture.ts +553 -7
  134. package/templates/tsconfig.json +1 -2
  135. package/versions.json +49 -36
  136. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
  137. package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
  138. package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
  139. package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
  140. package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
  141. package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
  142. package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
  143. package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
  144. package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
  145. package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
  146. package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
  147. package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
  148. package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
  149. package/templates/apps/api/src/bin/spokes.ts +0 -198
  150. package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
  151. package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
  152. package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
  153. package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
  154. package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
  155. package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
  156. package/templates/apps/api/src/config/index.ts +0 -596
  157. package/templates/apps/api/src/config/modules.ts +0 -83
  158. package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
  159. package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
  160. package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
  161. package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
  162. package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
  163. package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
  164. package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
  165. package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
  166. package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
  167. package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
  168. package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
  169. package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
  170. package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
  171. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
  172. package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
  173. package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
  174. package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
  175. package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
  176. package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
  177. package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
  178. package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
  179. package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
  180. package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
  181. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
  182. package/templates/apps/api/src/lib/agent-store.ts +0 -613
  183. package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
  184. package/templates/apps/api/src/lib/consent-store.ts +0 -363
  185. package/templates/apps/api/src/lib/content-adapter.ts +0 -112
  186. package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
  187. package/templates/apps/api/src/lib/error-serializer.ts +0 -164
  188. package/templates/apps/api/src/lib/errors.ts +0 -95
  189. package/templates/apps/api/src/lib/file-fallback.ts +0 -87
  190. package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
  191. package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
  192. package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
  193. package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
  194. package/templates/apps/api/src/lib/license-key-store.ts +0 -45
  195. package/templates/apps/api/src/lib/locales.ts +0 -201
  196. package/templates/apps/api/src/lib/outbound-http.ts +0 -127
  197. package/templates/apps/api/src/lib/prisma.ts +0 -21
  198. package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
  199. package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
  200. package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
  201. package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
  202. package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
  203. package/templates/apps/api/src/lib/site.ts +0 -257
  204. package/templates/apps/api/src/lib/slice-load.ts +0 -90
  205. package/templates/apps/api/src/lib/spoke-store.ts +0 -180
  206. package/templates/apps/api/src/lib/stripe.ts +0 -321
  207. package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
  208. package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
  209. package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
  210. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
  211. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
  212. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
  213. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
  214. package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
  215. package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
  216. package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
  217. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
  218. package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
  219. package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
  220. package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
  221. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
  222. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
  223. package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
  224. package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
  225. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
  226. package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
  227. package/templates/apps/api/src/middleware/auth.ts +0 -864
  228. package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
  229. package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
  230. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
  231. package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
  232. package/templates/apps/api/src/openapi/index.ts +0 -18
  233. package/templates/apps/api/src/openapi/spec.ts +0 -2148
  234. package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
  235. package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
  236. package/templates/apps/api/src/routes/aeo/index.ts +0 -107
  237. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
  238. package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
  239. package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
  240. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
  241. package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
  242. package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
  243. package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
  244. package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
  245. package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
  246. package/templates/apps/api/src/routes/auth/user.ts +0 -305
  247. package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
  248. package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
  249. package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
  250. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
  251. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
  252. package/templates/apps/api/src/routes/checkout/index.ts +0 -34
  253. package/templates/apps/api/src/routes/checkout/session.ts +0 -171
  254. package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
  255. package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
  256. package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
  257. package/templates/apps/api/src/routes/consent/account.ts +0 -268
  258. package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
  259. package/templates/apps/api/src/routes/consent/index.ts +0 -26
  260. package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
  261. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
  262. package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
  263. package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
  264. package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
  265. package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
  266. package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
  267. package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
  268. package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
  269. package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
  270. package/templates/apps/api/src/routes/content/get-page.ts +0 -183
  271. package/templates/apps/api/src/routes/content/index.ts +0 -49
  272. package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
  273. package/templates/apps/api/src/routes/content/list-types.ts +0 -19
  274. package/templates/apps/api/src/routes/content/offerings.ts +0 -184
  275. package/templates/apps/api/src/routes/content/pricing.ts +0 -176
  276. package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
  277. package/templates/apps/api/src/routes/content/search.ts +0 -100
  278. package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
  279. package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
  280. package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
  281. package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
  282. package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
  283. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
  284. package/templates/apps/api/src/routes/leads/index.ts +0 -639
  285. package/templates/apps/api/src/routes/leads/list.ts +0 -104
  286. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
  287. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
  288. package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
  289. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
  290. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
  291. package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
  292. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
  293. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
  294. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
  295. package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
  296. package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
  297. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
  298. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
  299. package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
  300. package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
  301. package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
  302. package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
  303. package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
  304. package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
  305. package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
  306. package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
  307. package/templates/apps/api/src/routes/requests/index.ts +0 -54
  308. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
  309. package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
  310. package/templates/apps/api/src/routes/webhooks/README.md +0 -398
  311. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
  312. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
  313. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
  314. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
  315. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
  316. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
  317. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
  318. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
  319. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
  320. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
  321. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
  322. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
  323. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
  324. package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
  325. package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
  326. package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
  327. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
  328. package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
  329. package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
  330. package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
  331. package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
  332. package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
  333. package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
  334. package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
  335. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
  336. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
  337. package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
  338. package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
  339. package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
  340. package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
  341. package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
  342. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
  343. package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
  344. package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
  345. package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
  346. package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
  347. package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
  348. package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
  349. package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
  350. package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
  351. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
  352. package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
  353. package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
  354. package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
  355. package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
  356. package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
  357. package/templates/apps/api/src/services/abandon-email.ts +0 -336
  358. package/templates/apps/api/src/services/aeo-score.ts +0 -325
  359. package/templates/apps/api/src/services/answer-distributions.ts +0 -138
  360. package/templates/apps/api/src/services/audit-log.ts +0 -961
  361. package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
  362. package/templates/apps/api/src/services/consent.ts +0 -834
  363. package/templates/apps/api/src/services/default-tenant.ts +0 -416
  364. package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
  365. package/templates/apps/api/src/services/dunning-policy.ts +0 -294
  366. package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
  367. package/templates/apps/api/src/services/entitlements.ts +0 -338
  368. package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
  369. package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
  370. package/templates/apps/api/src/services/lead-promotion.ts +0 -160
  371. package/templates/apps/api/src/services/lead-routing.ts +0 -1372
  372. package/templates/apps/api/src/services/leads-inbox.ts +0 -312
  373. package/templates/apps/api/src/services/listing-config.ts +0 -178
  374. package/templates/apps/api/src/services/magnet-completion.ts +0 -242
  375. package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
  376. package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
  377. package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
  378. package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
  379. package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
  380. package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
  381. package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
  382. package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
  383. package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
  384. package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
  385. package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
  386. package/templates/apps/api/src/services/offerings/index.ts +0 -614
  387. package/templates/apps/api/src/services/offerings/source.ts +0 -140
  388. package/templates/apps/api/src/services/offerings/store.ts +0 -150
  389. package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
  390. package/templates/apps/api/src/services/person.ts +0 -1211
  391. package/templates/apps/api/src/services/plan-offerings.ts +0 -125
  392. package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
  393. package/templates/apps/api/src/services/project-listings.ts +0 -2085
  394. package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
  395. package/templates/apps/api/src/services/request-confirm.ts +0 -698
  396. package/templates/apps/api/src/services/revalidation.ts +0 -235
  397. package/templates/apps/api/src/services/slack-notify.ts +0 -291
  398. package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
  399. package/templates/apps/api/src/services/usage-credits.ts +0 -340
  400. package/templates/apps/api/src/services/verified-email.ts +0 -71
  401. package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
  402. package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
  403. package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
  404. package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
  405. package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
  406. package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
  407. package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
  408. package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
  409. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
  410. package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
  411. package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
  412. package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
  413. package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
  414. package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
  415. package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
  416. package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
  417. package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
  418. package/templates/apps/mcp/__tests__/index.test.ts +0 -195
  419. package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
  420. package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
  421. package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
  422. package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
  423. package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
  424. package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
  425. package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
  426. package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
  427. package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
  428. package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
  429. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
  430. package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
  431. package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
  432. package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
  433. package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
  434. package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
  435. package/templates/apps/mcp/__tests__/server.test.ts +0 -388
  436. package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
  437. package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
  438. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
  439. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
  440. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
  441. package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
  442. package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
  443. package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
  444. package/templates/apps/mcp/src/abuse/index.ts +0 -349
  445. package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
  446. package/templates/apps/mcp/src/boot.ts +0 -167
  447. package/templates/apps/mcp/src/config/modules.ts +0 -43
  448. package/templates/apps/mcp/src/http-transport.ts +0 -564
  449. package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
  450. package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
  451. package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
  452. package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
  453. package/templates/apps/mcp/src/lib/errors.ts +0 -61
  454. package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
  455. package/templates/apps/mcp/src/lib/locales.ts +0 -171
  456. package/templates/apps/mcp/src/lib/prisma.ts +0 -39
  457. package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
  458. package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
  459. package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
  460. package/templates/apps/mcp/src/lib/site-config.ts +0 -53
  461. package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
  462. package/templates/apps/mcp/src/request-context.ts +0 -52
  463. package/templates/apps/mcp/src/server.ts +0 -343
  464. package/templates/apps/mcp/src/serverless-app.ts +0 -88
  465. package/templates/apps/mcp/src/tools/audit.ts +0 -127
  466. package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
  467. package/templates/apps/mcp/src/tools/create_project.ts +0 -134
  468. package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
  469. package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
  470. package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
  471. package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
  472. package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
  473. package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
  474. package/templates/apps/mcp/src/tools/index.ts +0 -138
  475. package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
  476. package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
  477. package/templates/apps/mcp/src/tools/proposals.ts +0 -27
  478. package/templates/apps/mcp/src/tools/purchase.ts +0 -205
  479. package/templates/apps/mcp/src/tools/read_content.ts +0 -81
  480. package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
  481. package/templates/apps/mcp/src/tools/search_content.ts +0 -63
  482. package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
  483. package/templates/apps/mcp/src/workspace-server.ts +0 -224
  484. package/templates/database/CHANGELOG.md +0 -981
  485. package/templates/database/LICENSE +0 -202
  486. package/templates/database/NOTICE +0 -2
  487. package/templates/database/README.md +0 -243
  488. package/templates/database/__tests__/agents.db.test.ts +0 -320
  489. package/templates/database/__tests__/appointment.db.test.ts +0 -106
  490. package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
  491. package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
  492. package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
  493. package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
  494. package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
  495. package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
  496. package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
  497. package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
  498. package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
  499. package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
  500. package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
  501. package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
  502. package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
  503. package/templates/database/__tests__/flows-presets.test.ts +0 -173
  504. package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
  505. package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
  506. package/templates/database/__tests__/member-area.db.test.ts +0 -257
  507. package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
  508. package/templates/database/__tests__/member-contract.db.test.ts +0 -413
  509. package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
  510. package/templates/database/__tests__/offerings-migration.test.ts +0 -197
  511. package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
  512. package/templates/database/__tests__/offerings.db.test.ts +0 -303
  513. package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
  514. package/templates/database/__tests__/person-contact.db.test.ts +0 -563
  515. package/templates/database/__tests__/person-notes.db.test.ts +0 -249
  516. package/templates/database/__tests__/person.db.test.ts +0 -586
  517. package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
  518. package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
  519. package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
  520. package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
  521. package/templates/database/__tests__/seed.test.ts +0 -272
  522. package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
  523. package/templates/database/__tests__/tenancy.test.ts +0 -141
  524. package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
  525. package/templates/database/__tests__/user-cascade.test.ts +0 -140
  526. package/templates/database/_gitignore +0 -8
  527. package/templates/database/auth/.gitkeep +0 -0
  528. package/templates/database/auth/schema.prisma +0 -641
  529. package/templates/database/config/.gitkeep +0 -0
  530. package/templates/database/config/schema.prisma +0 -441
  531. package/templates/database/content/.gitkeep +0 -0
  532. package/templates/database/content/schema.prisma +0 -339
  533. package/templates/database/eslint.config.mjs +0 -69
  534. package/templates/database/flows/listing-diagnostic.ts +0 -182
  535. package/templates/database/flows/presets.ts +0 -315
  536. package/templates/database/inbox/.gitkeep +0 -0
  537. package/templates/database/inbox/README.md +0 -3
  538. package/templates/database/inbox/__tests__/schema.test.ts +0 -44
  539. package/templates/database/inbox/schema.prisma +0 -1447
  540. package/templates/database/jest.config.cjs +0 -36
  541. package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
  542. package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
  543. package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
  544. package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
  545. package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
  546. package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
  547. package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
  548. package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
  549. package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
  550. package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
  551. package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
  552. package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
  553. package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
  554. package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
  555. package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
  556. package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
  557. package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
  558. package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
  559. package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
  560. package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
  561. package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
  562. package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
  563. package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
  564. package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
  565. package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
  566. package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
  567. package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
  568. package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
  569. package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
  570. package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
  571. package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
  572. package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
  573. package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
  574. package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
  575. package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
  576. package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
  577. package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
  578. package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
  579. package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
  580. package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
  581. package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
  582. package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
  583. package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
  584. package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
  585. package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
  586. package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
  587. package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
  588. package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
  589. package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
  590. package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
  591. package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
  592. package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
  593. package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
  594. package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
  595. package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
  596. package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
  597. package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
  598. package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
  599. package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
  600. package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
  601. package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
  602. package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
  603. package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
  604. package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
  605. package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
  606. package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
  607. package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
  608. package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
  609. package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
  610. package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
  611. package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
  612. package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
  613. package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
  614. package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
  615. package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
  616. package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
  617. package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
  618. package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
  619. package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
  620. package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
  621. package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
  622. package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
  623. package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
  624. package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
  625. package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
  626. package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
  627. package/templates/database/migrations/migration_lock.toml +0 -3
  628. package/templates/database/ops/.gitkeep +0 -0
  629. package/templates/database/ops/schema.prisma +0 -43
  630. package/templates/database/package.json +0 -89
  631. package/templates/database/schema.prisma +0 -71
  632. package/templates/database/scripts/db-generate-locked.sh +0 -80
  633. package/templates/database/scripts/person-backfill.sql +0 -132
  634. package/templates/database/tenancy.ts +0 -183
  635. package/templates/database/tsconfig.build.json +0 -16
  636. package/templates/database/tsconfig.flows.json +0 -15
  637. package/templates/database/tsconfig.json +0 -16
  638. package/templates/database/tsconfig.tenancy.json +0 -14
@@ -1,140 +0,0 @@
1
- /**
2
- * The fail-closed EMPTY adapter (#5876 spec D5) — a null object that holds
3
- * no client and issues no query. `getMcpContentAdapter()` (`content-adapter.ts`)
4
- * returns it whenever the environment selects `CONTENT_ADAPTER=database` and
5
- * the deployment's workspace resolution (`public-workspace.ts`) did not land
6
- * at `{ kind: "resolved" }`.
7
- *
8
- * All eleven `MdxContentAdapter` methods are specified, not left to throw a
9
- * generic TypeError: the six reads plus `getPageSource` return their own
10
- * not-found/empty shape, and the four write methods throw the SAME named
11
- * error `readOnlyContentAdapter()` (below) throws on the RESOLVED arm
12
- * (#5876 spec D13) — the seam is read-only under `CONTENT_ADAPTER=database`
13
- * on both arms, not only this fail-closed one.
14
- *
15
- * Three properties follow for free from this shape, over the rejected
16
- * alternatives (throwing the resolver's own "workspaceId required" error, or
17
- * returning `null` from the seam and guarding per tool):
18
- *
19
- * 1. Every content tool's own not-found/empty mapping fires with NO tool
20
- * edit — `read_content` and `get_*` already treat `null` as not-found;
21
- * `list_pages` and `search_content` already answer their empty
22
- * `ItemList` over `[]` (#7167: the routes' own envelopes).
23
- * 2. "Before any content lookup" (NFR-5) is structural, not asserted —
24
- * there is nothing here to look anything up in.
25
- * 3. `readContentDocument`'s `typeof getPageSource === "function"`
26
- * capability check (`@working-theory/content-adapters`) passes, so
27
- * `read_content` never sees THAT named throw on the fail-closed path.
28
- */
29
- import type {
30
- ContentPage,
31
- ExtractionType,
32
- MdxContentAdapter,
33
- MdxPageSource,
34
- SchemaOrgType,
35
- SearchOptions,
36
- SearchResult,
37
- StructuredDataFor,
38
- } from "@working-theory/content-adapters";
39
-
40
- /**
41
- * The one message every write method throws, on BOTH the empty adapter and
42
- * the read-only wrapper of a resolved database adapter — the seam is
43
- * read-only under `CONTENT_ADAPTER=database`, full stop (#5876 spec D13).
44
- * The three write MCP tools this boundary was drawn against
45
- * (`create_page`/`update_page`/`delete_page`) were retired ahead of this
46
- * issue (#5853); this is the seam's own STOP boundary, held independent of
47
- * which tools currently reach it.
48
- */
49
- const WRITE_NOT_SUPPORTED_MESSAGE =
50
- "This MCP server's CONTENT_ADAPTER=database seam is read-only: " +
51
- "createPage/updatePage/deletePage/getPageVersion are not available here. " +
52
- "Content writes go through apps/api's tenant-guarded workspace content routes.";
53
-
54
- function throwWriteNotSupported(): never {
55
- throw new Error(WRITE_NOT_SUPPORTED_MESSAGE);
56
- }
57
-
58
- /**
59
- * A null object satisfying `MdxContentAdapter`. Holds no client; every read
60
- * method resolves synchronously to its empty shape with no I/O.
61
- */
62
- export function emptyContentAdapter(): MdxContentAdapter {
63
- const adapter: MdxContentAdapter = {
64
- async getPageBySlug(
65
- _type: SchemaOrgType,
66
- _slug: string,
67
- _locale?: string,
68
- ): Promise<ContentPage | null> {
69
- return null;
70
- },
71
- async listPages(
72
- _type: SchemaOrgType,
73
- _locale?: string,
74
- ): Promise<ContentPage[]> {
75
- return [];
76
- },
77
- async getDetailBySlug(
78
- _type: SchemaOrgType,
79
- _slug: string,
80
- _locale?: string,
81
- ): Promise<ContentPage | null> {
82
- return null;
83
- },
84
- async listDetail(
85
- _type: SchemaOrgType,
86
- _locale?: string,
87
- ): Promise<ContentPage[]> {
88
- return [];
89
- },
90
- async searchPages(
91
- _query: string,
92
- _options?: SearchOptions,
93
- ): Promise<SearchResult[]> {
94
- return [];
95
- },
96
- async extractStructuredData<T extends ExtractionType>(
97
- _type: T,
98
- _slug: string,
99
- _locale?: string,
100
- ): Promise<StructuredDataFor<T> | null> {
101
- return null;
102
- },
103
- async getPageSource(
104
- _type: SchemaOrgType,
105
- _slug: string,
106
- _locale?: string,
107
- ): Promise<MdxPageSource | null> {
108
- return null;
109
- },
110
- createPage: throwWriteNotSupported,
111
- updatePage: throwWriteNotSupported,
112
- deletePage: throwWriteNotSupported,
113
- getPageVersion: throwWriteNotSupported,
114
- };
115
- return adapter;
116
- }
117
-
118
- /**
119
- * Wraps a RESOLVED database adapter so its four write methods throw the same
120
- * read-only error the empty adapter throws — the seam is read-only under
121
- * `CONTENT_ADAPTER=database` on both arms (#5876 spec D13). The six read
122
- * methods and `getPageSource` pass through untouched.
123
- */
124
- export function readOnlyContentAdapter(
125
- adapter: MdxContentAdapter,
126
- ): MdxContentAdapter {
127
- return {
128
- getPageBySlug: adapter.getPageBySlug.bind(adapter),
129
- listPages: adapter.listPages.bind(adapter),
130
- getDetailBySlug: adapter.getDetailBySlug.bind(adapter),
131
- listDetail: adapter.listDetail.bind(adapter),
132
- searchPages: adapter.searchPages.bind(adapter),
133
- extractStructuredData: adapter.extractStructuredData.bind(adapter),
134
- getPageSource: adapter.getPageSource.bind(adapter),
135
- createPage: throwWriteNotSupported,
136
- updatePage: throwWriteNotSupported,
137
- deletePage: throwWriteNotSupported,
138
- getPageVersion: throwWriteNotSupported,
139
- };
140
- }
@@ -1,61 +0,0 @@
1
- /**
2
- * Canonical error shape for apps/mcp content-write tools (D14a Stage 0).
3
- *
4
- * Mirrors the apps/api shape (`apps/api/src/lib/errors.ts`) intentionally —
5
- * REST and MCP surfaces must produce isomorphic error bodies (per brief
6
- * Layer 1 AC). The only structural difference is that MCP returns the body as
7
- * the tool result itself; HTTP carries it alongside a status code.
8
- *
9
- * Codes are the same closed set used by apps/api so an agent calling either
10
- * surface gets the same machine-readable shape.
11
- */
12
-
13
- export type ErrorCode =
14
- | "validation_failed"
15
- | "not_found"
16
- | "conflict"
17
- | "payment_required"
18
- | "unauthorized";
19
-
20
- export interface ErrorBody {
21
- error: ErrorCode;
22
- message: string;
23
- details?: Record<string, unknown>;
24
- }
25
-
26
- function makeBody(
27
- code: ErrorCode,
28
- message: string,
29
- details?: Record<string, unknown>,
30
- ): ErrorBody {
31
- if (details === undefined) {
32
- return { error: code, message };
33
- }
34
- return { error: code, message, details };
35
- }
36
-
37
- export function validationError(
38
- message: string,
39
- details?: Record<string, unknown>,
40
- ): ErrorBody {
41
- return makeBody("validation_failed", message, details);
42
- }
43
-
44
- export function unauthorizedError(message: string): ErrorBody {
45
- return makeBody("unauthorized", message);
46
- }
47
-
48
- export function paymentRequiredError(message: string): ErrorBody {
49
- return makeBody("payment_required", message);
50
- }
51
-
52
- export function notFoundError(message: string): ErrorBody {
53
- return makeBody("not_found", message);
54
- }
55
-
56
- export function conflictError(
57
- message: string,
58
- details?: Record<string, unknown>,
59
- ): ErrorBody {
60
- return makeBody("conflict", message, details);
61
- }
@@ -1,45 +0,0 @@
1
- /**
2
- * Registers the durable home of a renewed licence key (#6677 DD-6).
3
- *
4
- * `@working-theory/license` renews the deployment's key before it lapses and
5
- * keeps the renewed key in a `LicenseKeyStore`. Its default store is a file,
6
- * which a redeploy wipes. With a database configured, this registers the
7
- * store backed by ONE deployment-wide `SiteSetting` row,
8
- * `(DEFAULT_WORKSPACE_ID, "license.renewed_key")`, shared with apps/api and
9
- * apps/web — so the key apps/api renewed is the key this server resolves.
10
- *
11
- * `index.ts` awaits this BEFORE `initMcpCommerceClaim()`, which memoises the
12
- * claim at boot. Both imports are dynamic and reached only when
13
- * `DATABASE_URL` is set, so an MDX-only deployment never constructs a Prisma
14
- * client (the `prisma.ts` header's rule).
15
- */
16
-
17
- /**
18
- * Register the SiteSetting-backed store when `DATABASE_URL` is set. An
19
- * explicitly set `AILK_LICENSE_STORAGE_PATH` is the operator choosing the
20
- * file store, and is honoured. Never throws: a failure logs and leaves the
21
- * file store in place.
22
- */
23
- export async function registerLicenseKeyStore(): Promise<void> {
24
- if (!process.env["DATABASE_URL"] || process.env["AILK_LICENSE_STORAGE_PATH"]) return;
25
- try {
26
- const [{ getMcpPrismaClient }, { DEFAULT_WORKSPACE_ID }, license] =
27
- await Promise.all([
28
- import("./prisma.js"),
29
- import("@working-theory/database/tenancy"),
30
- import("@working-theory/license"),
31
- ]);
32
- const prisma = getMcpPrismaClient();
33
- license.setLicenseKeyStore(
34
- license.createSiteSettingLicenseKeyStore(
35
- prisma.siteSetting,
36
- DEFAULT_WORKSPACE_ID,
37
- ),
38
- );
39
- } catch (err) {
40
- console.error(
41
- "[mcp] could not register the SiteSetting licence-key store — the file store stays in place:",
42
- err instanceof Error ? err.name : "non-Error thrown",
43
- );
44
- }
45
- }
@@ -1,171 +0,0 @@
1
- /**
2
- * readLocales — read and validate the `product.locales` field from project.yaml.
3
- *
4
- * Mirrors `apps/web/lib/locales.ts` and `apps/api/src/lib/locales.ts`.
5
- * Duplicated because architecture.yaml does not permit cross-app imports
6
- * (apps/mcp may not import apps/web or apps/api), and a shared package for
7
- * filesystem helpers would extend the architectural surface beyond the scope
8
- * of this spec.
9
- *
10
- * Validation rules:
11
- * - `locales` field absent → defaults to `["en"]` (backward-compat with OSS
12
- * forks that pre-date the field)
13
- * - `locales` present → must be a non-empty array of BCP-47 locale tags
14
- * matching `/^[a-z]{2}(-[A-Z]{2})?$/` (MVP subset)
15
- * - `product.default_locale` must be included in the `locales` list; parse
16
- * error if not
17
- * - `locales: []` → parse error (empty array is invalid)
18
- *
19
- * Used by content read tools to validate the `locale` parameter against the
20
- * configured allowlist before passing to the adapter (defense-in-depth per
21
- * AC-i18n-07).
22
- */
23
-
24
- import { readFileSync } from "node:fs";
25
- import { join } from "node:path";
26
-
27
- import { parse } from "yaml";
28
-
29
- /** BCP-47 MVP subset: `xx` or `xx-XX` (language + optional region). */
30
- const BCP47_RE = /^[a-z]{2}(-[A-Z]{2})?$/;
31
-
32
- /**
33
- * Reads, validates, and returns the sorted locale list from project.yaml.
34
- *
35
- * @param cwd - Directory to search from. Defaults to `process.cwd()`.
36
- * @returns Sorted `string[]` of enabled locale tags.
37
- * @throws Error with a descriptive message (file + cause) when validation fails.
38
- */
39
- export function readLocales(cwd = process.cwd()): string[] {
40
- const filePath = resolveProjectYamlPath(cwd);
41
-
42
- let raw: string;
43
- try {
44
- raw = readFileSync(filePath, "utf8");
45
- } catch (err) {
46
- const e = new Error(
47
- `[locales] Cannot read ${filePath}: ${err instanceof Error ? err.message : String(err)}`,
48
- );
49
- (e as { cause?: unknown }).cause = err;
50
- throw e;
51
- }
52
-
53
- let doc: unknown;
54
- try {
55
- doc = parse(raw);
56
- } catch (err) {
57
- const e = new Error(
58
- `[locales] YAML parse error in ${filePath}: ${err instanceof Error ? err.message : String(err)}`,
59
- );
60
- (e as { cause?: unknown }).cause = err;
61
- throw e;
62
- }
63
-
64
- if (!doc || typeof doc !== "object") {
65
- throw new Error(
66
- `[locales] ${filePath}: expected a YAML mapping at the top level`,
67
- );
68
- }
69
-
70
- const top = doc as Record<string, unknown>;
71
- const product = top["product"];
72
-
73
- const p =
74
- product && typeof product === "object"
75
- ? (product as Record<string, unknown>)
76
- : {};
77
-
78
- const defaultLocale =
79
- typeof p["default_locale"] === "string" ? p["default_locale"] : "en";
80
-
81
- const rawLocales = p["locales"];
82
-
83
- if (rawLocales === undefined || rawLocales === null) {
84
- return ["en"];
85
- }
86
-
87
- if (!Array.isArray(rawLocales)) {
88
- throw new Error(
89
- `[locales] ${filePath}: product.locales must be an array, got ${typeof rawLocales}`,
90
- );
91
- }
92
-
93
- if (rawLocales.length === 0) {
94
- throw new Error(
95
- `[locales] ${filePath}: product.locales must be a non-empty array (got empty array)`,
96
- );
97
- }
98
-
99
- for (const entry of rawLocales) {
100
- if (typeof entry !== "string") {
101
- throw new Error(
102
- `[locales] ${filePath}: product.locales entries must be strings, got ${typeof entry}`,
103
- );
104
- }
105
- if (!BCP47_RE.test(entry)) {
106
- throw new Error(
107
- `[locales] ${filePath}: product.locales entry "${entry}" is not a valid BCP-47 locale tag (expected format: xx or xx-XX)`,
108
- );
109
- }
110
- }
111
-
112
- const locales = rawLocales as string[];
113
-
114
- if (!locales.includes(defaultLocale)) {
115
- throw new Error(
116
- `[locales] ${filePath}: product.default_locale "${defaultLocale}" is not in product.locales [${locales.join(", ")}]`,
117
- );
118
- }
119
-
120
- return [...locales].sort();
121
- }
122
-
123
- /**
124
- * Read the project's default locale from project.yaml. Returns `"en"` when
125
- * project.yaml is absent or `product.default_locale` is unset — same default
126
- * as the adapter.
127
- */
128
- export function readDefaultLocale(cwd = process.cwd()): string {
129
- const filePath = resolveProjectYamlPath(cwd);
130
-
131
- let raw: string;
132
- try {
133
- raw = readFileSync(filePath, "utf8");
134
- } catch {
135
- return "en";
136
- }
137
-
138
- let doc: unknown;
139
- try {
140
- doc = parse(raw);
141
- } catch {
142
- return "en";
143
- }
144
-
145
- if (!doc || typeof doc !== "object") return "en";
146
- const product = (doc as Record<string, unknown>)["product"];
147
- if (!product || typeof product !== "object") return "en";
148
- const defaultLocale = (product as Record<string, unknown>)["default_locale"];
149
- return typeof defaultLocale === "string" ? defaultLocale : "en";
150
- }
151
-
152
- /**
153
- * Probe likely locations for project.yaml. Apps run from their own dirs in
154
- * dev/build (`apps/mcp/`) but from repo root in some test setups.
155
- */
156
- function resolveProjectYamlPath(cwd: string): string {
157
- const candidates = [
158
- join(cwd, "project.yaml"),
159
- join(cwd, "..", "project.yaml"),
160
- join(cwd, "..", "..", "project.yaml"),
161
- ];
162
- for (const candidate of candidates) {
163
- try {
164
- readFileSync(candidate, "utf8");
165
- return candidate;
166
- } catch {
167
- // continue
168
- }
169
- }
170
- return candidates[0] ?? join(cwd, "project.yaml");
171
- }
@@ -1,39 +0,0 @@
1
- /**
2
- * Lazy Prisma client singleton for apps/mcp's `CONTENT_ADAPTER=database` path
3
- * (#5876 spec D7).
4
- *
5
- * Deliberately NOT the eager, module-scope-construction shape of
6
- * `apps/api/src/lib/prisma.ts` / `apps/web/lib/prisma-for-auth.ts`: this
7
- * module is reached only from `initMcpPublicWorkspace()`'s `database` branch
8
- * (`public-workspace.ts`), via `await import("./prisma.js")`, and only when
9
- * the caller supplied no `prisma` of its own — the injection seam every test
10
- * uses instead (FR-1). Constructing at MODULE scope — with a
11
- * `connectionString` that is `undefined` on every MDX-only deployment (the
12
- * 350 pre-existing apps/mcp tests set no `DATABASE_URL`) — would break the
13
- * no-`DATABASE_URL` scaffold the instant this file was imported anywhere,
14
- * even transitively. Construction happens on first CALL and is memoised
15
- * after that, mirroring #5852's identical deferral of the apps/api client
16
- * (`apps/api/src/services/public-site-resolver.ts` § D6).
17
- */
18
- import { PrismaPg } from "@prisma/adapter-pg";
19
- import { PrismaClient } from "@working-theory/database";
20
-
21
- let client: PrismaClient | undefined;
22
-
23
- /**
24
- * The process-wide lazy Prisma client for the MCP server's database path.
25
- * Constructs on first call; every subsequent call returns the same instance.
26
- */
27
- export function getMcpPrismaClient(): PrismaClient {
28
- if (client === undefined) {
29
- const adapter = new PrismaPg({
30
- connectionString: process.env.DATABASE_URL,
31
- });
32
- client = new PrismaClient({
33
- adapter,
34
- log:
35
- process.env.NODE_ENV === "development" ? ["error", "warn"] : ["error"],
36
- });
37
- }
38
- return client;
39
- }
@@ -1,133 +0,0 @@
1
- /**
2
- * The MCP server's own workspace resolution (#5876 spec D2/D4/D6/D7) — which
3
- * workspace `CONTENT_ADAPTER=database` content reads serve, resolved ONCE at
4
- * bootstrap and read synchronously thereafter by `content-adapter.ts`.
5
- *
6
- * WHY RESOLUTION HAPPENS AT BOOTSTRAP, NOT PER CALL (D4). Workspace
7
- * resolution is I/O (a `workspace.count()` + `findUnique()`), but
8
- * `getMcpContentAdapter()` stays SYNCHRONOUS — every one of its thirteen
9
- * call sites (nine read tools, `audit-single-page.ts`, and the three write
10
- * tools) calls it without `await`. Making it async would force `await` at
11
- * every one of those sites, a needless cross-cutting edit to a hard-floor
12
- * surface (`apps/mcp/src/tools/**`). So `apps/mcp/src/index.ts` awaits
13
- * `initMcpPublicWorkspace()` once, before either transport branch, and the
14
- * result is memoised here for `mcpPublicWorkspace()`'s synchronous read.
15
- *
16
- * A tool invoked before `initMcpPublicWorkspace()` has resolved sees the
17
- * module's initial `{ kind: "not-required" }` state — which the seam reads
18
- * exactly like an unresolved deployment under `database` mode (the empty
19
- * adapter, never content). That is the accepted, safe-direction cost D4
20
- * names, and it's what keeps the 350 pre-existing tests — which never call
21
- * `init` — on the byte-identical MDX path.
22
- *
23
- * NO-OP UNLESS THE ENVIRONMENT SELECTS `database` (D6). On `mdx` and
24
- * `projection`, `initMcpPublicWorkspace()`'s first statement is the same
25
- * `resolvedAdapterKind()` test the seam itself uses, and it returns before
26
- * any `await import()` — no database round-trip, no `DATABASE_URL` read, on
27
- * every MDX-only deployment.
28
- *
29
- * THE ONE-WORKSPACE PREDICATE IS SHARED, NOT REIMPLEMENTED (D2). This module
30
- * issues no direct tenant-model query of its own — it delegates to
31
- * `@working-theory/database/tenancy`'s `resolveDefaultWorkspaceRow`, the same
32
- * predicate `apps/api/src/services/default-tenant.ts` re-points at. One
33
- * predicate, reached from two apps, never two predicates (NFR-7).
34
- *
35
- * THE LAZY CLIENT (D7). The `prisma` injection option is the seam AC-1/AC-2
36
- * are scored through: when the caller supplies one, `./prisma.js` (the
37
- * module that constructs a real `PrismaClient`) is never imported — which is
38
- * what keeps every test in this repo's ordinary Jest run off a real
39
- * database connection (NFR-6).
40
- */
41
- import {
42
- resolvedAdapterKind,
43
- type ArtifactPrismaClient,
44
- } from "@working-theory/content-adapters";
45
- import {
46
- resolveDefaultWorkspaceRow,
47
- type WorkspacePredicateClient,
48
- } from "@working-theory/database/tenancy";
49
-
50
- /**
51
- * The three answers the MCP server's own workspace resolution can reach.
52
- * `reason` exists for the caller's own logging only — no MCP tool emits it
53
- * to the (anonymous, unauthenticated) caller (NFR-4, mirroring
54
- * `apps/api/src/services/public-site-resolver.ts`'s identical
55
- * `PublicSiteResolution`). Unlike that HTTP twin, there is no `host-unmatched`
56
- * arm here: an MCP stdio session carries no HTTP request and no host to
57
- * mismatch against (§2.3 — a host→workspace branch is explicitly out of
58
- * scope, #3635's to add).
59
- */
60
- export type McpWorkspaceResolution =
61
- | { kind: "not-required" }
62
- | { kind: "resolved"; workspaceId: string; prisma: ArtifactPrismaClient }
63
- | { kind: "unresolved"; reason: "ambiguous" };
64
-
65
- export interface InitMcpPublicWorkspaceOptions {
66
- /**
67
- * Injection seam for tests (D7, D11) — when supplied, `initMcpPublicWorkspace()`
68
- * uses it and never loads `./prisma.js`. Typed as the narrow surface THIS
69
- * function itself calls (`workspace.count`/`findUnique`); the real
70
- * `PrismaClient` (or a caller-injected structural equivalent) is
71
- * structurally wider and also satisfies `ArtifactPrismaClient`, which is
72
- * what the seam later forwards to `resolveContentAdapter()`.
73
- */
74
- prisma?: WorkspacePredicateClient;
75
- }
76
-
77
- let resolution: McpWorkspaceResolution = { kind: "not-required" };
78
-
79
- /**
80
- * Resolves the MCP server's workspace, once. Memoises the result for
81
- * `mcpPublicWorkspace()`'s synchronous read. Safe to call more than once
82
- * (each call re-resolves and re-memoises) — production calls it exactly once,
83
- * at bootstrap (`index.ts`).
84
- */
85
- export async function initMcpPublicWorkspace(
86
- options: InitMcpPublicWorkspaceOptions = {},
87
- ): Promise<McpWorkspaceResolution> {
88
- if (resolvedAdapterKind() !== "database") {
89
- resolution = { kind: "not-required" };
90
- return resolution;
91
- }
92
-
93
- // Deferred — see this file's header (D7) and #5852's identical deferral of
94
- // apps/api's own client (`services/public-site-resolver.ts`).
95
- const prisma =
96
- options.prisma ?? (await import("./prisma.js")).getMcpPrismaClient();
97
- const workspace = await resolveDefaultWorkspaceRow(prisma);
98
- resolution =
99
- workspace === null
100
- ? { kind: "unresolved", reason: "ambiguous" }
101
- : {
102
- kind: "resolved",
103
- workspaceId: workspace.id,
104
- prisma: prisma as unknown as ArtifactPrismaClient,
105
- };
106
- return resolution;
107
- }
108
-
109
- /**
110
- * The memoised resolution, read synchronously. `content-adapter.ts`'s
111
- * `database` branch is the one caller in production; every arm other than
112
- * `{ kind: "resolved" }` maps to the fail-closed empty adapter.
113
- */
114
- export function mcpPublicWorkspace(): McpWorkspaceResolution {
115
- return resolution;
116
- }
117
-
118
- /** Test-only injector — sets the memoised resolution directly, bypassing the
119
- * tenancy predicate entirely. This is the seam `read_content.test.ts`,
120
- * `list_pages.test.ts` and `fail-closed-tools.test.ts` use: they care about
121
- * the CONTENT tools' behaviour under a given resolution, not about exercising
122
- * the resolution logic itself (that's `public-workspace.test.ts`'s job, via
123
- * the real `initMcpPublicWorkspace({ prisma: <stub> })`). */
124
- export function __setMcpPublicWorkspaceForTest(
125
- next: McpWorkspaceResolution,
126
- ): void {
127
- resolution = next;
128
- }
129
-
130
- /** Test-only reset — returns to the module's initial, pre-bootstrap state. */
131
- export function resetMcpPublicWorkspace(): void {
132
- resolution = { kind: "not-required" };
133
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * resolveLocale — validate a caller-supplied locale against the project's
3
- * allowlist. Phase 3 S3.
4
- *
5
- * Returns the requested locale when it's present in `readLocales()`;
6
- * otherwise silently falls back to the project's default locale (AC-i18n-07).
7
- *
8
- * Failures reading `project.yaml` degrade to a default-locale-only allowlist
9
- * — mirrors the same defensive behavior in `apps/api/src/routes/content/*`.
10
- *
11
- * This boundary check is defense-in-depth on top of the adapter's BCP-47
12
- * regex; the adapter still applies its own check and fallback chain on
13
- * every read.
14
- */
15
-
16
- import { readDefaultLocale, readLocales } from "./locales.js";
17
-
18
- export function resolveLocale(requested: string | undefined): string {
19
- const defaultLocale = readDefaultLocale();
20
- if (requested === undefined) return defaultLocale;
21
-
22
- let allow: string[];
23
- try {
24
- allow = readLocales();
25
- } catch {
26
- allow = [defaultLocale];
27
- }
28
-
29
- return allow.includes(requested) ? requested : defaultLocale;
30
- }