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,339 +0,0 @@
1
- // content namespace — chat + artifact substrate (AgentSession, ConversationEvent,
2
- // SessionReadReceipt, Artifact, ArtifactVersion, Asset)
3
- //
4
- // Backs the event-sourced conversation transport + artifact persistence in
5
- // docs/research/ploy-capture/BACKEND-REQUIREMENTS.md (§1 transport R-T1..R-T7,
6
- // §2 event envelope, §3 endpoints). Workspaces own all domain content, so every
7
- // table here carries a non-null `workspaceId` tenant scope.
8
- //
9
- // Per ADR 0009 invariant 1: workspaceId / userId are plain String stable IDs —
10
- // NO @relation into the auth namespace (Workspace/User live in database/auth/).
11
- // Relations WITHIN this namespace (event → session, version → artifact) are
12
- // real FKs. Cross-namespace assembly (e.g. tenant guard resolving a session's
13
- // workspace) routes through apps/api/src/services/ (invariant 4).
14
- //
15
- // Generator + datasource blocks live in database/schema.prisma (the root schema
16
- // file). This file holds only model definitions for the content namespace.
17
-
18
- /// AgentSession — one agent conversation ("session"/captured "ploy") within a
19
- /// workspace. lastSeq is the append watermark for the event log (R-T1).
20
- model AgentSession {
21
- id String @id @default(dbgenerated("('agsess_'::text || (uuidv7())::text)")) @db.Text
22
- workspaceId String @map("workspace_id")
23
- title String?
24
- status String @default("idle")
25
- lastSeq Int @default(0) @map("last_seq")
26
- lastMessageAt DateTime? @map("last_message_at")
27
- draftMessage String? @map("draft_message")
28
- createdAt DateTime @default(now()) @map("created_at")
29
- updatedAt DateTime @updatedAt @map("updated_at")
30
-
31
- events ConversationEvent[]
32
- artifacts Artifact[]
33
- readReceipts SessionReadReceipt[]
34
-
35
- @@index([workspaceId, lastMessageAt(sort: Desc)])
36
- @@map("agent_sessions")
37
- }
38
-
39
- /// ConversationEvent — append-only, seq-ordered event log entry (R-T1/R-T4).
40
- /// Envelope: { agentId, seq, type, turnId, payload, createdAt } (§2).
41
- /// workspaceId is denormalized so the scope layer filters events without a
42
- /// join through agent_sessions.
43
- model ConversationEvent {
44
- id String @id @default(dbgenerated("('convev_'::text || (uuidv7())::text)")) @db.Text
45
- sessionId String @map("session_id")
46
- workspaceId String @map("workspace_id")
47
- agentId String @map("agent_id")
48
- seq Int
49
- type String
50
- turnId String? @map("turn_id")
51
- payload Json
52
- createdAt DateTime @default(now()) @map("created_at")
53
-
54
- session AgentSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
55
-
56
- @@unique([sessionId, seq])
57
- @@index([workspaceId])
58
- @@map("conversation_events")
59
- }
60
-
61
- /// SessionReadReceipt — per-user read position for a session (R-T7 mark-read;
62
- /// drives unread badges). userId is a stable auth-namespace ID — no FK.
63
- model SessionReadReceipt {
64
- id String @id @default(dbgenerated("('receipt_'::text || (uuidv7())::text)")) @db.Text
65
- sessionId String @map("session_id")
66
- workspaceId String @map("workspace_id")
67
- userId String @map("user_id")
68
- lastReadSeq Int @default(0) @map("last_read_seq")
69
- updatedAt DateTime @updatedAt @map("updated_at")
70
-
71
- session AgentSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
72
-
73
- @@unique([sessionId, userId])
74
- @@index([workspaceId])
75
- @@map("session_read_receipts")
76
- }
77
-
78
- /// Artifact — a piece of the WORKSPACE's versioned content (#3846, generalized
79
- /// by #5800 / roadmap D1). Originally "a session's produced output"; a session
80
- /// is now PROVENANCE, not ownership — `sessionId` is optional and `SetNull`, so
81
- /// deleting the conversation that produced a page leaves the page standing.
82
- ///
83
- /// `contentType` is the discriminator the content store reads: `text/page` is
84
- /// what the editor writes, `text/document` the legacy chat artifact. A page's
85
- /// public identity is `(workspaceId, contentType, locale, slug)`; `slug` stays
86
- /// NULL until publish, and NULLs never collide in a Postgres unique index, so a
87
- /// workspace may hold any number of unpublished drafts.
88
- ///
89
- /// `publishedVersionId` is a plain pointer at the ArtifactVersion the public
90
- /// read serves — deliberately NOT a relation (a FK back into `versions` would
91
- /// make the delete order of an artifact's own history circular), and
92
- /// deliberately NOT `ArtifactVersion.isCurrent`, which is the DRAFT TIP and is
93
- /// never the publish mechanism. Saving a draft moves `isCurrent`; only publish
94
- /// moves this pointer.
95
- ///
96
- /// `type` is the LEGACY discriminator. It predates `contentType` and is still
97
- /// read by apps/api/src/routes/workspaces/sessions.ts (the session-artifacts
98
- /// route, a hard-floor surface), so #5800 added `contentType` beside it and
99
- /// backfilled it from `type` rather than renaming the column out from under a
100
- /// live consumer. New code reads `contentType`; retiring `type` belongs to the
101
- /// card that moves that route.
102
- model Artifact {
103
- id String @id @default(dbgenerated("('artif_'::text || (uuidv7())::text)")) @db.Text
104
- sessionId String? @map("session_id")
105
- workspaceId String @map("workspace_id")
106
- type String @default("text/document")
107
- contentType String @default("text/document") @map("content_type")
108
- locale String @default("en")
109
- slug String?
110
- title String
111
- publishedVersionId String? @map("published_version_id")
112
- createdAt DateTime @default(now()) @map("created_at")
113
- updatedAt DateTime @updatedAt @map("updated_at")
114
-
115
- session AgentSession? @relation(fields: [sessionId], references: [id], onDelete: SetNull)
116
- versions ArtifactVersion[]
117
-
118
- @@unique([workspaceId, contentType, locale, slug])
119
- @@index([sessionId])
120
- @@index([workspaceId])
121
- @@index([workspaceId, contentType, updatedAt])
122
- @@map("artifacts")
123
- }
124
-
125
- /// ArtifactVersion — auto-saved version history; exactly one isCurrent per
126
- /// artifact (enforced at the service layer on save/restore).
127
- model ArtifactVersion {
128
- id String @id @default(dbgenerated("('artiv_'::text || (uuidv7())::text)")) @db.Text
129
- artifactId String @map("artifact_id")
130
- workspaceId String @map("workspace_id")
131
- content Json
132
- isCurrent Boolean @default(true) @map("is_current")
133
- savedAt DateTime @default(now()) @map("saved_at")
134
-
135
- artifact Artifact @relation(fields: [artifactId], references: [id], onDelete: Cascade)
136
-
137
- @@index([artifactId, savedAt(sort: Desc)])
138
- @@index([workspaceId])
139
- @@map("artifact_versions")
140
- }
141
-
142
- /// Asset — a workspace's uploaded binary (#5800 / roadmap D7), following the
143
- /// `DeliverableAsset` precedent in the inbox namespace: the bytes live in the
144
- /// row, not in object storage. That precedent was deliberate — no new
145
- /// infrastructure — and only the resolver changes if blob storage arrives later.
146
- ///
147
- /// `workspaceId` is a plain String stable id with no @relation (ADR 0009
148
- /// invariant 1), and `(workspaceId, key)` is the addressable identity. Ids are
149
- /// UUIDv7 (ADR 0031), so a re-upload is a NEW id and a served asset can be
150
- /// cached immutably. The upload route itself is #5802's scope, not this model's.
151
- ///
152
- /// Since #6310: this is also the store a magnet's `deliverables.assets[].assetKey`
153
- /// resolves against FIRST (by `(workspaceId, key)`), ahead of the legacy
154
- /// `DeliverableAsset` fallback (database/inbox/schema.prisma) — read through
155
- /// the scoped boundary in apps/api/src/lib/deliverable-asset-store.ts, never
156
- /// a raw query.
157
- model Asset {
158
- id String @id @default(dbgenerated("('asset_'::text || (uuidv7())::text)")) @db.Text
159
- workspaceId String @map("workspace_id")
160
- /// The caller-chosen name an artifact's content references the asset by.
161
- key String
162
- /// Download filename (Content-Disposition). Stored RAW; sanitize at SERVE
163
- /// time, exactly as the DeliverableAsset download route does.
164
- filename String
165
- contentType String @map("content_type")
166
- bytes Bytes
167
- size Int
168
- /// Owner-authored display name, shown above the filename in the lightbox
169
- /// (#6092, S4/D10). NULL means the owner has not written one — distinct from
170
- /// an empty string, which means they cleared it. Never backfilled from
171
- /// `filename`: the two are different facts (demo.html:782 renders both).
172
- title String?
173
- /// Owner-authored longer description. Same NULL-vs-empty contract as `title`.
174
- description String?
175
- /// Owner-controlled tag SLUGS (`ad-creative`, `workspace-memory`, …), never
176
- /// the human labels — the label is presentation, resolved by the surface from
177
- /// its own vocabulary (demo.html:358 `ATAGS`, :794 the Docs set). Free-form
178
- /// by design: the asset vocabulary and the document vocabulary (D8/D9) ride
179
- /// this one column, and the "fixed set" of D10 is a UI affordance, not a
180
- /// database constraint (#6092, D2 of the spec).
181
- tags String[] @default([])
182
- createdAt DateTime @default(now()) @map("created_at")
183
-
184
- @@unique([workspaceId, key])
185
- @@index([workspaceId])
186
- @@map("assets")
187
- }
188
-
189
- // ============================================================================
190
- // Usage-billing metering (FEAT-047 P1.S1, #3709 — Epic #3704)
191
- //
192
- // The metering event + its org-level aggregates. Per ADR 0009 D2 (roadmap §4),
193
- // the metering event + UsagePeriod + UsageBillingReport live in `content`;
194
- // balances/plans (S2) live in auth/config. organizationId/workspaceId/userId
195
- // are plain String stable-ids — no @relation into auth (ADR 0009 invariant 1).
196
- // Field roster ported from docs/research/wt-billing-capture/schema.md, modeled
197
- // on WT's TraceLog billing columns (spec D1), with workspaceId/userId added to
198
- // the event grain (spec D2). Cross-namespace assembly (e.g. resolving an
199
- // event's owning Workspace) routes through apps/api/src/services/.
200
- // ============================================================================
201
-
202
- /// ModelTier — the pricing tier at event time. BASE is unlimited/free-ish;
203
- /// PREMIUM/FRONTIER consume credits. Defined here (S1, the dependency root)
204
- /// per spec OQ-1 — S2's LlmModel references the same enum through the merged
205
- /// prismaSchemaFolder (one logical schema; an enum reference needs no
206
- /// @relation, so this is not a cross-namespace FK).
207
- enum ModelTier {
208
- BASE
209
- PREMIUM
210
- FRONTIER
211
- }
212
-
213
- /// UsageBillingStatus — UsageBillingReport lifecycle: PENDING → REPORTED →
214
- /// INVOICED → PAID, or FAILED.
215
- enum UsageBillingStatus {
216
- PENDING
217
- REPORTED
218
- INVOICED
219
- PAID
220
- FAILED
221
- }
222
-
223
- /// UsageEvent — one row per billable AI call (the metering event; modeled on
224
- /// WT's TraceLog billing columns, spec D1). org+workspace+user grain (spec
225
- /// D2); all three scope ids are plain String stable-ids — no cross-namespace
226
- /// @relation (ADR 0009 invariant 1, spec D3). The three attribution portion
227
- /// columns are the load-bearing billing split; only onDemandPortionCents is
228
- /// ever reported to Stripe (P4, spec D4). completionStatus 'success' rows
229
- /// drive billing — aggregation (P2) filters on it.
230
- model UsageEvent {
231
- id String @id @default(dbgenerated("('usagev_'::text || (uuidv7())::text)")) @db.Text
232
- organizationId String @map("organization_id")
233
- workspaceId String @map("workspace_id")
234
- userId String @map("user_id")
235
-
236
- provider String
237
- model String
238
-
239
- // Cache-aware token breakdown.
240
- inputTokensCacheWrite Int @map("input_tokens_cache_write")
241
- inputTokensNoCacheWrite Int @map("input_tokens_no_cache_write")
242
- cacheReadTokens Int @map("cache_read_tokens")
243
- outputTokens Int @map("output_tokens")
244
- thinkingTokens Int @map("thinking_tokens")
245
- totalTokens Int @map("total_tokens")
246
-
247
- providerCostUsd Decimal @map("provider_cost_usd") @db.Decimal(10, 6)
248
- billedCostUsd Decimal @map("billed_cost_usd") @db.Decimal(10, 6)
249
- markupPercent Decimal @map("markup_percent") @db.Decimal(5, 2)
250
-
251
- modelTier ModelTier @default(BASE) @map("model_tier")
252
- wasAutoModel Boolean @map("was_auto_model")
253
-
254
- // Attribution split — billedCostUsd apportioned across the three buckets;
255
- // only onDemandPortionCents is ever Stripe-metered (P4, spec D4).
256
- includedPortionCents Int @default(0) @map("included_portion_cents")
257
- creditBalancePortionCents Int @default(0) @map("credit_balance_portion_cents")
258
- onDemandPortionCents Int @default(0) @map("on_demand_portion_cents")
259
-
260
- completionStatus String @map("completion_status")
261
- createdAt DateTime @default(now()) @map("created_at")
262
-
263
- @@index([organizationId, createdAt])
264
- @@index([workspaceId, createdAt])
265
- @@index([userId, createdAt])
266
- @@index([provider, model])
267
- @@index([modelTier, wasAutoModel])
268
- @@map("usage_events")
269
- }
270
-
271
- /// UsagePeriod — one row per (organizationId, periodStart); the org-scoped
272
- /// spend/tier rollup the P2 write path upserts as UsageEvent rows land.
273
- /// Carries the event-grain roll-up support for the Org → Workspace → User
274
- /// aggregation (spec D2) — whether this model itself gains per-workspace
275
- /// sub-rows is a P2 decision, not a P1 schema requirement (spec OQ-2).
276
- model UsagePeriod {
277
- id String @id @default(dbgenerated("('usagper_'::text || (uuidv7())::text)")) @db.Text
278
- organizationId String @map("organization_id")
279
-
280
- periodStart DateTime @map("period_start")
281
- periodEnd DateTime @map("period_end")
282
-
283
- tokensConsumed BigInt @default(0) @map("tokens_consumed")
284
- baseTokensConsumed BigInt @default(0) @map("base_tokens_consumed")
285
- premiumTokensConsumed BigInt @default(0) @map("premium_tokens_consumed")
286
- frontierTokensConsumed BigInt @default(0) @map("frontier_tokens_consumed")
287
-
288
- usageSpendCents Int @default(0) @map("usage_spend_cents")
289
-
290
- @@unique([organizationId, periodStart])
291
- @@index([baseTokensConsumed, premiumTokensConsumed, frontierTokensConsumed], map: "usage_periods_tier_tracking_idx")
292
- @@map("usage_periods")
293
- }
294
-
295
- /// UsageBillingReport — one per (organizationId, periodStart, periodEnd); the
296
- /// Stripe-reporting unit rolled up from UsageEvent by P2 aggregation. Only
297
- /// onDemandCents is ever reported to Stripe (P4, spec D4) — includedCents/
298
- /// creditBalanceCents are informational attribution, never metered.
299
- model UsageBillingReport {
300
- id String @id @default(dbgenerated("('usagrept_'::text || (uuidv7())::text)")) @db.Text
301
- organizationId String @map("organization_id")
302
-
303
- periodStart DateTime @map("period_start")
304
- periodEnd DateTime @map("period_end")
305
-
306
- // AGGREGATE precision (#3738 H2) — these hold a MONTH of events, not one
307
- // event, so they must NOT reuse UsageEvent's per-event widths. At the
308
- // original Decimal(10,6)/Int, an org whose month crossed $9,999.999999 (or
309
- // 2.15B tokens) overflowed the column, the upsert threw, and the report was
310
- // never written on ANY subsequent run — silently stalling revenue for the
311
- // largest customers, worsening monotonically. Decimal(20,6) ≈ $1e14 and int8
312
- // give headroom far above the service's own MAX_TOTAL_USD / token caps, so
313
- // the service's loud `aggregate_overflow` assertion is always the gate and a
314
- // silent DB overflow is unreachable. See usage-aggregation.ts § Bounds.
315
- totalProviderCost Decimal @map("total_provider_cost") @db.Decimal(20, 6)
316
- totalMarkupAmount Decimal @map("total_markup_amount") @db.Decimal(20, 6)
317
- totalBilledAmount Decimal @map("total_billed_amount") @db.Decimal(20, 6)
318
-
319
- totalTokens BigInt @map("total_tokens")
320
- eventCount Int @map("event_count")
321
-
322
- // Attribution split — only onDemandCents is ever Stripe-metered (P4, spec D4).
323
- includedCents Int @default(0) @map("included_cents")
324
- creditBalanceCents Int @default(0) @map("credit_balance_cents")
325
- onDemandCents Int @default(0) @map("on_demand_cents")
326
-
327
- stripeUsageRecordId String? @map("stripe_usage_record_id")
328
- reportedToStripeAt DateTime? @map("reported_to_stripe_at")
329
- stripeInvoiceId String? @map("stripe_invoice_id")
330
-
331
- status UsageBillingStatus @default(PENDING)
332
- errorMessage String? @map("error_message")
333
-
334
- @@unique([organizationId, periodStart, periodEnd], map: "usage_billing_reports_period_key")
335
- @@index([organizationId, status])
336
- @@index([status])
337
- @@index([periodStart])
338
- @@map("usage_billing_reports")
339
- }
@@ -1,69 +0,0 @@
1
- // Self-contained ESLint flat config for this scaffolded package.
2
- //
3
- // It deliberately does NOT depend on @working-theory/eslint-config — that
4
- // package is internal to the AI Launch Kit monorepo and is not published, so
5
- // it cannot be a dependency of a scaffolded starter. Everything below comes
6
- // from public npm packages already pinned as devDependencies (see
7
- // package.json): @eslint/js, globals and typescript-eslint.
8
- //
9
- // Source file name (#5556): this file is checked in as `_eslint.config.mjs`,
10
- // not `eslint.config.mjs` — build-templates.mjs renames it at snapshot time
11
- // (renameScaffoldLintConfigs()). A file literally named `eslint.config.mjs`
12
- // anywhere under this monorepo (even one this repo's own root eslint.config.ts
13
- // lists in its `ignores`) is auto-discovered by ESLint's flat-config nested
14
- // resolution as a competing config root, which breaks the monorepo's own
15
- // lint runs (verified live: typescript-eslint's "multiple candidate
16
- // TSConfigRootDirs" parser error across unrelated packages/create-ailk
17
- // files). The underscore prefix keeps it invisible to that discovery while
18
- // it lives in this checkout; only the snapshot in templates/ — which ships
19
- // to the customer, not this repo — gets the real filename.
20
- import js from "@eslint/js";
21
- import globals from "globals";
22
- import tseslint from "typescript-eslint";
23
-
24
- export default tseslint.config(
25
- {
26
- ignores: [
27
- "**/.next/**",
28
- "**/dist/**",
29
- "**/generated/**",
30
- "**/node_modules/**",
31
- ],
32
- },
33
- js.configs.recommended,
34
- ...tseslint.configs.recommended,
35
- {
36
- languageOptions: {
37
- globals: {
38
- ...globals.node,
39
- ...globals.browser,
40
- ...globals.jest,
41
- },
42
- // Explicit, self-contained root — this scaffold config is never meant
43
- // to combine with any sibling scaffold package's config (each ships
44
- // standalone), and leaving it unset makes typescript-eslint's
45
- // candidate-root disambiguation ambiguous the moment more than one
46
- // scaffold package's config resolves in the same ESLint process (e.g.
47
- // this monorepo's own `templates/` build, where all four exist
48
- // side by side; a real customer scaffold never has that problem,
49
- // since it only ever ships and lints ONE of these four at a time).
50
- parserOptions: {
51
- tsconfigRootDir: import.meta.dirname,
52
- },
53
- },
54
- rules: {
55
- // Downgraded rather than off, so both stay visible without failing a
56
- // fresh scaffold's lint:
57
- // - unused-vars: most of the source follows the underscore-prefix
58
- // convention for intentionally-unused bindings, which this rule's
59
- // default options don't recognize; a handful of test fixtures also
60
- // carry genuinely-unused locals this minimal config doesn't try to
61
- // triage file-by-file.
62
- // - require-imports: CommonJS require() is the correct form in Jest
63
- // config/mock files and in a few test-only dynamic re-require
64
- // patterns.
65
- "@typescript-eslint/no-unused-vars": "warn",
66
- "@typescript-eslint/no-require-imports": "warn",
67
- },
68
- },
69
- );
@@ -1,182 +0,0 @@
1
- /**
2
- * @file listing-diagnostic.ts
3
- * @description The ONE scoring RULE every project-listing diagnostic shares
4
- * (#5001, reworked by #5036 D4) — the template's Q3–Q6 resolved by option
5
- * VALUE, never by option position.
6
- *
7
- * The mechanism (#5036 D4, "scoring by value, not position"): the generated
8
- * flow emits each scored option under the FOUNDER'S OWN `option.value`, and
9
- * the register's `optionWeights` map is keyed on those same values. Q3/Q4 are
10
- * founder-authored, so their weights map is built PER LISTING from that
11
- * listing's own options — the WEIGHT still comes from the founder's declared
12
- * order via `listingOptionPoints(index, arity)`, but it is stored against the
13
- * value rather than an index. Q5/Q6 carry fixed values
14
- * (`projectListingQuestionsSchema`, #4998), so their weights are declared once
15
- * here, shared by every listing.
16
- *
17
- * What that buys, and why the old `q{n}:{i}of{k}` encoding had to go: meaning
18
- * now travels with the value. A register may reorder or insert options and an
19
- * already-stored answer keeps scoring what it always meant, so the subset a
20
- * surface renders no longer has to be a prefix of the register's list — which
21
- * is what unblocks the shared team-composition value set (#5036 D3). It also
22
- * dissolves the "shared register needs a shared value universe" problem
23
- * (docs/lessons/2026-09-07-…): the generated experiment's `questionSet` now
24
- * declares the listing's OWN options, so
25
- * `waitlistExperimentConfigSchema`'s "every weights key must be a declared
26
- * option" cross-validation is satisfied by construction rather than by
27
- * declaring a finite universe of positional tokens.
28
- *
29
- * What is shared is therefore the RULE and the shape — same point names, same
30
- * `total` sum, same tier floors, same 0–12 range — not a single frozen
31
- * constant. Two listings' registers differ only in the Q3/Q4 KEYS, which are
32
- * the founders' own option values.
33
- *
34
- * Q5 runs STRONGEST-FIRST, deliberately. `projectListingQuestionsSchema` pins
35
- * Q5's values as `urgent | planning | exploring`, which is urgency descending,
36
- * while the positional rule scores index 0 lowest — so the old positional
37
- * encoding scored `urgent` 0 and `exploring` 3, backwards, a standing defect
38
- * recorded in docs/lessons/2026-09-07-q5-fixed-order-is-strongest-first.md.
39
- * Scoring by value is exactly the mechanism that resolves it: the weights
40
- * below name `urgent` 3 and `exploring` 0 explicitly, with no reordering of
41
- * the founder's rendered options and no per-question special case hidden
42
- * inside a positional formula. That lesson's open question is closed here.
43
- * Q6 (`low → critical`) is genuinely weakest-first and keeps 0 → 3.
44
- *
45
- * Q1 (contact), Q2 (segment), Q7 (free text) and the extras carry no points —
46
- * they are absent from `points` entirely, so they contribute 0 by
47
- * construction rather than by a zero weight that could drift.
48
- *
49
- * This module is data + the pure functions that generate it — it imports only
50
- * TYPES from `@working-theory/validation` and introduces no dependency from
51
- * `database/` toward `apps/*` (architecture.yaml's import boundary), exactly
52
- * like `presets.ts` beside it. The rule lives here and only here; the
53
- * projection (`apps/api/src/services/project-listing-flow.ts`) calls
54
- * `buildListingDiagnosticScoring` rather than re-deriving weights, so the
55
- * register and the flow can never disagree about what an answer is worth.
56
- */
57
-
58
- import type {
59
- ProjectListingQuestions,
60
- WaitlistScoring,
61
- } from "@working-theory/validation";
62
-
63
- /** The four scored template questions, in template order. */
64
- export const LISTING_DIAGNOSTIC_SCORED_QUESTIONS = ["q3", "q4", "q5", "q6"] as const;
65
- export type ListingDiagnosticScoredQuestion =
66
- (typeof LISTING_DIAGNOSTIC_SCORED_QUESTIONS)[number];
67
-
68
- /** The highest score any one question can contribute. */
69
- export const LISTING_DIAGNOSTIC_MAX_QUESTION_POINTS = 3;
70
-
71
- /**
72
- * The weight of option `index` (zero-based) of `arity` options —
73
- * `round(3·i/(k−1))`, so the founder's first option always scores 0 and their
74
- * last always scores 3, whatever the arity. This is still how a
75
- * founder-authored question's weights are DERIVED (the founder orders their
76
- * options weakest→strongest); what changed in #5036 D4 is where the result is
77
- * STORED — against the option's value, not its index.
78
- *
79
- * A single-option question (`arity <= 1`) has no spread to score and yields 0;
80
- * the template never produces one, and this guard exists so the expression can
81
- * never divide by zero.
82
- */
83
- export function listingOptionPoints(index: number, arity: number): number {
84
- if (arity <= 1) return 0;
85
- return Math.round((LISTING_DIAGNOSTIC_MAX_QUESTION_POINTS * index) / (arity - 1));
86
- }
87
-
88
- /**
89
- * `optionWeights` for one founder-authored question (Q3/Q4), keyed by the
90
- * founder's own option values and weighted by their declared order.
91
- */
92
- export function listingDiagnosticOptionWeights(
93
- options: readonly { value: string }[],
94
- ): Record<string, number> {
95
- const weights: Record<string, number> = {};
96
- options.forEach((option, index) => {
97
- weights[option.value] = listingOptionPoints(index, options.length);
98
- });
99
- return weights;
100
- }
101
-
102
- /**
103
- * Q5's fixed urgency weights — STRONGEST FIRST, against the positional rule
104
- * and deliberately so (see the file header). `urgent` is the strongest buying
105
- * signal the question can carry and scores 3; `exploring` is the weakest and
106
- * scores 0. The three weights are the same multiset a 3-option positional
107
- * question produces (`{0, 2, 3}`), so the 0–12 total range is unchanged.
108
- */
109
- export const LISTING_DIAGNOSTIC_Q5_WEIGHTS: Readonly<Record<string, number>> = {
110
- urgent: 3,
111
- planning: 2,
112
- exploring: 0,
113
- };
114
-
115
- /**
116
- * Q6's fixed band weights — weakest first, matching the schema's own
117
- * `low → critical` low→high ordering, so these are exactly what the positional
118
- * rule produced for a 4-option question.
119
- */
120
- export const LISTING_DIAGNOSTIC_Q6_WEIGHTS: Readonly<Record<string, number>> = {
121
- low: 0,
122
- medium: 1,
123
- high: 2,
124
- critical: 3,
125
- };
126
-
127
- /** The four tier keys, strongest first — the order `tiers` is evaluated in. */
128
- export const LISTING_DIAGNOSTIC_TIERS = ["now", "soon", "later", "curious"] as const;
129
-
130
- /**
131
- * The inclusive lower bound of each tier over the 0–12 total (4 questions ×
132
- * 3 points): `now` 10–12, `soon` 7–9, `later` 4–6, `curious` 0–3. Ordered
133
- * strongest-first because `evaluateWaitlistScoring` takes the FIRST matching
134
- * tier, so a `gte` ladder read top-down is total and unambiguous.
135
- */
136
- const TIER_FLOORS: Readonly<Record<(typeof LISTING_DIAGNOSTIC_TIERS)[number], number>> = {
137
- now: 10,
138
- soon: 7,
139
- later: 4,
140
- curious: 0,
141
- };
142
-
143
- /**
144
- * Build one listing's register from its own `questions` block. Embedded
145
- * verbatim into that listing's generated `WaitlistExperiment.config` —
146
- * `waitlistExperimentConfigSchema` carries the scoring block by value and
147
- * offers no by-reference slot.
148
- *
149
- * Every listing gets the same point names, the same `total` sum, the same
150
- * tier ladder and the same 0–12 range; only the Q3/Q4 weight KEYS differ,
151
- * because those keys are the founder's own option values (#5036 D4).
152
- */
153
- export function buildListingDiagnosticScoring(
154
- questions: ProjectListingQuestions,
155
- ): WaitlistScoring {
156
- const weights: Record<ListingDiagnosticScoredQuestion, Record<string, number>> = {
157
- q3: listingDiagnosticOptionWeights(questions.q3.options),
158
- q4: listingDiagnosticOptionWeights(questions.q4.options),
159
- q5: { ...LISTING_DIAGNOSTIC_Q5_WEIGHTS },
160
- q6: { ...LISTING_DIAGNOSTIC_Q6_WEIGHTS },
161
- };
162
-
163
- return {
164
- version: 1,
165
- points: LISTING_DIAGNOSTIC_SCORED_QUESTIONS.map((question) => ({
166
- name: `${question}_points`,
167
- question,
168
- kind: "optionWeights" as const,
169
- weights: weights[question],
170
- })),
171
- scores: {
172
- total: {
173
- sum: LISTING_DIAGNOSTIC_SCORED_QUESTIONS.map((q) => `${q}_points`),
174
- },
175
- },
176
- tiers: LISTING_DIAGNOSTIC_TIERS.map((key) => ({
177
- key,
178
- when: { score: "total", gte: TIER_FLOORS[key] },
179
- })),
180
- default: "curious",
181
- };
182
- }