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,210 +0,0 @@
1
- -- #6314 — ProjectListing gains `captured_by_flow_id`: the listicle-kind
2
- -- FlowDefinition that CAPTURED the application, so a magnet's own
3
- -- Applications list can be scoped to its own submissions rather than to the
4
- -- whole workspace. Nothing constrains a workspace to one listicle magnet
5
- -- ("flow_definitions" carries a (site_id, slug) unique and no
6
- -- (site_id, kind) one), so workspace-only scoping would silently conflate
7
- -- two listicle magnets' applications.
8
- --
9
- -- A NEW MIGRATION DIRECTORY, not an amendment of the already-merged
10
- -- 20260922120000_tenancy_fence (spec D8). #6254 AC-1's one-migration-per-
11
- -- milestone rule names #6314 by number in that migration's own header, so
12
- -- this is a DEPARTURE taken deliberately and with the operator's
13
- -- confirmation (2026-09-20), not a gap that rule failed to cover. Two
14
- -- reasons, in order of weight:
15
- -- 1. Prisma records a per-migration CHECKSUM. `prisma migrate deploy`
16
- -- refuses a migration whose file no longer matches `_prisma_migrations`,
17
- -- so a database that already applied the fence directory would never
18
- -- receive this column or its index while the new code assumes both.
19
- -- "Editing it in place is a silent no-op" is true of the SQL; it is not
20
- -- true of the checksum.
21
- -- 2. apps/api/CLAUDE.md: "Never edit a shipped migration — add a new one."
22
- -- Where a spec's convenience and an in-repo rule disagree, the rule wins.
23
- --
24
- -- PURELY ADDITIVE: one nullable column, one index. NO UPDATE, NO backfill,
25
- -- and NO foreign key.
26
- --
27
- -- NO BACKFILL, deliberately (spec § 3.5 / AC-3, operator ruling 2026-09-19).
28
- -- No existing row carries evidence naming the magnet that captured it — no
29
- -- referrer, no session link, no slug. A backfill would have to guess "the
30
- -- workspace's only listicle magnet", which is exactly the conflation this
31
- -- column exists to remove, made permanent and unauditable. Every row written
32
- -- before this migration therefore reads NULL for the life of the row:
33
- -- unattributed, excluded from every per-magnet list (NULL never equals a
34
- -- magnet id, so the exclusion is a property of the query, not a filter that
35
- -- can be forgotten), and UNCHANGED in the workspace Inbox — no operator loses
36
- -- access to any application. This is the same discipline the founder-name
37
- -- parts (#5407), the address parts (#5279) and `owner_user_id` (#5295) each
38
- -- follow: a value that can only be guessed must not be asserted.
39
- --
40
- -- NO foreign key, deliberately (spec § 3.2, operator decision 2026-09-20,
41
- -- which withdrew the 2026-09-19 ruling's "on-delete set-null" clause). Both
42
- -- models live in the `inbox` namespace, so ADR 0009 invariant #1 (which bans
43
- -- CROSS-namespace relations) does not reach this column — permission was
44
- -- never the question. The convention is: of the 24 foreign-key constraints
45
- -- under database/migrations/**, every one targets the `auth` namespace
46
- -- ("users"); the intra-inbox columns listing_id, lead_id, grant_id and
47
- -- flow_session_id carry none. The composite (workspace_id, …) shape was
48
- -- itself offered and declined on "listing_csv_sends" the day before this
49
- -- spec's pin. Integrity rests on the server-side resolve in
50
- -- `startProjectListingDraft` (site_id + workspace_id + kind = 'listicle')
51
- -- and on the read carrying the injected workspace_id alongside the magnet id
52
- -- — so a dangling or foreign value yields no rows, never another workspace's.
53
- -- Nothing deletes a flow_definitions row either (routes/magnets D5: "No
54
- -- DELETE"), so ON DELETE SET NULL would have described no live code path.
55
- --
56
- -- RE-RUNNABLE: IF NOT EXISTS on both DDL statements, the census temp table is
57
- -- dropped-if-exists before it is built, and post-assertion 2 is skipped on a
58
- -- re-apply (it proves this file grew no backfill, which only the first
59
- -- application can show — see its own comment). So re-applying this directory
60
- -- against a database that already has the column is inert rather than an abort
61
- -- that would wedge the ledger.
62
- --
63
- -- ORDER-SAFE: the index references "workspace_id", added by
64
- -- 20260919140000_inbox_workspace_key and made NOT NULL by
65
- -- 20260922120000_tenancy_fence — both of which this migration sorts strictly
66
- -- after. The guard below is therefore a formality in the normal case, kept
67
- -- for the reason 20260920130000_lead_workspace_source_index keeps one: IF NOT
68
- -- EXISTS guards the INDEX's own name, not the column it references, so an
69
- -- unguarded CREATE INDEX would abort inside prisma migrate's per-migration
70
- -- transaction and wedge the ledger for the whole deployment if that earlier
71
- -- migration were ever skipped, renamed, or rolled back on a given database.
72
- --
73
- -- CREATE INDEX is NOT CONCURRENT, and cannot be: CONCURRENTLY may not run
74
- -- inside prisma migrate's per-migration transaction. It therefore takes a
75
- -- lock on "project_listings" for its duration — the same accepted risk
76
- -- 20260920130000_lead_workspace_source_index names. A deployment with a large
77
- -- project_listings table should create this index out-of-band with
78
- -- CONCURRENTLY first; the IF NOT EXISTS guard then makes the statement a
79
- -- no-op.
80
- --
81
- -- Rollback:
82
- -- DROP INDEX "project_listings_workspace_id_captured_by_flow_id_idx";
83
- -- ALTER TABLE "project_listings" DROP COLUMN "captured_by_flow_id";
84
- -- Safe at any point: the column is nullable and unconstrained, and no row's
85
- -- correctness depends on it beyond per-magnet attribution.
86
-
87
- -- A census, so the post-assertions below can prove nothing moved.
88
- --
89
- -- `column_preexisted` is captured HERE, before the ALTER, and it is what keeps
90
- -- assertion 2 honest on a RE-APPLY. That assertion proves a property of THIS
91
- -- FILE (it performs no backfill), which is only observable on the application
92
- -- that first adds the column: once the application has written even one real
93
- -- attribution, "no row is attributed" is false for reasons this migration had
94
- -- nothing to do with. Asserting it unconditionally would abort inside prisma
95
- -- migrate's per-migration transaction and wedge the ledger for every later
96
- -- migration on that database — on a restored snapshot, a `migrate resolve
97
- -- --rolled-back` redeploy, or a branch of production.
98
- -- `pg_temp.`-qualified: DROP TABLE does not distinguish temporary from
99
- -- permanent relations, and at this point the session holds no temp table, so
100
- -- an unqualified name would resolve through search_path to `public` and drop
101
- -- a same-named PERMANENT table — inside the transaction prisma commits.
102
- DROP TABLE IF EXISTS pg_temp."_6314_capture_census";
103
- CREATE TEMP TABLE "_6314_capture_census" AS
104
- SELECT
105
- count(*) AS p,
106
- EXISTS (
107
- SELECT 1 FROM information_schema.columns
108
- -- `table_schema = current_schema()` is load-bearing, not tidiness:
109
- -- `information_schema.columns` spans EVERY schema in the database, so
110
- -- without it the probe answers "does any table anywhere named
111
- -- project_listings carry this column" rather than "does the table this
112
- -- migration is about to alter carry it". A pre-migration snapshot in a
113
- -- side schema (`CREATE TABLE backup.project_listings AS SELECT ...`, a
114
- -- `pg_dump -n` restore) would then make a genuine FIRST apply take the
115
- -- skip branch below and wave a real backfill through unchecked — the
116
- -- exact AC-8 property assertion 2 exists to prove.
117
- WHERE table_schema = current_schema()
118
- AND table_name = 'project_listings'
119
- AND column_name = 'captured_by_flow_id'
120
- ) AS column_preexisted
121
- FROM "project_listings";
122
-
123
- -- AlterTable — the capturing magnet's id. Nullable and unconstrained, so a
124
- -- row predating this migration reads NULL and nothing here can reject it.
125
- ALTER TABLE "project_listings" ADD COLUMN IF NOT EXISTS "captured_by_flow_id" TEXT;
126
-
127
- -- CreateIndex — the read is workspace_id = $1 AND captured_by_flow_id = $2,
128
- -- ordered by created_at desc. A two-column (workspace_id, captured_by_flow_id)
129
- -- index serves it directly. With no foreign key there is no cascade, so no
130
- -- referencing-side index is owed beyond this one.
131
- DO $$ BEGIN
132
- IF EXISTS (
133
- SELECT 1 FROM information_schema.columns
134
- -- `table_schema = current_schema()` for the same reason the census probe
135
- -- above carries it, and the failure direction here is WORSE. A decoy
136
- -- `project_listings` in another schema makes this EXISTS spuriously true;
137
- -- the CREATE INDEX below then runs against the table search_path actually
138
- -- resolves, hits `column "workspace_id" does not exist`, and aborts the
139
- -- whole migration transaction — a wedged ledger, where the census probe's
140
- -- equivalent merely skips an assertion. The guard must ask about the table
141
- -- the statement it protects will really touch.
142
- WHERE table_schema = current_schema()
143
- AND table_name = 'project_listings'
144
- AND column_name = 'workspace_id'
145
- ) THEN
146
- CREATE INDEX IF NOT EXISTS "project_listings_workspace_id_captured_by_flow_id_idx"
147
- ON "project_listings"("workspace_id", "captured_by_flow_id");
148
- ELSE
149
- RAISE NOTICE '#6314: project_listings.workspace_id absent — index skipped. 20260919140000_inbox_workspace_key has not run against this database; the per-magnet Applications read cannot be served efficiently until it does.';
150
- END IF;
151
- END $$;
152
-
153
- -- Post-assertions, in 20260922120000_tenancy_fence's own idiom.
154
- DO $$
155
- DECLARE
156
- before_p bigint;
157
- after_p bigint;
158
- attributed bigint;
159
- preexisted boolean;
160
- BEGIN
161
- SELECT p, column_preexisted INTO before_p, preexisted FROM "_6314_capture_census";
162
- SELECT count(*) INTO after_p FROM "project_listings";
163
-
164
- -- 1. Nothing LOST. Deliberately `<`, not `<>`.
165
- --
166
- -- An equality test here has no true-positive mode and one guaranteed
167
- -- false-positive mode, which is the worst shape a guard can have. No
168
- -- statement in this file modifies a row of "project_listings" (the whole
169
- -- file is five statements; read them), so the two counts can only diverge
170
- -- through a write committed by ANOTHER session between them. The census
171
- -- takes ACCESS SHARE; the ALTER takes ACCESS EXCLUSIVE, and until it does,
172
- -- the table stays open to writers. "project_listings" is written by an
173
- -- ANONYMOUS, unauthenticated route, so on a live deploy one application
174
- -- started mid-migration aborts the migration — and the retry meets the
175
- -- same race. That is a wedged ledger caused by the system working
176
- -- normally.
177
- --
178
- -- `<` keeps the property the assertion is actually for — this migration
179
- -- must never destroy a row — while letting a concurrent INSERT through.
180
- -- A DELETE or TRUNCATE creeping into this file still trips it.
181
- IF after_p < before_p THEN
182
- RAISE EXCEPTION
183
- '#6314 post-assertion: project_listings LOST row(s) across a purely additive migration (% -> %)',
184
- before_p, after_p;
185
- END IF;
186
-
187
- -- 2. Nothing guessed (AC-8): every PRE-EXISTING row reads NULL. This
188
- -- migration performs no UPDATE, so a non-NULL row on the application that
189
- -- first adds the column would mean the file grew a backfill the ruling
190
- -- refused.
191
- --
192
- -- Skipped when the column already existed: on a re-apply, attributed rows
193
- -- are the APPLICATION's own writes, not a backfill, and failing on them
194
- -- would wedge the migration ledger (see the census above). The assertion
195
- -- still fires where it can mean anything — the first application, which is
196
- -- the only run that can introduce a backfill.
197
- IF preexisted THEN
198
- RAISE NOTICE '#6314 post-assertion 2 skipped: captured_by_flow_id already existed, so this is a re-apply and any attributed row is an application write rather than a backfill.';
199
- ELSE
200
- SELECT count(*) INTO attributed
201
- FROM "project_listings" WHERE "captured_by_flow_id" IS NOT NULL;
202
- IF attributed <> 0 THEN
203
- RAISE EXCEPTION
204
- '#6314 post-assertion: % project_listings row(s) carry a captured_by_flow_id after a migration that performs no UPDATE — existing rows must stay unattributed (no backfill by guess)',
205
- attributed;
206
- END IF;
207
- END IF;
208
- END $$;
209
-
210
- DROP TABLE pg_temp."_6314_capture_census";
@@ -1,80 +0,0 @@
1
- -- #7532 — the hub's spoke registry and the booking-origin record (spec
2
- -- docs/specs/7532-a-spoke-s-public-reads-spec.md D1, D5).
3
- --
4
- -- spokes (auth) — one row per separately deployed site that
5
- -- calls this hub, bound to ONE workspace. It
6
- -- stores the SHA-256 digest of the spoke's
7
- -- hub-minted key, never the key. Deleting a
8
- -- workspace deletes its spokes (the FK below).
9
- -- appointment_origins (inbox) — (provider, booking uid) → workspace, written
10
- -- when a spoke's booking is created so the
11
- -- deployment-wide Cal.com webhook stores the
12
- -- booking in the spoke's workspace. One origin
13
- -- per booking uid. No foreign key and no
14
- -- relation (ADR 0009): workspace_id and
15
- -- spoke_id are plain columns with format CHECKs.
16
- --
17
- -- PURELY ADDITIVE: two new tables, their indexes and one FK to "workspaces".
18
- -- No statement touches an existing table's rows or columns, so there is no
19
- -- pre-assertion block — this migration cannot lose a row.
20
- --
21
- -- Rollback: DROP TABLE "appointment_origins"; DROP TABLE "spokes". Safe while
22
- -- nothing but #7532's own code reads them.
23
-
24
- -- CreateTable
25
- CREATE TABLE "spokes" (
26
- "id" TEXT NOT NULL DEFAULT ('spoke_'::text || (uuidv7())::text),
27
- "workspace_id" TEXT NOT NULL,
28
- "name" VARCHAR(120) NOT NULL,
29
- "credential_hash" CHAR(64) NOT NULL,
30
- "credential_prefix" VARCHAR(24) NOT NULL,
31
- "revoked_at" TIMESTAMP(3),
32
- "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
33
- "updated_at" TIMESTAMP(3) NOT NULL,
34
-
35
- CONSTRAINT "spokes_pkey" PRIMARY KEY ("id")
36
- );
37
-
38
- -- CreateTable
39
- CREATE TABLE "appointment_origins" (
40
- "id" TEXT NOT NULL DEFAULT ('apptorg_'::text || (uuidv7())::text),
41
- "provider" VARCHAR(32) NOT NULL DEFAULT 'cal',
42
- "provider_booking_uid" VARCHAR(200) NOT NULL,
43
- "workspace_id" TEXT NOT NULL,
44
- "spoke_id" TEXT NOT NULL,
45
- "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
46
-
47
- CONSTRAINT "appointment_origins_pkey" PRIMARY KEY ("id")
48
- );
49
-
50
- -- CreateIndex
51
- -- The lookup a spoke's every request makes (`findSpokeByKeyHash`).
52
- CREATE UNIQUE INDEX "spokes_credential_hash_key" ON "spokes"("credential_hash");
53
-
54
- -- CreateIndex
55
- CREATE INDEX "spokes_workspace_id_idx" ON "spokes"("workspace_id");
56
-
57
- -- CreateIndex
58
- CREATE INDEX "appointment_origins_workspace_id_idx" ON "appointment_origins"("workspace_id");
59
-
60
- -- CreateIndex
61
- -- One origin per booking uid (spec D5). The bind inserts with
62
- -- ON CONFLICT DO NOTHING against this key.
63
- CREATE UNIQUE INDEX "appointment_origins_provider_provider_booking_uid_key" ON "appointment_origins"("provider", "provider_booking_uid");
64
-
65
- -- AddForeignKey
66
- ALTER TABLE "spokes" ADD CONSTRAINT "spokes_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE;
67
-
68
- -- ADR-0031 rule 3 — spokes: spoke_, appointment_origins: apptorg_ (registered
69
- -- in packages/ids/src/registry.ts; this migration's path is added to
70
- -- migration-sync.test.ts's PK_CHECK_MIGRATIONS).
71
- ALTER TABLE "spokes" ALTER COLUMN "id" TYPE text COLLATE "C";
72
- ALTER TABLE "spokes" ALTER COLUMN "id" SET DEFAULT ('spoke_'::text || (uuidv7())::text);
73
- ALTER TABLE "spokes" ADD CONSTRAINT "spokes_id_format" CHECK ("id" ~ '^spoke_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
74
- ALTER TABLE "spokes" ADD CONSTRAINT "spokes_workspace_id_format" CHECK ("workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
75
-
76
- ALTER TABLE "appointment_origins" ALTER COLUMN "id" TYPE text COLLATE "C";
77
- ALTER TABLE "appointment_origins" ALTER COLUMN "id" SET DEFAULT ('apptorg_'::text || (uuidv7())::text);
78
- ALTER TABLE "appointment_origins" ADD CONSTRAINT "appointment_origins_id_format" CHECK ("id" ~ '^apptorg_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
79
- ALTER TABLE "appointment_origins" ADD CONSTRAINT "appointment_origins_spoke_id_format" CHECK ("spoke_id" ~ '^spoke_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
80
- ALTER TABLE "appointment_origins" ADD CONSTRAINT "appointment_origins_workspace_id_format" CHECK ("workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
@@ -1,49 +0,0 @@
1
- -- #7533 — the SchedulingConnection model: a workspace's own scheduling
2
- -- provider account (spec docs/specs/7533-a-scheduling-connection-per-workspace-spec.md
3
- -- D1). One row per workspace, keyed `@unique(workspace_id)` like its config
4
- -- sibling workspace_meetings; the credential and webhook secret columns hold
5
- -- AES-256-GCM ciphertext written only by apps/api's
6
- -- services/scheduling/connections.ts. `webhook_token` is the per-connection
7
- -- webhook entry point's routing id, unique so a delivery resolves at most
8
- -- one row.
9
- --
10
- -- One new table, two unique indexes, in the house style of
11
- -- 20260919130000_workspace_meetings (CreateTable + CreateIndex immediately
12
- -- followed by the ADR-0031 rule-3 id-format completion, in ONE migration
13
- -- since the table is new and needs no retrofit). No `workspace_id_format`
14
- -- CHECK and no `provider` CHECK, matching that same precedent (the API
15
- -- accepts only the provider ids its factory table knows).
16
- --
17
- -- No backfill, no constraint relaxed, no existing table touched.
18
- --
19
- -- Rollback: DROP TABLE "scheduling_connections". Every stored connection is
20
- -- lost; each workspace returns to the unconfigured state (or, on a
21
- -- one-workspace deployment, to the CAL_API_KEY env fallback).
22
-
23
- -- CreateTable
24
- CREATE TABLE "scheduling_connections" (
25
- "id" TEXT NOT NULL DEFAULT ('schconn_'::text || (uuidv7())::text),
26
- "workspace_id" TEXT NOT NULL,
27
- "provider" VARCHAR(32) NOT NULL,
28
- "credential_ciphertext" TEXT NOT NULL,
29
- "webhook_token" VARCHAR(64) NOT NULL,
30
- "webhook_secret_ciphertext" TEXT NOT NULL,
31
- "base_url" TEXT,
32
- "created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
33
- "updated_at" TIMESTAMPTZ NOT NULL,
34
-
35
- CONSTRAINT "scheduling_connections_pkey" PRIMARY KEY ("id")
36
- );
37
-
38
- -- CreateIndex
39
- CREATE UNIQUE INDEX "scheduling_connections_workspace_id_key" ON "scheduling_connections"("workspace_id");
40
-
41
- -- CreateIndex
42
- CREATE UNIQUE INDEX "scheduling_connections_webhook_token_key" ON "scheduling_connections"("webhook_token");
43
-
44
- -- ADR-0031 rule 3 — scheduling_connections: schconn_ (registered in
45
- -- packages/ids/src/registry.ts ENTITY_PREFIX.schedulingConnection; this
46
- -- migration's path is added to migration-sync.test.ts's PK_CHECK_MIGRATIONS).
47
- ALTER TABLE "scheduling_connections" ALTER COLUMN "id" TYPE text COLLATE "C";
48
- ALTER TABLE "scheduling_connections" ALTER COLUMN "id" SET DEFAULT ('schconn_'::text || (uuidv7())::text);
49
- ALTER TABLE "scheduling_connections" ADD CONSTRAINT "scheduling_connections_id_format" CHECK ("id" ~ '^schconn_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
@@ -1,84 +0,0 @@
1
- -- #3591 — the agent seat, step A (spec
2
- -- docs/specs/3591-tenant-scoped-agent-auth-secure-spec.md D1).
3
- --
4
- -- agents (auth) — one row per agent: a stored delegate of ONE person (its
5
- -- responsible Membership), bound to ONE workspace. It stores
6
- -- the SHA-256 digest of the agent's key, never the key.
7
- -- Deleting the organization, the workspace or the person's
8
- -- membership deletes the agent; deleting the membership of
9
- -- the person who was last shown its key sets
10
- -- key_issued_to_membership_id null, which the guard refuses
11
- -- until the agent is re-keyed. created_by_user_id is a plain
12
- -- column with no foreign key, so deleting the creator does
13
- -- not delete the agents they made for someone else.
14
- --
15
- -- PURELY ADDITIVE: one new enum, one new table, its indexes and four FKs (to
16
- -- "organizations", "workspaces" and twice to "memberships"). No statement
17
- -- touches an existing table's rows or columns, so there is no pre-assertion
18
- -- block — this migration cannot lose a row.
19
- --
20
- -- Rollback: DROP TABLE "agents"; DROP TYPE "AgentPermissionLevel". Safe while
21
- -- nothing but #3591's own code reads them.
22
-
23
- -- CreateEnum
24
- CREATE TYPE "AgentPermissionLevel" AS ENUM ('member');
25
-
26
- -- CreateTable
27
- CREATE TABLE "agents" (
28
- "id" TEXT NOT NULL DEFAULT ('agent_'::text || (uuidv7())::text),
29
- "organization_id" TEXT NOT NULL,
30
- "workspace_id" TEXT NOT NULL,
31
- "responsible_membership_id" TEXT NOT NULL,
32
- "name" VARCHAR(80) NOT NULL,
33
- "permission_level" "AgentPermissionLevel" NOT NULL DEFAULT 'member',
34
- "enabled" BOOLEAN NOT NULL DEFAULT true,
35
- "credential_hash" CHAR(64) NOT NULL,
36
- "credential_prefix" VARCHAR(24) NOT NULL,
37
- "last_active_at" TIMESTAMP(3),
38
- "created_by_user_id" TEXT NOT NULL,
39
- "key_issued_to_membership_id" TEXT,
40
- "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
41
- "updated_at" TIMESTAMP(3) NOT NULL,
42
-
43
- CONSTRAINT "agents_pkey" PRIMARY KEY ("id")
44
- );
45
-
46
- -- CreateIndex
47
- -- The lookup an agent's every request makes (`findAgentByKeyHash`).
48
- CREATE UNIQUE INDEX "agents_credential_hash_key" ON "agents"("credential_hash");
49
-
50
- -- CreateIndex
51
- CREATE INDEX "agents_organization_id_idx" ON "agents"("organization_id");
52
-
53
- -- CreateIndex
54
- CREATE INDEX "agents_workspace_id_idx" ON "agents"("workspace_id");
55
-
56
- -- CreateIndex
57
- CREATE INDEX "agents_responsible_membership_id_idx" ON "agents"("responsible_membership_id");
58
-
59
- -- AddForeignKey
60
- ALTER TABLE "agents" ADD CONSTRAINT "agents_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
61
-
62
- -- AddForeignKey
63
- ALTER TABLE "agents" ADD CONSTRAINT "agents_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE;
64
-
65
- -- AddForeignKey
66
- -- Leaving stops the agent: removing the person's membership deletes it.
67
- ALTER TABLE "agents" ADD CONSTRAINT "agents_responsible_membership_id_fkey" FOREIGN KEY ("responsible_membership_id") REFERENCES "memberships"("id") ON DELETE CASCADE ON UPDATE CASCADE;
68
-
69
- -- AddForeignKey
70
- -- A key dies with the person who received it: SET NULL, which the guard refuses.
71
- ALTER TABLE "agents" ADD CONSTRAINT "agents_key_issued_to_membership_id_fkey" FOREIGN KEY ("key_issued_to_membership_id") REFERENCES "memberships"("id") ON DELETE SET NULL ON UPDATE CASCADE;
72
-
73
- -- ADR-0031 rule 3 — agents: agent_ (registered in packages/ids/src/registry.ts;
74
- -- this migration's path is added to migration-sync.test.ts's
75
- -- PK_CHECK_MIGRATIONS). Each reference column carries the format CHECK of the
76
- -- entity it names, in the exact pattern the spoke migration uses.
77
- ALTER TABLE "agents" ALTER COLUMN "id" TYPE text COLLATE "C";
78
- ALTER TABLE "agents" ALTER COLUMN "id" SET DEFAULT ('agent_'::text || (uuidv7())::text);
79
- ALTER TABLE "agents" ADD CONSTRAINT "agents_id_format" CHECK ("id" ~ '^agent_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
80
- ALTER TABLE "agents" ADD CONSTRAINT "agents_organization_id_format" CHECK ("organization_id" ~ '^org_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
81
- ALTER TABLE "agents" ADD CONSTRAINT "agents_workspace_id_format" CHECK ("workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
82
- ALTER TABLE "agents" ADD CONSTRAINT "agents_responsible_membership_id_format" CHECK ("responsible_membership_id" ~ '^member_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
83
- ALTER TABLE "agents" ADD CONSTRAINT "agents_key_issued_to_membership_id_format" CHECK ("key_issued_to_membership_id" ~ '^member_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
84
- ALTER TABLE "agents" ADD CONSTRAINT "agents_created_by_user_id_format" CHECK ("created_by_user_id" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
@@ -1,35 +0,0 @@
1
- -- #7803 — sign-in lands in the user's last workspace (spec
2
- -- docs/specs/7803-sign-in-last-workspace-spec.md D1).
3
- --
4
- -- users.last_workspace_id (auth) — the workspace this person last activated.
5
- -- Written only by activateWorkspace after its membership
6
- -- grant; read only by listTenancy, which reports it only
7
- -- when the workspace is in the caller's own listing
8
- -- (apps/api/src/services/tenant-context.ts). Deleting the
9
- -- workspace sets it null.
10
- --
11
- -- PURELY ADDITIVE: one nullable column with no default, its index, one FK to
12
- -- "workspaces" and the ADR-0031 format CHECK on the new reference column. No
13
- -- backfill runs and no existing row changes, so there is no pre-assertion
14
- -- block — this migration cannot lose a row. A NULL passes the CHECK.
15
- --
16
- -- Rollout: deploy this migration BEFORE the API code that reads the column
17
- -- (SEC-7803-3). Being nullable, it is safe to apply ahead of the code.
18
- --
19
- -- Rollback: ALTER TABLE "users" DROP COLUMN "last_workspace_id"; (this drops
20
- -- the index, the FK and the CHECK with it). Safe while nothing but #7803's own
21
- -- code reads it.
22
-
23
- -- AlterTable
24
- ALTER TABLE "users" ADD COLUMN "last_workspace_id" TEXT;
25
-
26
- -- CreateIndex
27
- CREATE INDEX "users_last_workspace_id_idx" ON "users"("last_workspace_id");
28
-
29
- -- AddForeignKey
30
- -- A deleted workspace clears every pointer to it.
31
- ALTER TABLE "users" ADD CONSTRAINT "users_last_workspace_id_fkey" FOREIGN KEY ("last_workspace_id") REFERENCES "workspaces"("id") ON DELETE SET NULL ON UPDATE CASCADE;
32
-
33
- -- ADR-0031 rule 3 — the reference column carries the format CHECK of the
34
- -- entity it names (wksp_), in the exact pattern the agents migration uses.
35
- ALTER TABLE "users" ADD CONSTRAINT "users_last_workspace_id_format" CHECK ("last_workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
@@ -1,20 +0,0 @@
1
- -- #7869 (spoke-pattern roadmap Phase 1, D5) — Lead idempotency key: the
2
- -- caller's optional `Idempotency-Key` header on POST /v1/leads/submit, so a
3
- -- retried lead write (a client retry, a spoke's fulfilment replay) finds the
4
- -- first lead instead of writing a second. Mirrors the column-add shape of
5
- -- 20260906000000_add_flow_checkout_idempotency (one AlterTable, one unique
6
- -- index under the Prisma section headers).
7
- --
8
- -- The column is nullable with no default, so no pre-existing row needs a
9
- -- backfill and none collides on the new unique — Postgres treats NULLs as
10
- -- distinct. The unique is scoped by workspace_id: one key in two workspaces
11
- -- is two leads.
12
- --
13
- -- Rollback: ALTER TABLE "leads" DROP COLUMN "idempotency_key"; (the index
14
- -- goes with it).
15
-
16
- -- AlterTable
17
- ALTER TABLE "leads" ADD COLUMN "idempotency_key" TEXT;
18
-
19
- -- CreateIndex
20
- CREATE UNIQUE INDEX "leads_workspace_id_idempotency_key_key" ON "leads"("workspace_id", "idempotency_key");
@@ -1,33 +0,0 @@
1
- -- #7864 — grant an agent key five named abilities (spec
2
- -- docs/specs/7864-agent-key-grants-spec.md D2).
3
- --
4
- -- agents.grants (auth) — the permissions an owner or admin granted this
5
- -- agent one by one. Written only by setServedAgentGrants
6
- -- (apps/api/src/lib/agent-store.ts, the PUT
7
- -- …/agents/:agentId/grants route); read by the auth
8
- -- preHandler's key lookup and the agent list. The tenant
9
- -- guards hold an agent to the grants its person's own role
10
- -- also holds, so a stored grant never outranks the person.
11
- --
12
- -- The CHECK names the same five permissions as @working-theory/validation's
13
- -- AGENT_GRANTABLE_PERMISSIONS; database/__tests__/agents.db.test.ts reads
14
- -- this file and fails if the two lists differ (SEC-7864-G).
15
- --
16
- -- PURELY ADDITIVE: one NOT NULL column with an empty-array default and its
17
- -- CHECK. No backfill runs: every existing agent takes the default, no
18
- -- grants, and so behaves exactly as before. No existing row changes beyond
19
- -- the default fill, so there is no pre-assertion block.
20
- --
21
- -- Rollout: deploy this migration BEFORE the API code that reads the column.
22
- -- Code without the column fails closed — its key lookup errors and every
23
- -- agent is answered 401 (SEC-7864-F).
24
- --
25
- -- Rollback: ALTER TABLE "agents" DROP COLUMN "grants"; (this drops the CHECK
26
- -- with it). Safe while nothing but #7864's own code reads it.
27
-
28
- -- AlterTable
29
- ALTER TABLE "agents" ADD COLUMN "grants" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[];
30
-
31
- -- Only the five grantable permissions may be stored.
32
- ALTER TABLE "agents" ADD CONSTRAINT "agents_grants_allowed"
33
- CHECK ("grants" <@ ARRAY['content-edit','content-publish','assets-write','magnets-manage','meeting-types-manage']::TEXT[]);
@@ -1,106 +0,0 @@
1
- -- #852 — Person, the per-workspace client record (spec
2
- -- docs/specs/852-person-the-per-workspace-client-spec.md D1, D2).
3
- --
4
- -- people (inbox) — one client of one workspace, keyed on a lowercased,
5
- -- trimmed email unique per workspace. Created only by
6
- -- apps/api/src/services/person.ts's findOrCreatePerson.
7
- -- workspace_id and user_id are plain columns with no
8
- -- foreign key (ADR 0009): they name auth-namespace rows.
9
- -- leads.person_id, appointments.person_id — the Person each row belongs
10
- -- to, stamped at creation by the intake paths.
11
- --
12
- -- PURELY ADDITIVE, DDL ONLY: one new table with its indexes and CHECKs, and
13
- -- one nullable column with no default on each of "leads" and "appointments",
14
- -- so Postgres changes only the catalog for those two. No existing row's
15
- -- values change here — the backfill is the next migration,
16
- -- 20261010121000_person_backfill, split out so its row updates never run
17
- -- under the exclusive locks these ALTER TABLEs take (SEC-852-E). Prisma runs
18
- -- this file as one transaction, so each ALTER TABLE's ACCESS EXCLUSIVE lock
19
- -- is held until the file commits — through the plain CREATE INDEX on the new
20
- -- column — blocking reads AND writes of "leads" and "appointments" (lead
21
- -- capture included) for one heap scan of each. Accepted: the scan is short
22
- -- next to the backfill it is split from.
23
- --
24
- -- Rollout: deploy this migration (and the backfill) BEFORE the API code that
25
- -- writes person_id; code without the column fails every lead write.
26
- --
27
- -- Rollback: ALTER TABLE "leads" DROP COLUMN "person_id"; ALTER TABLE
28
- -- "appointments" DROP COLUMN "person_id"; DROP TABLE "people"; (the indexes
29
- -- and CHECKs go with them). Safe while nothing but #852's own code reads them.
30
-
31
- -- AlterTable
32
- ALTER TABLE "appointments" ADD COLUMN "person_id" TEXT;
33
-
34
- -- AlterTable
35
- ALTER TABLE "leads" ADD COLUMN "person_id" TEXT;
36
-
37
- -- CreateTable
38
- CREATE TABLE "people" (
39
- "id" TEXT NOT NULL DEFAULT ('person_'::text || (uuidv7())::text),
40
- "workspace_id" TEXT NOT NULL,
41
- "email" VARCHAR(254) NOT NULL,
42
- "name" VARCHAR(200),
43
- "user_id" TEXT,
44
- "billing_provider" VARCHAR(32),
45
- "billing_customer_id" VARCHAR(255),
46
- "plan_offering" VARCHAR(100),
47
- "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
48
- "updated_at" TIMESTAMP(3) NOT NULL,
49
-
50
- CONSTRAINT "people_pkey" PRIMARY KEY ("id")
51
- );
52
-
53
- -- CreateIndex
54
- -- The webhook's first match: a customer id within one workspace (D3 step 2).
55
- -- NOT unique — the spokes share one Stripe account.
56
- CREATE INDEX "people_workspace_id_billing_customer_id_idx" ON "people"("workspace_id", "billing_customer_id");
57
-
58
- -- CreateIndex
59
- -- The People list: workspace_id = $1 ORDER BY created_at DESC (D7).
60
- CREATE INDEX "people_workspace_id_created_at_idx" ON "people"("workspace_id", "created_at");
61
-
62
- -- CreateIndex
63
- -- One Person per address per workspace — what findOrCreatePerson's
64
- -- INSERT … ON CONFLICT DO NOTHING absorbs a concurrent duplicate on.
65
- CREATE UNIQUE INDEX "people_workspace_id_email_key" ON "people"("workspace_id", "email");
66
-
67
- -- CreateIndex
68
- -- One Person per User per workspace. NULLs are distinct, so any number of
69
- -- unlinked Persons fit.
70
- CREATE UNIQUE INDEX "people_workspace_id_user_id_key" ON "people"("workspace_id", "user_id");
71
-
72
- -- CreateIndex
73
- CREATE INDEX "appointments_person_id_idx" ON "appointments"("person_id");
74
-
75
- -- CreateIndex
76
- CREATE INDEX "leads_person_id_idx" ON "leads"("person_id");
77
-
78
- -- ADR-0031 rule 3 — people: person_ (registered in packages/ids/src/registry.ts;
79
- -- this migration's path is added to migration-sync.test.ts's
80
- -- PK_CHECK_MIGRATIONS). Each reference column carries the format CHECK of the
81
- -- entity it names, in the agents-migration shape.
82
- ALTER TABLE "people" ALTER COLUMN "id" TYPE text COLLATE "C";
83
- ALTER TABLE "people" ALTER COLUMN "id" SET DEFAULT ('person_'::text || (uuidv7())::text);
84
- ALTER TABLE "people" ADD CONSTRAINT "people_id_format" CHECK ("id" ~ '^person_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
85
- ALTER TABLE "people" ADD CONSTRAINT "people_workspace_id_format" CHECK ("workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
86
- ALTER TABLE "people" ADD CONSTRAINT "people_user_id_format" CHECK ("user_id" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
87
-
88
- -- The stored address is already normalized: printable ASCII only (no
89
- -- whitespace, no control or invisible character), exactly one @ with a
90
- -- non-empty side each, lower case. findOrCreatePerson's
91
- -- isStorablePersonEmail applies the same rule before any write (D3).
92
- ALTER TABLE "people" ADD CONSTRAINT "people_email_normalized"
93
- CHECK ("email" = lower("email" COLLATE "C") AND "email" ~ '^[!-?A-~]+@[!-?A-~]+$');
94
-
95
- -- A provider and its customer id are written together or not at all — the
96
- -- same provider-agnostic pair User and Organization carry.
97
- ALTER TABLE "people" ADD CONSTRAINT "people_billing_pair"
98
- CHECK (("billing_provider" IS NULL) = ("billing_customer_id" IS NULL));
99
-
100
- -- The two new reference columns carry the person_ format CHECK, added NOT
101
- -- VALID and then validated: the file runs as one transaction, so the ALTER
102
- -- TABLE's lock is still held, and the scan is of an all-NULL column.
103
- ALTER TABLE "leads" ADD CONSTRAINT "leads_person_id_format" CHECK ("person_id" ~ '^person_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$') NOT VALID;
104
- ALTER TABLE "leads" VALIDATE CONSTRAINT "leads_person_id_format";
105
- ALTER TABLE "appointments" ADD CONSTRAINT "appointments_person_id_format" CHECK ("person_id" ~ '^person_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$') NOT VALID;
106
- ALTER TABLE "appointments" VALIDATE CONSTRAINT "appointments_person_id_format";