create-ailk 0.24.0 → 0.25.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 (599) hide show
  1. package/README.md +42 -20
  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 +1 -1
  14. package/dist/lib/fetch-template-snapshot.js +7 -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 +34 -12
  19. package/dist/module-architecture.d.ts +20 -3
  20. package/dist/module-architecture.js +117 -550
  21. package/dist/paid-sections.d.ts +25 -1
  22. package/dist/paid-sections.js +88 -3
  23. package/dist/surfaces.js +10 -2
  24. package/dist/template-record.d.ts +14 -4
  25. package/dist/template-record.js +23 -5
  26. package/dist/topology.d.ts +16 -3
  27. package/dist/topology.js +31 -19
  28. package/dist/update.d.ts +10 -1
  29. package/dist/update.js +540 -16
  30. package/package.json +3 -3
  31. package/release-scope.json +1 -1
  32. package/templates/.claude/cloudparity-repo-hooks.json +5 -0
  33. package/templates/.claude/hooks/template-guard.sh +137 -0
  34. package/templates/.claude/rules/extending.md +106 -0
  35. package/templates/.claude/rules/loop-contract.md +2 -2
  36. package/templates/.claude/settings.json +11 -0
  37. package/templates/.env.example +5 -5
  38. package/templates/.github/workflows/ci.yml +7 -4
  39. package/templates/CLAUDE.md +11 -1
  40. package/templates/CONVENTIONS.md +8 -10
  41. package/templates/README.md +14 -13
  42. package/templates/apps/api/.env.example +2 -2
  43. package/templates/apps/api/CLAUDE.md +102 -76
  44. package/templates/apps/api/jest.config.cjs +15 -5
  45. package/templates/apps/api/package.json +16 -20
  46. package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
  47. package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
  48. package/templates/apps/api/src/index.ts +1 -1
  49. package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
  50. package/templates/apps/api/src/modules/commerce.ts +10 -0
  51. package/templates/apps/api/src/modules/content-write.ts +10 -0
  52. package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
  53. package/templates/apps/api/src/modules/scheduling.ts +10 -0
  54. package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
  55. package/templates/apps/api/src/modules/workspace.ts +10 -0
  56. package/templates/apps/api/src/server.ts +117 -1882
  57. package/templates/apps/api/vercel.json +2 -2
  58. package/templates/apps/mcp/CLAUDE.md +67 -20
  59. package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
  60. package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
  61. package/templates/apps/mcp/jest.config.cjs +6 -1
  62. package/templates/apps/mcp/package.json +5 -13
  63. package/templates/apps/mcp/src/app.ts +8 -7
  64. package/templates/apps/mcp/src/index.ts +6 -34
  65. package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
  66. package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
  67. package/templates/apps/mcp/src/site.ts +12 -0
  68. package/templates/apps/web/.env.example +1 -1
  69. package/templates/apps/web/CLAUDE.md +10 -3
  70. package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
  71. package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
  72. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
  73. package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
  74. package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
  75. package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
  76. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
  77. package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
  78. package/templates/apps/web/app/api/revalidate/route.ts +3 -3
  79. package/templates/apps/web/auth.ts +2 -2
  80. package/templates/apps/web/jest.config.cjs +1 -0
  81. package/templates/apps/web/lib/auth-email.ts +1 -1
  82. package/templates/apps/web/lib/relay.ts +2 -2
  83. package/templates/apps/web/lib/release-scope.ts +47 -0
  84. package/templates/apps/web/lib/server-api.ts +1 -1
  85. package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
  86. package/templates/customizations.yaml +37 -0
  87. package/templates/database/prisma.config.ts +10 -14
  88. package/templates/database/seed-test.ts +2 -2
  89. package/templates/database/seed.ts +5 -5
  90. package/templates/package.json +12 -6
  91. package/templates/pnpm-workspace.yaml +0 -1
  92. package/templates/project.yaml +16 -8
  93. package/templates/tools/jest/reporters.cjs +65 -0
  94. package/templates/tools/lint-architecture.ts +553 -7
  95. package/templates/tsconfig.json +1 -2
  96. package/versions.json +48 -35
  97. package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
  98. package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
  99. package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
  100. package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
  101. package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
  102. package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
  103. package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
  104. package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
  105. package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
  106. package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
  107. package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
  108. package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
  109. package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
  110. package/templates/apps/api/src/bin/spokes.ts +0 -198
  111. package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
  112. package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
  113. package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
  114. package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
  115. package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
  116. package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
  117. package/templates/apps/api/src/config/index.ts +0 -596
  118. package/templates/apps/api/src/config/modules.ts +0 -83
  119. package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
  120. package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
  121. package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
  122. package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
  123. package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
  124. package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
  125. package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
  126. package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
  127. package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
  128. package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
  129. package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
  130. package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
  131. package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
  132. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
  133. package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
  134. package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
  135. package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
  136. package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
  137. package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
  138. package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
  139. package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
  140. package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
  141. package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
  142. package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
  143. package/templates/apps/api/src/lib/agent-store.ts +0 -613
  144. package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
  145. package/templates/apps/api/src/lib/consent-store.ts +0 -363
  146. package/templates/apps/api/src/lib/content-adapter.ts +0 -112
  147. package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
  148. package/templates/apps/api/src/lib/error-serializer.ts +0 -164
  149. package/templates/apps/api/src/lib/errors.ts +0 -95
  150. package/templates/apps/api/src/lib/file-fallback.ts +0 -87
  151. package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
  152. package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
  153. package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
  154. package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
  155. package/templates/apps/api/src/lib/license-key-store.ts +0 -45
  156. package/templates/apps/api/src/lib/locales.ts +0 -201
  157. package/templates/apps/api/src/lib/outbound-http.ts +0 -127
  158. package/templates/apps/api/src/lib/prisma.ts +0 -21
  159. package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
  160. package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
  161. package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
  162. package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
  163. package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
  164. package/templates/apps/api/src/lib/site.ts +0 -257
  165. package/templates/apps/api/src/lib/slice-load.ts +0 -90
  166. package/templates/apps/api/src/lib/spoke-store.ts +0 -180
  167. package/templates/apps/api/src/lib/stripe.ts +0 -321
  168. package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
  169. package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
  170. package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
  171. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
  172. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
  173. package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
  174. package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
  175. package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
  176. package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
  177. package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
  178. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
  179. package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
  180. package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
  181. package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
  182. package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
  183. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
  184. package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
  185. package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
  186. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
  187. package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
  188. package/templates/apps/api/src/middleware/auth.ts +0 -864
  189. package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
  190. package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
  191. package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
  192. package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
  193. package/templates/apps/api/src/openapi/index.ts +0 -18
  194. package/templates/apps/api/src/openapi/spec.ts +0 -2148
  195. package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
  196. package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
  197. package/templates/apps/api/src/routes/aeo/index.ts +0 -107
  198. package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
  199. package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
  200. package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
  201. package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
  202. package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
  203. package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
  204. package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
  205. package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
  206. package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
  207. package/templates/apps/api/src/routes/auth/user.ts +0 -305
  208. package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
  209. package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
  210. package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
  211. package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
  212. package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
  213. package/templates/apps/api/src/routes/checkout/index.ts +0 -34
  214. package/templates/apps/api/src/routes/checkout/session.ts +0 -171
  215. package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
  216. package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
  217. package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
  218. package/templates/apps/api/src/routes/consent/account.ts +0 -268
  219. package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
  220. package/templates/apps/api/src/routes/consent/index.ts +0 -26
  221. package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
  222. package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
  223. package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
  224. package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
  225. package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
  226. package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
  227. package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
  228. package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
  229. package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
  230. package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
  231. package/templates/apps/api/src/routes/content/get-page.ts +0 -183
  232. package/templates/apps/api/src/routes/content/index.ts +0 -49
  233. package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
  234. package/templates/apps/api/src/routes/content/list-types.ts +0 -19
  235. package/templates/apps/api/src/routes/content/offerings.ts +0 -184
  236. package/templates/apps/api/src/routes/content/pricing.ts +0 -176
  237. package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
  238. package/templates/apps/api/src/routes/content/search.ts +0 -100
  239. package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
  240. package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
  241. package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
  242. package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
  243. package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
  244. package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
  245. package/templates/apps/api/src/routes/leads/index.ts +0 -639
  246. package/templates/apps/api/src/routes/leads/list.ts +0 -104
  247. package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
  248. package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
  249. package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
  250. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
  251. package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
  252. package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
  253. package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
  254. package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
  255. package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
  256. package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
  257. package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
  258. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
  259. package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
  260. package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
  261. package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
  262. package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
  263. package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
  264. package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
  265. package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
  266. package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
  267. package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
  268. package/templates/apps/api/src/routes/requests/index.ts +0 -54
  269. package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
  270. package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
  271. package/templates/apps/api/src/routes/webhooks/README.md +0 -398
  272. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
  273. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
  274. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
  275. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
  276. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
  277. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
  278. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
  279. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
  280. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
  281. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
  282. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
  283. package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
  284. package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
  285. package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
  286. package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
  287. package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
  288. package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
  289. package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
  290. package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
  291. package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
  292. package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
  293. package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
  294. package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
  295. package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
  296. package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
  297. package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
  298. package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
  299. package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
  300. package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
  301. package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
  302. package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
  303. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
  304. package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
  305. package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
  306. package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
  307. package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
  308. package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
  309. package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
  310. package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
  311. package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
  312. package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
  313. package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
  314. package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
  315. package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
  316. package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
  317. package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
  318. package/templates/apps/api/src/services/abandon-email.ts +0 -336
  319. package/templates/apps/api/src/services/aeo-score.ts +0 -325
  320. package/templates/apps/api/src/services/answer-distributions.ts +0 -138
  321. package/templates/apps/api/src/services/audit-log.ts +0 -961
  322. package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
  323. package/templates/apps/api/src/services/consent.ts +0 -834
  324. package/templates/apps/api/src/services/default-tenant.ts +0 -416
  325. package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
  326. package/templates/apps/api/src/services/dunning-policy.ts +0 -294
  327. package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
  328. package/templates/apps/api/src/services/entitlements.ts +0 -338
  329. package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
  330. package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
  331. package/templates/apps/api/src/services/lead-promotion.ts +0 -160
  332. package/templates/apps/api/src/services/lead-routing.ts +0 -1372
  333. package/templates/apps/api/src/services/leads-inbox.ts +0 -312
  334. package/templates/apps/api/src/services/listing-config.ts +0 -178
  335. package/templates/apps/api/src/services/magnet-completion.ts +0 -242
  336. package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
  337. package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
  338. package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
  339. package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
  340. package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
  341. package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
  342. package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
  343. package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
  344. package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
  345. package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
  346. package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
  347. package/templates/apps/api/src/services/offerings/index.ts +0 -614
  348. package/templates/apps/api/src/services/offerings/source.ts +0 -140
  349. package/templates/apps/api/src/services/offerings/store.ts +0 -150
  350. package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
  351. package/templates/apps/api/src/services/person.ts +0 -1211
  352. package/templates/apps/api/src/services/plan-offerings.ts +0 -125
  353. package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
  354. package/templates/apps/api/src/services/project-listings.ts +0 -2085
  355. package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
  356. package/templates/apps/api/src/services/request-confirm.ts +0 -698
  357. package/templates/apps/api/src/services/revalidation.ts +0 -235
  358. package/templates/apps/api/src/services/slack-notify.ts +0 -291
  359. package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
  360. package/templates/apps/api/src/services/usage-credits.ts +0 -340
  361. package/templates/apps/api/src/services/verified-email.ts +0 -71
  362. package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
  363. package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
  364. package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
  365. package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
  366. package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
  367. package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
  368. package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
  369. package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
  370. package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
  371. package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
  372. package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
  373. package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
  374. package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
  375. package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
  376. package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
  377. package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
  378. package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
  379. package/templates/apps/mcp/__tests__/index.test.ts +0 -195
  380. package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
  381. package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
  382. package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
  383. package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
  384. package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
  385. package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
  386. package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
  387. package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
  388. package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
  389. package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
  390. package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
  391. package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
  392. package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
  393. package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
  394. package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
  395. package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
  396. package/templates/apps/mcp/__tests__/server.test.ts +0 -388
  397. package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
  398. package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
  399. package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
  400. package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
  401. package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
  402. package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
  403. package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
  404. package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
  405. package/templates/apps/mcp/src/abuse/index.ts +0 -349
  406. package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
  407. package/templates/apps/mcp/src/boot.ts +0 -167
  408. package/templates/apps/mcp/src/config/modules.ts +0 -43
  409. package/templates/apps/mcp/src/http-transport.ts +0 -564
  410. package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
  411. package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
  412. package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
  413. package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
  414. package/templates/apps/mcp/src/lib/errors.ts +0 -61
  415. package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
  416. package/templates/apps/mcp/src/lib/locales.ts +0 -171
  417. package/templates/apps/mcp/src/lib/prisma.ts +0 -39
  418. package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
  419. package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
  420. package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
  421. package/templates/apps/mcp/src/lib/site-config.ts +0 -53
  422. package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
  423. package/templates/apps/mcp/src/request-context.ts +0 -52
  424. package/templates/apps/mcp/src/server.ts +0 -343
  425. package/templates/apps/mcp/src/serverless-app.ts +0 -88
  426. package/templates/apps/mcp/src/tools/audit.ts +0 -127
  427. package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
  428. package/templates/apps/mcp/src/tools/create_project.ts +0 -134
  429. package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
  430. package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
  431. package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
  432. package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
  433. package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
  434. package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
  435. package/templates/apps/mcp/src/tools/index.ts +0 -138
  436. package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
  437. package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
  438. package/templates/apps/mcp/src/tools/proposals.ts +0 -27
  439. package/templates/apps/mcp/src/tools/purchase.ts +0 -205
  440. package/templates/apps/mcp/src/tools/read_content.ts +0 -81
  441. package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
  442. package/templates/apps/mcp/src/tools/search_content.ts +0 -63
  443. package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
  444. package/templates/apps/mcp/src/workspace-server.ts +0 -224
  445. package/templates/database/CHANGELOG.md +0 -981
  446. package/templates/database/LICENSE +0 -202
  447. package/templates/database/NOTICE +0 -2
  448. package/templates/database/README.md +0 -243
  449. package/templates/database/__tests__/agents.db.test.ts +0 -320
  450. package/templates/database/__tests__/appointment.db.test.ts +0 -106
  451. package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
  452. package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
  453. package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
  454. package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
  455. package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
  456. package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
  457. package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
  458. package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
  459. package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
  460. package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
  461. package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
  462. package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
  463. package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
  464. package/templates/database/__tests__/flows-presets.test.ts +0 -173
  465. package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
  466. package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
  467. package/templates/database/__tests__/member-area.db.test.ts +0 -257
  468. package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
  469. package/templates/database/__tests__/member-contract.db.test.ts +0 -413
  470. package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
  471. package/templates/database/__tests__/offerings-migration.test.ts +0 -197
  472. package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
  473. package/templates/database/__tests__/offerings.db.test.ts +0 -303
  474. package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
  475. package/templates/database/__tests__/person-contact.db.test.ts +0 -563
  476. package/templates/database/__tests__/person-notes.db.test.ts +0 -249
  477. package/templates/database/__tests__/person.db.test.ts +0 -586
  478. package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
  479. package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
  480. package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
  481. package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
  482. package/templates/database/__tests__/seed.test.ts +0 -272
  483. package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
  484. package/templates/database/__tests__/tenancy.test.ts +0 -141
  485. package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
  486. package/templates/database/__tests__/user-cascade.test.ts +0 -140
  487. package/templates/database/_gitignore +0 -8
  488. package/templates/database/auth/.gitkeep +0 -0
  489. package/templates/database/auth/schema.prisma +0 -641
  490. package/templates/database/config/.gitkeep +0 -0
  491. package/templates/database/config/schema.prisma +0 -441
  492. package/templates/database/content/.gitkeep +0 -0
  493. package/templates/database/content/schema.prisma +0 -339
  494. package/templates/database/eslint.config.mjs +0 -69
  495. package/templates/database/flows/listing-diagnostic.ts +0 -182
  496. package/templates/database/flows/presets.ts +0 -315
  497. package/templates/database/inbox/.gitkeep +0 -0
  498. package/templates/database/inbox/README.md +0 -3
  499. package/templates/database/inbox/__tests__/schema.test.ts +0 -44
  500. package/templates/database/inbox/schema.prisma +0 -1447
  501. package/templates/database/jest.config.cjs +0 -36
  502. package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
  503. package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
  504. package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
  505. package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
  506. package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
  507. package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
  508. package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
  509. package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
  510. package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
  511. package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
  512. package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
  513. package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
  514. package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
  515. package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
  516. package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
  517. package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
  518. package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
  519. package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
  520. package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
  521. package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
  522. package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
  523. package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
  524. package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
  525. package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
  526. package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
  527. package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
  528. package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
  529. package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
  530. package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
  531. package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
  532. package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
  533. package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
  534. package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
  535. package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
  536. package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
  537. package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
  538. package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
  539. package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
  540. package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
  541. package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
  542. package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
  543. package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
  544. package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
  545. package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
  546. package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
  547. package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
  548. package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
  549. package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
  550. package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
  551. package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
  552. package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
  553. package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
  554. package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
  555. package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
  556. package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
  557. package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
  558. package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
  559. package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
  560. package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
  561. package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
  562. package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
  563. package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
  564. package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
  565. package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
  566. package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
  567. package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
  568. package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
  569. package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
  570. package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
  571. package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
  572. package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
  573. package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
  574. package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
  575. package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
  576. package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
  577. package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
  578. package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
  579. package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
  580. package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
  581. package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
  582. package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
  583. package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
  584. package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
  585. package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
  586. package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
  587. package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
  588. package/templates/database/migrations/migration_lock.toml +0 -3
  589. package/templates/database/ops/.gitkeep +0 -0
  590. package/templates/database/ops/schema.prisma +0 -43
  591. package/templates/database/package.json +0 -89
  592. package/templates/database/schema.prisma +0 -71
  593. package/templates/database/scripts/db-generate-locked.sh +0 -80
  594. package/templates/database/scripts/person-backfill.sql +0 -132
  595. package/templates/database/tenancy.ts +0 -183
  596. package/templates/database/tsconfig.build.json +0 -16
  597. package/templates/database/tsconfig.flows.json +0 -15
  598. package/templates/database/tsconfig.json +0 -16
  599. 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
- }