@aotter/mantle 0.2.0-alpha.6 → 0.2.0-alpha.8

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 (946) hide show
  1. package/README.md +157 -45
  2. package/dist/auth/adapter.d.ts +32 -0
  3. package/dist/auth/adapter.js +285 -0
  4. package/dist/auth/admin.d.ts +3 -0
  5. package/dist/auth/admin.js +21 -0
  6. package/dist/auth/caller.d.ts +86 -0
  7. package/dist/auth/caller.js +155 -0
  8. package/dist/auth/hardening.d.ts +24 -0
  9. package/dist/auth/hardening.js +40 -0
  10. package/dist/auth/identity.d.ts +121 -0
  11. package/dist/auth/identity.js +203 -0
  12. package/dist/auth/oauth.d.ts +63 -0
  13. package/dist/auth/oauth.js +217 -0
  14. package/dist/auth/resource-seeds.js +10 -0
  15. package/dist/auth/routes.d.ts +32 -0
  16. package/dist/auth/routes.js +225 -0
  17. package/dist/build/compiler.d.ts +712 -0
  18. package/dist/build/compiler.js +6896 -0
  19. package/dist/{spec → build/spec}/domain/model/ManifestGrammar.d.ts +30 -47
  20. package/dist/{spec → build/spec}/domain/model/RuntimePlan.d.ts +77 -3
  21. package/dist/{spec → build/spec}/domain/model/SqlIr.d.ts +37 -6
  22. package/dist/build/spec/domain/model/UserFields.d.ts +20 -0
  23. package/dist/{spec → build/spec}/domain/service/PlanFingerprint.d.ts +4 -1
  24. package/dist/{spec → build/spec}/kernel/diagnostic.d.ts +1 -30
  25. package/dist/bun/assets.d.ts +2 -0
  26. package/dist/bun/assets.js +24 -0
  27. package/dist/domain/adminOrder.js +24 -0
  28. package/dist/domain/columns.js +55 -0
  29. package/dist/domain/describe/chunk-ZVXBGP7Y.js +424 -0
  30. package/dist/domain/describe/index.d.ts +58 -0
  31. package/dist/domain/describe/index.js +115 -0
  32. package/dist/domain/describe/target-hash.d.ts +8 -0
  33. package/dist/domain/describe/target-hash.js +12 -0
  34. package/dist/domain/describe/targets.d.ts +40 -0
  35. package/dist/domain/entry.js +33 -0
  36. package/dist/domain/generated-tools.js +19 -0
  37. package/dist/domain/generation.d.ts +16 -0
  38. package/dist/domain/generation.js +1 -0
  39. package/dist/domain/input.js +17 -0
  40. package/dist/domain/model.js +1 -0
  41. package/dist/domain/paging.js +230 -0
  42. package/dist/domain/recipes.js +19 -0
  43. package/dist/domain/userReferences.js +5 -0
  44. package/dist/domain/wireScalars.js +47 -0
  45. package/dist/infrastructure/adminEntries.js +153 -0
  46. package/dist/infrastructure/adminPaging.js +72 -0
  47. package/dist/infrastructure/artifacts.js +71 -0
  48. package/dist/infrastructure/authSchema.js +83 -0
  49. package/dist/infrastructure/bundle.js +174 -0
  50. package/dist/infrastructure/cli.js +97 -0
  51. package/dist/infrastructure/generate.d.ts +12 -0
  52. package/dist/infrastructure/generate.js +174 -0
  53. package/dist/infrastructure/generateAuth.d.ts +8 -0
  54. package/dist/infrastructure/generateAuth.js +23 -0
  55. package/dist/infrastructure/inputs.js +41 -0
  56. package/dist/infrastructure/wrangler.js +94 -0
  57. package/dist/kernel/authorization.d.ts +4 -0
  58. package/dist/kernel/authorization.js +16 -0
  59. package/dist/kernel/binds.d.ts +51 -0
  60. package/dist/kernel/binds.js +45 -0
  61. package/dist/kernel/caller-identity.d.ts +24 -0
  62. package/dist/kernel/caller-identity.js +22 -0
  63. package/dist/kernel/contract-error.d.ts +12 -0
  64. package/dist/kernel/contract-error.js +14 -0
  65. package/dist/kernel/contracts.d.ts +139 -0
  66. package/dist/kernel/contracts.js +92 -0
  67. package/dist/{spec/domain/service/CloudflareCron.d.ts → kernel/cron.d.ts} +0 -1
  68. package/dist/{spec/domain/service/CloudflareCron.js → kernel/cron.js} +1 -6
  69. package/dist/kernel/dialect/common.d.ts +39 -0
  70. package/dist/kernel/dialect/common.js +6 -0
  71. package/dist/kernel/dialect/postgres.d.ts +16 -0
  72. package/dist/kernel/dialect/postgres.js +18 -0
  73. package/dist/kernel/dialect/sqlite.d.ts +20 -0
  74. package/dist/kernel/dialect/sqlite.js +34 -0
  75. package/dist/kernel/drain.d.ts +5 -0
  76. package/dist/kernel/drain.js +35 -0
  77. package/dist/kernel/driver/bun-sqlite.d.ts +19 -0
  78. package/dist/kernel/driver/bun-sqlite.js +77 -0
  79. package/dist/kernel/driver/d1.d.ts +24 -0
  80. package/dist/kernel/driver/d1.js +22 -0
  81. package/dist/kernel/driver/postgres.d.ts +25 -0
  82. package/dist/kernel/driver/postgres.js +98 -0
  83. package/dist/kernel/driver/transaction-context.d.ts +10 -0
  84. package/dist/kernel/driver/transaction-context.js +29 -0
  85. package/dist/kernel/email.d.ts +28 -0
  86. package/dist/{auth/emailTemplates.js → kernel/email.js} +13 -2
  87. package/dist/kernel/host-access.d.ts +10 -0
  88. package/dist/kernel/host-access.js +65 -0
  89. package/dist/kernel/host-caller.d.ts +39 -0
  90. package/dist/kernel/host-caller.js +56 -0
  91. package/dist/kernel/json-body.d.ts +4 -0
  92. package/dist/kernel/json-body.js +44 -0
  93. package/dist/kernel/mcp-apps.d.ts +69 -0
  94. package/dist/kernel/mcp-apps.js +40 -0
  95. package/dist/kernel/mcp-call.d.ts +5 -0
  96. package/dist/kernel/mcp-call.js +25 -0
  97. package/dist/kernel/mcp-handler.js +371 -0
  98. package/dist/kernel/mcp.d.ts +106 -0
  99. package/dist/kernel/mcp.js +49 -0
  100. package/dist/kernel/media.d.ts +27 -0
  101. package/dist/kernel/media.js +216 -0
  102. package/dist/kernel/paging.d.ts +55 -0
  103. package/dist/kernel/paging.js +95 -0
  104. package/dist/kernel/publishing.d.ts +4 -0
  105. package/dist/kernel/publishing.js +16 -0
  106. package/dist/{cloudflare/r2Media.d.ts → kernel/r2-media.d.ts} +4 -5
  107. package/dist/kernel/r2-media.js +78 -0
  108. package/dist/kernel/rest-dispatch.js +38 -0
  109. package/dist/kernel/rest-router.js +64 -0
  110. package/dist/kernel/rest.d.ts +58 -0
  111. package/dist/kernel/rest.js +41 -0
  112. package/dist/kernel/scalars.d.ts +6 -0
  113. package/dist/kernel/scalars.js +43 -0
  114. package/dist/kernel/search.js +5 -0
  115. package/dist/{core/site.d.ts → kernel/site-types.d.ts} +38 -9
  116. package/dist/kernel/site-types.js +1 -0
  117. package/dist/kernel/site.d.ts +39 -0
  118. package/dist/kernel/site.js +32 -0
  119. package/dist/kernel/store.d.ts +165 -0
  120. package/dist/kernel/store.js +257 -0
  121. package/dist/kernel/surface.d.ts +10 -0
  122. package/dist/kernel/surface.js +19 -0
  123. package/dist/kernel/sweep.d.ts +17 -0
  124. package/dist/kernel/sweep.js +27 -0
  125. package/dist/kernel/translations.d.ts +1 -0
  126. package/dist/kernel/translations.js +13 -0
  127. package/dist/kernel/user-caller.d.ts +31 -0
  128. package/dist/kernel/user-caller.js +67 -0
  129. package/dist/kernel/user-field-name.js +3 -0
  130. package/dist/kernel/user-fields.d.ts +34 -0
  131. package/dist/kernel/user-fields.js +71 -0
  132. package/dist/kernel/validation.d.ts +15 -0
  133. package/dist/kernel/validation.js +54 -0
  134. package/dist/kernel/web-gateway.js +68 -0
  135. package/dist/kernel/web-head.js +15 -0
  136. package/dist/kernel/web-response.js +8 -0
  137. package/dist/kernel/web.d.ts +77 -0
  138. package/dist/kernel/web.js +158 -0
  139. package/dist/kernel/where.js +27 -0
  140. package/dist/testing/index.d.ts +1 -37
  141. package/dist/testing/index.js +1 -43
  142. package/dist/usecase/adminBindings.js +141 -0
  143. package/dist/usecase/adminClient.js +87 -0
  144. package/dist/usecase/adminDescriptors.js +107 -0
  145. package/dist/usecase/generate.js +165 -0
  146. package/dist/usecase/handlers.js +21 -0
  147. package/dist/usecase/mcp-media.js +17 -0
  148. package/dist/usecase/mcp.js +100 -0
  149. package/dist/usecase/paging.js +71 -0
  150. package/dist/usecase/publishing.js +63 -0
  151. package/dist/usecase/refusals.js +27 -0
  152. package/dist/usecase/rest.js +54 -0
  153. package/dist/usecase/search.js +7 -0
  154. package/dist/usecase/site.js +40 -0
  155. package/dist/usecase/stores.js +62 -0
  156. package/dist/usecase/tool-version.js +9 -0
  157. package/dist/usecase/translations.js +78 -0
  158. package/dist/usecase/ttl.js +20 -0
  159. package/dist/usecase/validation.js +233 -0
  160. package/dist/usecase/web.js +23 -0
  161. package/docs/examples/README.md +31 -16
  162. package/docs/examples/app-shell/README.md +86 -0
  163. package/docs/examples/app-shell/package.json +42 -0
  164. package/docs/examples/app-shell/pnpm-workspace.yaml +8 -0
  165. package/docs/examples/app-shell/smoke-kit.mjs +154 -0
  166. package/docs/examples/app-shell/src/auth.ts +57 -0
  167. package/docs/examples/app-shell/src/handlers.ts +5 -0
  168. package/docs/examples/app-shell/src/index.ts +4 -0
  169. package/docs/examples/app-shell/src/routes.ts +13 -0
  170. package/docs/examples/app-shell/src/schedule.ts +8 -0
  171. package/docs/examples/app-shell/src/service.ts +70 -0
  172. package/docs/examples/app-shell/src/sign-in.ts +41 -0
  173. package/docs/examples/app-shell/src/signup.ts +8 -0
  174. package/docs/examples/{reference-service → app-shell}/tsconfig.json +6 -2
  175. package/docs/examples/app-shell/worker-configuration.d.ts +22 -0
  176. package/docs/examples/app-shell/wrangler.jsonc +62 -0
  177. package/docs/examples/club-events/README.md +60 -0
  178. package/docs/examples/club-events/manifests/club-events.yaml +225 -0
  179. package/docs/examples/club-events/smoke.mjs +121 -0
  180. package/docs/examples/club-events/src/handlers.ts +25 -0
  181. package/docs/examples/club-events/src/signup.ts +9 -0
  182. package/docs/examples/generated-web/README.md +78 -0
  183. package/docs/examples/generated-web/posts.yaml +38 -0
  184. package/docs/examples/generated-web/seed.sql +6 -0
  185. package/docs/examples/generated-web/src/worker.ts +43 -0
  186. package/docs/examples/generated-web/tsconfig.json +8 -0
  187. package/docs/examples/generated-web/wrangler.jsonc +8 -0
  188. package/docs/examples/purchasing/.dev.vars.example +6 -0
  189. package/docs/examples/purchasing/README.md +90 -0
  190. package/docs/examples/purchasing/manifests/purchasing.yaml +341 -0
  191. package/docs/examples/purchasing/seed.sql +4 -0
  192. package/docs/examples/purchasing/smoke.mjs +177 -0
  193. package/docs/examples/purchasing/src/admin.tsx +13 -0
  194. package/docs/examples/purchasing/src/handlers.ts +33 -0
  195. package/docs/examples/purchasing/src/notify.ts +29 -0
  196. package/docs/examples/purchasing/src/requests-page.ts +57 -0
  197. package/docs/examples/purchasing/src/routes.ts +53 -0
  198. package/docs/examples/purchasing/src/schedule.ts +31 -0
  199. package/docs/examples/purchasing/src/signup.ts +5 -0
  200. package/docs/examples/purchasing/src/supplier.ts +32 -0
  201. package/docs/examples/purchasing/wrangler.jsonc +69 -0
  202. package/docs/examples/recipes/README.md +58 -0
  203. package/docs/examples/recipes/manifests/recipes.yaml +75 -0
  204. package/docs/examples/recipes/smoke.mjs +102 -0
  205. package/docs/examples/recipes/src/media.ts +13 -0
  206. package/docs/examples/recipes/src/pages.ts +99 -0
  207. package/docs/examples/recipes/src/routes.ts +71 -0
  208. package/docs/examples/recipes/src/site-config.ts +12 -0
  209. package/docs/examples/recipes/wrangler.jsonc +74 -0
  210. package/docs/handbook/cloudflare/authentication.md +164 -214
  211. package/docs/handbook/cloudflare/chatgpt-sites.md +4 -113
  212. package/docs/handbook/cloudflare/deploy-and-operate.md +38 -103
  213. package/docs/handbook/cloudflare/media-r2.md +62 -133
  214. package/docs/handbook/cloudflare/service-entry.md +210 -119
  215. package/docs/handbook/concepts/authorization.md +10 -123
  216. package/docs/handbook/concepts/four-atoms.md +9 -92
  217. package/docs/handbook/concepts/lifecycle-and-locales.md +9 -80
  218. package/docs/handbook/concepts/mcp-and-agents.md +24 -136
  219. package/docs/handbook/concepts/procedures-and-triggers.md +5 -162
  220. package/docs/handbook/concepts/runtime-and-adapters.md +15 -224
  221. package/docs/handbook/concepts/views.md +10 -109
  222. package/docs/handbook/examples/hub.md +2 -18
  223. package/docs/handbook/guides/adapter-guide.md +11 -0
  224. package/docs/handbook/guides/admin-ui.md +111 -164
  225. package/docs/handbook/guides/agent-setup.md +32 -27
  226. package/docs/handbook/guides/email.md +86 -0
  227. package/docs/handbook/guides/mcp-apps.md +483 -0
  228. package/docs/handbook/guides/native-admin.md +543 -0
  229. package/docs/handbook/guides/native-execution.md +132 -0
  230. package/docs/handbook/guides/oauth.md +161 -0
  231. package/docs/handbook/guides/postgres-adapters.md +56 -0
  232. package/docs/handbook/guides/public-pages.md +53 -0
  233. package/docs/handbook/guides/size-and-startup.md +9 -0
  234. package/docs/handbook/guides/typed-queries.md +39 -102
  235. package/docs/handbook/navigation.json +160 -31
  236. package/docs/handbook/reference/admin-descriptors.md +53 -0
  237. package/docs/handbook/reference/authorization.md +44 -52
  238. package/docs/handbook/reference/describe.md +56 -0
  239. package/docs/handbook/reference/diagnostics.md +15 -79
  240. package/docs/handbook/reference/features.md +45 -53
  241. package/docs/handbook/reference/manifest.md +6 -69
  242. package/docs/handbook/reference/procedure.md +11 -116
  243. package/docs/handbook/reference/schema.md +85 -185
  244. package/docs/handbook/reference/site-config.md +5 -65
  245. package/docs/handbook/reference/surface.md +389 -97
  246. package/docs/handbook/reference/trigger.md +54 -90
  247. package/docs/handbook/reference/view.md +32 -160
  248. package/docs/handbook/releases/index.md +120 -13
  249. package/docs/handbook/start/overview.md +9 -56
  250. package/docs/handbook/start/project-and-cli.md +40 -149
  251. package/docs/handbook/start/quickstart-worker.md +38 -116
  252. package/docs/skills/develop/SKILL.md +35 -123
  253. package/docs/skills/develop/mcp-app.md +37 -77
  254. package/docs/skills/integrate/SKILL.md +42 -84
  255. package/docs/skills/media-gc/SKILL.md +21 -8
  256. package/docs/skills/provision/SKILL.md +28 -91
  257. package/docs/skills/update/SKILL.md +19 -43
  258. package/docs/source/scripts/postgres-adapter.ts +101 -0
  259. package/docs/upgrade-0.1-to-0.2.md +25 -9
  260. package/package.json +97 -112
  261. package/skills/.keep +0 -0
  262. package/skills/README.md +67 -0
  263. package/skills/mantle/SKILL.md +135 -0
  264. package/skills/mantle/references/local-testing.md +15 -0
  265. package/skills/mantle/references/web.md +41 -0
  266. package/skills/mantle/references/website.md +49 -0
  267. package/dist/admin/consent.d.ts +0 -17
  268. package/dist/admin/consent.d.ts.map +0 -1
  269. package/dist/admin/consent.js +0 -17
  270. package/dist/admin/consent.js.map +0 -1
  271. package/dist/admin/createAdminSurface.d.ts +0 -25
  272. package/dist/admin/createAdminSurface.d.ts.map +0 -1
  273. package/dist/admin/createAdminSurface.js +0 -635
  274. package/dist/admin/createAdminSurface.js.map +0 -1
  275. package/dist/admin/design.d.ts +0 -7
  276. package/dist/admin/design.d.ts.map +0 -1
  277. package/dist/admin/design.js +0 -18
  278. package/dist/admin/design.js.map +0 -1
  279. package/dist/admin/developerConsole.d.ts +0 -267
  280. package/dist/admin/developerConsole.d.ts.map +0 -1
  281. package/dist/admin/developerConsole.js +0 -136
  282. package/dist/admin/developerConsole.js.map +0 -1
  283. package/dist/admin/extensions.d.ts +0 -290
  284. package/dist/admin/extensions.d.ts.map +0 -1
  285. package/dist/admin/extensions.js +0 -532
  286. package/dist/admin/extensions.js.map +0 -1
  287. package/dist/admin/identity.d.ts +0 -62
  288. package/dist/admin/identity.d.ts.map +0 -1
  289. package/dist/admin/identity.js +0 -7
  290. package/dist/admin/identity.js.map +0 -1
  291. package/dist/admin/index.d.ts +0 -7
  292. package/dist/admin/index.d.ts.map +0 -1
  293. package/dist/admin/index.js +0 -7
  294. package/dist/admin/index.js.map +0 -1
  295. package/dist/admin/procedureFlow.d.ts +0 -38
  296. package/dist/admin/procedureFlow.d.ts.map +0 -1
  297. package/dist/admin/procedureFlow.js +0 -188
  298. package/dist/admin/procedureFlow.js.map +0 -1
  299. package/dist/auth/ConsoleEmailSender.d.ts +0 -15
  300. package/dist/auth/ConsoleEmailSender.d.ts.map +0 -1
  301. package/dist/auth/ConsoleEmailSender.js +0 -19
  302. package/dist/auth/ConsoleEmailSender.js.map +0 -1
  303. package/dist/auth/appleClientSecret.d.ts +0 -75
  304. package/dist/auth/appleClientSecret.d.ts.map +0 -1
  305. package/dist/auth/appleClientSecret.js +0 -116
  306. package/dist/auth/appleClientSecret.js.map +0 -1
  307. package/dist/auth/buildAuth.d.ts +0 -4568
  308. package/dist/auth/buildAuth.d.ts.map +0 -1
  309. package/dist/auth/buildAuth.js +0 -312
  310. package/dist/auth/buildAuth.js.map +0 -1
  311. package/dist/auth/callerResolver.d.ts +0 -52
  312. package/dist/auth/callerResolver.d.ts.map +0 -1
  313. package/dist/auth/callerResolver.js +0 -52
  314. package/dist/auth/callerResolver.js.map +0 -1
  315. package/dist/auth/createAuthRoutes.d.ts +0 -22
  316. package/dist/auth/createAuthRoutes.d.ts.map +0 -1
  317. package/dist/auth/createAuthRoutes.js +0 -129
  318. package/dist/auth/createAuthRoutes.js.map +0 -1
  319. package/dist/auth/createMantleAuth.d.ts +0 -3
  320. package/dist/auth/createMantleAuth.d.ts.map +0 -1
  321. package/dist/auth/createMantleAuth.js +0 -504
  322. package/dist/auth/createMantleAuth.js.map +0 -1
  323. package/dist/auth/db.d.ts +0 -18
  324. package/dist/auth/db.d.ts.map +0 -1
  325. package/dist/auth/db.js +0 -27
  326. package/dist/auth/db.js.map +0 -1
  327. package/dist/auth/emailTemplates.d.ts +0 -7
  328. package/dist/auth/emailTemplates.d.ts.map +0 -1
  329. package/dist/auth/emailTemplates.js.map +0 -1
  330. package/dist/auth/index.d.ts +0 -9
  331. package/dist/auth/index.d.ts.map +0 -1
  332. package/dist/auth/index.js +0 -7
  333. package/dist/auth/index.js.map +0 -1
  334. package/dist/auth/methods.d.ts +0 -717
  335. package/dist/auth/methods.d.ts.map +0 -1
  336. package/dist/auth/methods.js +0 -321
  337. package/dist/auth/methods.js.map +0 -1
  338. package/dist/auth/oauthTokens.d.ts +0 -24
  339. package/dist/auth/oauthTokens.d.ts.map +0 -1
  340. package/dist/auth/oauthTokens.js +0 -146
  341. package/dist/auth/oauthTokens.js.map +0 -1
  342. package/dist/auth/setupIncomplete.d.ts +0 -16
  343. package/dist/auth/setupIncomplete.d.ts.map +0 -1
  344. package/dist/auth/setupIncomplete.js +0 -50
  345. package/dist/auth/setupIncomplete.js.map +0 -1
  346. package/dist/auth/types.d.ts +0 -440
  347. package/dist/auth/types.d.ts.map +0 -1
  348. package/dist/auth/types.js +0 -10
  349. package/dist/auth/types.js.map +0 -1
  350. package/dist/bun/index.d.ts +0 -21
  351. package/dist/bun/index.d.ts.map +0 -1
  352. package/dist/bun/index.js +0 -46
  353. package/dist/bun/index.js.map +0 -1
  354. package/dist/cli/emitModule.d.ts +0 -7
  355. package/dist/cli/emitModule.d.ts.map +0 -1
  356. package/dist/cli/emitModule.js +0 -127
  357. package/dist/cli/emitModule.js.map +0 -1
  358. package/dist/cli/generate.d.ts +0 -8
  359. package/dist/cli/generate.d.ts.map +0 -1
  360. package/dist/cli/generate.js +0 -391
  361. package/dist/cli/generate.js.map +0 -1
  362. package/dist/cli/main.d.ts +0 -3
  363. package/dist/cli/main.d.ts.map +0 -1
  364. package/dist/cli/main.js +0 -21
  365. package/dist/cli/main.js.map +0 -1
  366. package/dist/cli/preset.d.ts +0 -18
  367. package/dist/cli/preset.d.ts.map +0 -1
  368. package/dist/cli/preset.js +0 -405
  369. package/dist/cli/preset.js.map +0 -1
  370. package/dist/cloudflare/index.d.ts +0 -25
  371. package/dist/cloudflare/index.d.ts.map +0 -1
  372. package/dist/cloudflare/index.js +0 -16
  373. package/dist/cloudflare/index.js.map +0 -1
  374. package/dist/cloudflare/r2Media.d.ts.map +0 -1
  375. package/dist/cloudflare/r2Media.js +0 -69
  376. package/dist/cloudflare/r2Media.js.map +0 -1
  377. package/dist/core/caller.d.ts +0 -35
  378. package/dist/core/caller.d.ts.map +0 -1
  379. package/dist/core/caller.js +0 -3
  380. package/dist/core/caller.js.map +0 -1
  381. package/dist/core/createMantle.d.ts +0 -22
  382. package/dist/core/createMantle.d.ts.map +0 -1
  383. package/dist/core/createMantle.js +0 -117
  384. package/dist/core/createMantle.js.map +0 -1
  385. package/dist/core/dialect.d.ts +0 -53
  386. package/dist/core/dialect.d.ts.map +0 -1
  387. package/dist/core/dialect.js +0 -7
  388. package/dist/core/dialect.js.map +0 -1
  389. package/dist/core/driver.d.ts +0 -24
  390. package/dist/core/driver.d.ts.map +0 -1
  391. package/dist/core/driver.js +0 -2
  392. package/dist/core/driver.js.map +0 -1
  393. package/dist/core/email.d.ts +0 -17
  394. package/dist/core/email.d.ts.map +0 -1
  395. package/dist/core/email.js +0 -2
  396. package/dist/core/email.js.map +0 -1
  397. package/dist/core/index.d.ts +0 -16
  398. package/dist/core/index.d.ts.map +0 -1
  399. package/dist/core/index.js +0 -16
  400. package/dist/core/index.js.map +0 -1
  401. package/dist/core/invocation.d.ts +0 -66
  402. package/dist/core/invocation.d.ts.map +0 -1
  403. package/dist/core/invocation.js +0 -3
  404. package/dist/core/invocation.js.map +0 -1
  405. package/dist/core/observation.d.ts +0 -3
  406. package/dist/core/observation.d.ts.map +0 -1
  407. package/dist/core/observation.js +0 -10
  408. package/dist/core/observation.js.map +0 -1
  409. package/dist/core/runtime/auth.d.ts +0 -9
  410. package/dist/core/runtime/auth.d.ts.map +0 -1
  411. package/dist/core/runtime/auth.js +0 -39
  412. package/dist/core/runtime/auth.js.map +0 -1
  413. package/dist/core/runtime/createRuntime.d.ts +0 -23
  414. package/dist/core/runtime/createRuntime.d.ts.map +0 -1
  415. package/dist/core/runtime/createRuntime.js +0 -214
  416. package/dist/core/runtime/createRuntime.js.map +0 -1
  417. package/dist/core/runtime/verifyPlan.d.ts +0 -34
  418. package/dist/core/runtime/verifyPlan.d.ts.map +0 -1
  419. package/dist/core/runtime/verifyPlan.js +0 -301
  420. package/dist/core/runtime/verifyPlan.js.map +0 -1
  421. package/dist/core/service.d.ts +0 -45
  422. package/dist/core/service.d.ts.map +0 -1
  423. package/dist/core/service.js +0 -2
  424. package/dist/core/service.js.map +0 -1
  425. package/dist/core/sessionUser.d.ts +0 -14
  426. package/dist/core/sessionUser.d.ts.map +0 -1
  427. package/dist/core/sessionUser.js +0 -4
  428. package/dist/core/sessionUser.js.map +0 -1
  429. package/dist/core/site.d.ts.map +0 -1
  430. package/dist/core/site.js +0 -2
  431. package/dist/core/site.js.map +0 -1
  432. package/dist/core/siteConfig.d.ts +0 -5
  433. package/dist/core/siteConfig.d.ts.map +0 -1
  434. package/dist/core/siteConfig.js +0 -24
  435. package/dist/core/siteConfig.js.map +0 -1
  436. package/dist/core/sql/allowlist.d.ts +0 -67
  437. package/dist/core/sql/allowlist.d.ts.map +0 -1
  438. package/dist/core/sql/allowlist.js +0 -737
  439. package/dist/core/sql/allowlist.js.map +0 -1
  440. package/dist/core/sql/ast.d.ts +0 -24
  441. package/dist/core/sql/ast.d.ts.map +0 -1
  442. package/dist/core/sql/ast.js +0 -32
  443. package/dist/core/sql/ast.js.map +0 -1
  444. package/dist/core/sql/compile.d.ts +0 -50
  445. package/dist/core/sql/compile.d.ts.map +0 -1
  446. package/dist/core/sql/compile.js +0 -48
  447. package/dist/core/sql/compile.js.map +0 -1
  448. package/dist/core/sql/policy.d.ts +0 -123
  449. package/dist/core/sql/policy.d.ts.map +0 -1
  450. package/dist/core/sql/policy.js +0 -398
  451. package/dist/core/sql/policy.js.map +0 -1
  452. package/dist/core/sql/positions.d.ts +0 -30
  453. package/dist/core/sql/positions.d.ts.map +0 -1
  454. package/dist/core/sql/positions.js +0 -22
  455. package/dist/core/sql/positions.js.map +0 -1
  456. package/dist/core/sql/run.d.ts +0 -68
  457. package/dist/core/sql/run.d.ts.map +0 -1
  458. package/dist/core/sql/run.js +0 -384
  459. package/dist/core/sql/run.js.map +0 -1
  460. package/dist/core/store/createStore.d.ts +0 -49
  461. package/dist/core/store/createStore.d.ts.map +0 -1
  462. package/dist/core/store/createStore.js +0 -227
  463. package/dist/core/store/createStore.js.map +0 -1
  464. package/dist/core/store/cursor.d.ts +0 -4
  465. package/dist/core/store/cursor.d.ts.map +0 -1
  466. package/dist/core/store/cursor.js +0 -22
  467. package/dist/core/store/cursor.js.map +0 -1
  468. package/dist/core/store/json.d.ts +0 -80
  469. package/dist/core/store/json.d.ts.map +0 -1
  470. package/dist/core/store/json.js +0 -342
  471. package/dist/core/store/json.js.map +0 -1
  472. package/dist/core/store.d.ts +0 -160
  473. package/dist/core/store.d.ts.map +0 -1
  474. package/dist/core/store.js +0 -2
  475. package/dist/core/store.js.map +0 -1
  476. package/dist/core/wire.d.ts +0 -20
  477. package/dist/core/wire.d.ts.map +0 -1
  478. package/dist/core/wire.js +0 -84
  479. package/dist/core/wire.js.map +0 -1
  480. package/dist/core/withCaller.d.ts +0 -24
  481. package/dist/core/withCaller.d.ts.map +0 -1
  482. package/dist/core/withCaller.js +0 -35
  483. package/dist/core/withCaller.js.map +0 -1
  484. package/dist/d1/adapter.d.ts +0 -12
  485. package/dist/d1/adapter.d.ts.map +0 -1
  486. package/dist/d1/adapter.js +0 -23
  487. package/dist/d1/adapter.js.map +0 -1
  488. package/dist/d1/codec.d.ts +0 -14
  489. package/dist/d1/codec.d.ts.map +0 -1
  490. package/dist/d1/codec.js +0 -136
  491. package/dist/d1/codec.js.map +0 -1
  492. package/dist/d1/compile/index.d.ts +0 -9
  493. package/dist/d1/compile/index.d.ts.map +0 -1
  494. package/dist/d1/compile/index.js +0 -9
  495. package/dist/d1/compile/index.js.map +0 -1
  496. package/dist/d1/dialect.d.ts +0 -4
  497. package/dist/d1/dialect.d.ts.map +0 -1
  498. package/dist/d1/dialect.js +0 -13
  499. package/dist/d1/dialect.js.map +0 -1
  500. package/dist/d1/executor.d.ts +0 -15
  501. package/dist/d1/executor.d.ts.map +0 -1
  502. package/dist/d1/executor.js +0 -96
  503. package/dist/d1/executor.js.map +0 -1
  504. package/dist/d1/index.d.ts +0 -6
  505. package/dist/d1/index.d.ts.map +0 -1
  506. package/dist/d1/index.js +0 -6
  507. package/dist/d1/index.js.map +0 -1
  508. package/dist/d1/lower.d.ts +0 -8
  509. package/dist/d1/lower.d.ts.map +0 -1
  510. package/dist/d1/lower.js +0 -167
  511. package/dist/d1/lower.js.map +0 -1
  512. package/dist/d1/media.d.ts +0 -5
  513. package/dist/d1/media.d.ts.map +0 -1
  514. package/dist/d1/media.js +0 -157
  515. package/dist/d1/media.js.map +0 -1
  516. package/dist/d1/migrations.d.ts +0 -12
  517. package/dist/d1/migrations.d.ts.map +0 -1
  518. package/dist/d1/migrations.js +0 -111
  519. package/dist/d1/migrations.js.map +0 -1
  520. package/dist/d1/print.d.ts +0 -28
  521. package/dist/d1/print.d.ts.map +0 -1
  522. package/dist/d1/print.js +0 -54
  523. package/dist/d1/print.js.map +0 -1
  524. package/dist/d1/site.d.ts +0 -17
  525. package/dist/d1/site.d.ts.map +0 -1
  526. package/dist/d1/site.js +0 -63
  527. package/dist/d1/site.js.map +0 -1
  528. package/dist/d1/storage.d.ts +0 -34
  529. package/dist/d1/storage.d.ts.map +0 -1
  530. package/dist/d1/storage.js +0 -288
  531. package/dist/d1/storage.js.map +0 -1
  532. package/dist/d1/tz.d.ts +0 -21
  533. package/dist/d1/tz.d.ts.map +0 -1
  534. package/dist/d1/tz.js +0 -54
  535. package/dist/d1/tz.js.map +0 -1
  536. package/dist/d1/validator.d.ts +0 -10
  537. package/dist/d1/validator.d.ts.map +0 -1
  538. package/dist/d1/validator.js +0 -33
  539. package/dist/d1/validator.js.map +0 -1
  540. package/dist/mcp/apps.d.ts +0 -43
  541. package/dist/mcp/apps.d.ts.map +0 -1
  542. package/dist/mcp/apps.js +0 -57
  543. package/dist/mcp/apps.js.map +0 -1
  544. package/dist/mcp/catalog.d.ts +0 -55
  545. package/dist/mcp/catalog.d.ts.map +0 -1
  546. package/dist/mcp/catalog.js +0 -81
  547. package/dist/mcp/catalog.js.map +0 -1
  548. package/dist/mcp/createMcpSurface.d.ts +0 -60
  549. package/dist/mcp/createMcpSurface.d.ts.map +0 -1
  550. package/dist/mcp/createMcpSurface.js +0 -182
  551. package/dist/mcp/createMcpSurface.js.map +0 -1
  552. package/dist/mcp/index.d.ts +0 -4
  553. package/dist/mcp/index.d.ts.map +0 -1
  554. package/dist/mcp/index.js +0 -4
  555. package/dist/mcp/index.js.map +0 -1
  556. package/dist/mcp/media.d.ts +0 -9
  557. package/dist/mcp/media.d.ts.map +0 -1
  558. package/dist/mcp/media.js +0 -33
  559. package/dist/mcp/media.js.map +0 -1
  560. package/dist/postgres/adapter.d.ts +0 -23
  561. package/dist/postgres/adapter.d.ts.map +0 -1
  562. package/dist/postgres/adapter.js +0 -50
  563. package/dist/postgres/adapter.js.map +0 -1
  564. package/dist/postgres/codec.d.ts +0 -13
  565. package/dist/postgres/codec.d.ts.map +0 -1
  566. package/dist/postgres/codec.js +0 -110
  567. package/dist/postgres/codec.js.map +0 -1
  568. package/dist/postgres/compile/index.d.ts +0 -9
  569. package/dist/postgres/compile/index.d.ts.map +0 -1
  570. package/dist/postgres/compile/index.js +0 -9
  571. package/dist/postgres/compile/index.js.map +0 -1
  572. package/dist/postgres/driver.d.ts +0 -109
  573. package/dist/postgres/driver.d.ts.map +0 -1
  574. package/dist/postgres/driver.js +0 -186
  575. package/dist/postgres/driver.js.map +0 -1
  576. package/dist/postgres/executor.d.ts +0 -28
  577. package/dist/postgres/executor.d.ts.map +0 -1
  578. package/dist/postgres/executor.js +0 -96
  579. package/dist/postgres/executor.js.map +0 -1
  580. package/dist/postgres/index.d.ts +0 -8
  581. package/dist/postgres/index.d.ts.map +0 -1
  582. package/dist/postgres/index.js +0 -8
  583. package/dist/postgres/index.js.map +0 -1
  584. package/dist/postgres/lower.d.ts +0 -6
  585. package/dist/postgres/lower.d.ts.map +0 -1
  586. package/dist/postgres/lower.js +0 -152
  587. package/dist/postgres/lower.js.map +0 -1
  588. package/dist/postgres/print.d.ts +0 -11
  589. package/dist/postgres/print.d.ts.map +0 -1
  590. package/dist/postgres/print.js +0 -108
  591. package/dist/postgres/print.js.map +0 -1
  592. package/dist/postgres/session.d.ts +0 -9
  593. package/dist/postgres/session.d.ts.map +0 -1
  594. package/dist/postgres/session.js +0 -111
  595. package/dist/postgres/session.js.map +0 -1
  596. package/dist/postgres/storage.d.ts +0 -32
  597. package/dist/postgres/storage.d.ts.map +0 -1
  598. package/dist/postgres/storage.js +0 -283
  599. package/dist/postgres/storage.js.map +0 -1
  600. package/dist/postgres/validator.d.ts +0 -13
  601. package/dist/postgres/validator.d.ts.map +0 -1
  602. package/dist/postgres/validator.js +0 -53
  603. package/dist/postgres/validator.js.map +0 -1
  604. package/dist/spec/domain/index.d.ts +0 -3
  605. package/dist/spec/domain/index.d.ts.map +0 -1
  606. package/dist/spec/domain/index.js +0 -3
  607. package/dist/spec/domain/index.js.map +0 -1
  608. package/dist/spec/domain/model/ContentState.d.ts +0 -8
  609. package/dist/spec/domain/model/ContentState.d.ts.map +0 -1
  610. package/dist/spec/domain/model/ContentState.js +0 -7
  611. package/dist/spec/domain/model/ContentState.js.map +0 -1
  612. package/dist/spec/domain/model/Entry.d.ts +0 -29
  613. package/dist/spec/domain/model/Entry.d.ts.map +0 -1
  614. package/dist/spec/domain/model/Entry.js +0 -16
  615. package/dist/spec/domain/model/Entry.js.map +0 -1
  616. package/dist/spec/domain/model/Locale.d.ts +0 -30
  617. package/dist/spec/domain/model/Locale.d.ts.map +0 -1
  618. package/dist/spec/domain/model/Locale.js +0 -33
  619. package/dist/spec/domain/model/Locale.js.map +0 -1
  620. package/dist/spec/domain/model/ManifestGrammar.d.ts.map +0 -1
  621. package/dist/spec/domain/model/ManifestGrammar.js +0 -153
  622. package/dist/spec/domain/model/ManifestGrammar.js.map +0 -1
  623. package/dist/spec/domain/model/MediaMimeAccept.d.ts +0 -55
  624. package/dist/spec/domain/model/MediaMimeAccept.d.ts.map +0 -1
  625. package/dist/spec/domain/model/MediaMimeAccept.js +0 -90
  626. package/dist/spec/domain/model/MediaMimeAccept.js.map +0 -1
  627. package/dist/spec/domain/model/RuntimePlan.d.ts.map +0 -1
  628. package/dist/spec/domain/model/RuntimePlan.js +0 -4
  629. package/dist/spec/domain/model/RuntimePlan.js.map +0 -1
  630. package/dist/spec/domain/model/SiteConfig.d.ts +0 -173
  631. package/dist/spec/domain/model/SiteConfig.d.ts.map +0 -1
  632. package/dist/spec/domain/model/SiteConfig.js +0 -13
  633. package/dist/spec/domain/model/SiteConfig.js.map +0 -1
  634. package/dist/spec/domain/model/SqlIr.d.ts.map +0 -1
  635. package/dist/spec/domain/model/SqlIr.js +0 -95
  636. package/dist/spec/domain/model/SqlIr.js.map +0 -1
  637. package/dist/spec/domain/model/index.d.ts +0 -14
  638. package/dist/spec/domain/model/index.d.ts.map +0 -1
  639. package/dist/spec/domain/model/index.js +0 -14
  640. package/dist/spec/domain/model/index.js.map +0 -1
  641. package/dist/spec/domain/service/CloudflareCron.d.ts.map +0 -1
  642. package/dist/spec/domain/service/CloudflareCron.js.map +0 -1
  643. package/dist/spec/domain/service/CrossSchemaChecker.d.ts +0 -34
  644. package/dist/spec/domain/service/CrossSchemaChecker.d.ts.map +0 -1
  645. package/dist/spec/domain/service/CrossSchemaChecker.js +0 -114
  646. package/dist/spec/domain/service/CrossSchemaChecker.js.map +0 -1
  647. package/dist/spec/domain/service/EntryDataValidator.d.ts +0 -56
  648. package/dist/spec/domain/service/EntryDataValidator.d.ts.map +0 -1
  649. package/dist/spec/domain/service/EntryDataValidator.js +0 -88
  650. package/dist/spec/domain/service/EntryDataValidator.js.map +0 -1
  651. package/dist/spec/domain/service/JsonSchemaToZod.d.ts +0 -29
  652. package/dist/spec/domain/service/JsonSchemaToZod.d.ts.map +0 -1
  653. package/dist/spec/domain/service/JsonSchemaToZod.js +0 -156
  654. package/dist/spec/domain/service/JsonSchemaToZod.js.map +0 -1
  655. package/dist/spec/domain/service/LifecycleStateMachine.d.ts +0 -75
  656. package/dist/spec/domain/service/LifecycleStateMachine.d.ts.map +0 -1
  657. package/dist/spec/domain/service/LifecycleStateMachine.js +0 -76
  658. package/dist/spec/domain/service/LifecycleStateMachine.js.map +0 -1
  659. package/dist/spec/domain/service/LocaleCanonicalizer.d.ts +0 -29
  660. package/dist/spec/domain/service/LocaleCanonicalizer.d.ts.map +0 -1
  661. package/dist/spec/domain/service/LocaleCanonicalizer.js +0 -96
  662. package/dist/spec/domain/service/LocaleCanonicalizer.js.map +0 -1
  663. package/dist/spec/domain/service/ManifestFieldChecks.d.ts +0 -60
  664. package/dist/spec/domain/service/ManifestFieldChecks.d.ts.map +0 -1
  665. package/dist/spec/domain/service/ManifestFieldChecks.js +0 -116
  666. package/dist/spec/domain/service/ManifestFieldChecks.js.map +0 -1
  667. package/dist/spec/domain/service/ManifestGraphValidator.d.ts +0 -15
  668. package/dist/spec/domain/service/ManifestGraphValidator.d.ts.map +0 -1
  669. package/dist/spec/domain/service/ManifestGraphValidator.js +0 -225
  670. package/dist/spec/domain/service/ManifestGraphValidator.js.map +0 -1
  671. package/dist/spec/domain/service/ManifestLinker.d.ts +0 -45
  672. package/dist/spec/domain/service/ManifestLinker.d.ts.map +0 -1
  673. package/dist/spec/domain/service/ManifestLinker.js +0 -92
  674. package/dist/spec/domain/service/ManifestLinker.js.map +0 -1
  675. package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts +0 -16
  676. package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts.map +0 -1
  677. package/dist/spec/domain/service/ManifestLocaleTrimmer.js +0 -76
  678. package/dist/spec/domain/service/ManifestLocaleTrimmer.js.map +0 -1
  679. package/dist/spec/domain/service/ManifestParser.d.ts +0 -49
  680. package/dist/spec/domain/service/ManifestParser.d.ts.map +0 -1
  681. package/dist/spec/domain/service/ManifestParser.js +0 -203
  682. package/dist/spec/domain/service/ManifestParser.js.map +0 -1
  683. package/dist/spec/domain/service/ManifestPartition.d.ts +0 -9
  684. package/dist/spec/domain/service/ManifestPartition.d.ts.map +0 -1
  685. package/dist/spec/domain/service/ManifestPartition.js +0 -19
  686. package/dist/spec/domain/service/ManifestPartition.js.map +0 -1
  687. package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts +0 -33
  688. package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts.map +0 -1
  689. package/dist/spec/domain/service/ManifestPathDiagnoser.js +0 -43
  690. package/dist/spec/domain/service/ManifestPathDiagnoser.js.map +0 -1
  691. package/dist/spec/domain/service/ManifestSourceSpans.d.ts +0 -10
  692. package/dist/spec/domain/service/ManifestSourceSpans.d.ts.map +0 -1
  693. package/dist/spec/domain/service/ManifestSourceSpans.js +0 -76
  694. package/dist/spec/domain/service/ManifestSourceSpans.js.map +0 -1
  695. package/dist/spec/domain/service/McpToolNaming.d.ts +0 -25
  696. package/dist/spec/domain/service/McpToolNaming.d.ts.map +0 -1
  697. package/dist/spec/domain/service/McpToolNaming.js +0 -50
  698. package/dist/spec/domain/service/McpToolNaming.js.map +0 -1
  699. package/dist/spec/domain/service/PlanFingerprint.d.ts.map +0 -1
  700. package/dist/spec/domain/service/PlanFingerprint.js +0 -14
  701. package/dist/spec/domain/service/PlanFingerprint.js.map +0 -1
  702. package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts +0 -4
  703. package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts.map +0 -1
  704. package/dist/spec/domain/service/ProcedureViewSpecChecks.js +0 -211
  705. package/dist/spec/domain/service/ProcedureViewSpecChecks.js.map +0 -1
  706. package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts +0 -44
  707. package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts.map +0 -1
  708. package/dist/spec/domain/service/SchemaAdminUiChecker.js +0 -333
  709. package/dist/spec/domain/service/SchemaAdminUiChecker.js.map +0 -1
  710. package/dist/spec/domain/service/SchemaIndexChecker.d.ts +0 -33
  711. package/dist/spec/domain/service/SchemaIndexChecker.d.ts.map +0 -1
  712. package/dist/spec/domain/service/SchemaIndexChecker.js +0 -256
  713. package/dist/spec/domain/service/SchemaIndexChecker.js.map +0 -1
  714. package/dist/spec/domain/service/SchemaSearchChecker.d.ts +0 -11
  715. package/dist/spec/domain/service/SchemaSearchChecker.d.ts.map +0 -1
  716. package/dist/spec/domain/service/SchemaSearchChecker.js +0 -78
  717. package/dist/spec/domain/service/SchemaSearchChecker.js.map +0 -1
  718. package/dist/spec/domain/service/SchemaSpecChecks.d.ts +0 -31
  719. package/dist/spec/domain/service/SchemaSpecChecks.d.ts.map +0 -1
  720. package/dist/spec/domain/service/SchemaSpecChecks.js +0 -445
  721. package/dist/spec/domain/service/SchemaSpecChecks.js.map +0 -1
  722. package/dist/spec/domain/service/SiteDefaultsValidator.d.ts +0 -39
  723. package/dist/spec/domain/service/SiteDefaultsValidator.d.ts.map +0 -1
  724. package/dist/spec/domain/service/SiteDefaultsValidator.js +0 -194
  725. package/dist/spec/domain/service/SiteDefaultsValidator.js.map +0 -1
  726. package/dist/spec/domain/service/SqlClassify.d.ts +0 -19
  727. package/dist/spec/domain/service/SqlClassify.d.ts.map +0 -1
  728. package/dist/spec/domain/service/SqlClassify.js +0 -42
  729. package/dist/spec/domain/service/SqlClassify.js.map +0 -1
  730. package/dist/spec/domain/service/SqlRefusal.d.ts +0 -16
  731. package/dist/spec/domain/service/SqlRefusal.d.ts.map +0 -1
  732. package/dist/spec/domain/service/SqlRefusal.js +0 -20
  733. package/dist/spec/domain/service/SqlRefusal.js.map +0 -1
  734. package/dist/spec/domain/service/SqlTypes.d.ts +0 -40
  735. package/dist/spec/domain/service/SqlTypes.d.ts.map +0 -1
  736. package/dist/spec/domain/service/SqlTypes.js +0 -110
  737. package/dist/spec/domain/service/SqlTypes.js.map +0 -1
  738. package/dist/spec/domain/service/StaffRoleHierarchy.d.ts +0 -3
  739. package/dist/spec/domain/service/StaffRoleHierarchy.d.ts.map +0 -1
  740. package/dist/spec/domain/service/StaffRoleHierarchy.js +0 -19
  741. package/dist/spec/domain/service/StaffRoleHierarchy.js.map +0 -1
  742. package/dist/spec/domain/service/TriggerGraphChecks.d.ts +0 -16
  743. package/dist/spec/domain/service/TriggerGraphChecks.d.ts.map +0 -1
  744. package/dist/spec/domain/service/TriggerGraphChecks.js +0 -337
  745. package/dist/spec/domain/service/TriggerGraphChecks.js.map +0 -1
  746. package/dist/spec/domain/service/TriggerSpecChecks.d.ts +0 -4
  747. package/dist/spec/domain/service/TriggerSpecChecks.d.ts.map +0 -1
  748. package/dist/spec/domain/service/TriggerSpecChecks.js +0 -89
  749. package/dist/spec/domain/service/TriggerSpecChecks.js.map +0 -1
  750. package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts +0 -11
  751. package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts.map +0 -1
  752. package/dist/spec/domain/service/ValidatedAdminUiProjection.js +0 -26
  753. package/dist/spec/domain/service/ValidatedAdminUiProjection.js.map +0 -1
  754. package/dist/spec/domain/service/ViewAdminUiChecker.d.ts +0 -14
  755. package/dist/spec/domain/service/ViewAdminUiChecker.d.ts.map +0 -1
  756. package/dist/spec/domain/service/ViewAdminUiChecker.js +0 -58
  757. package/dist/spec/domain/service/ViewAdminUiChecker.js.map +0 -1
  758. package/dist/spec/domain/service/index.d.ts +0 -24
  759. package/dist/spec/domain/service/index.d.ts.map +0 -1
  760. package/dist/spec/domain/service/index.js +0 -24
  761. package/dist/spec/domain/service/index.js.map +0 -1
  762. package/dist/spec/index.d.ts +0 -10
  763. package/dist/spec/index.d.ts.map +0 -1
  764. package/dist/spec/index.js +0 -12
  765. package/dist/spec/index.js.map +0 -1
  766. package/dist/spec/infrastructure/cli/parseArgsError.d.ts +0 -16
  767. package/dist/spec/infrastructure/cli/parseArgsError.d.ts.map +0 -1
  768. package/dist/spec/infrastructure/cli/parseArgsError.js +0 -34
  769. package/dist/spec/infrastructure/cli/parseArgsError.js.map +0 -1
  770. package/dist/spec/infrastructure/index.d.ts +0 -2
  771. package/dist/spec/infrastructure/index.d.ts.map +0 -1
  772. package/dist/spec/infrastructure/index.js +0 -2
  773. package/dist/spec/infrastructure/index.js.map +0 -1
  774. package/dist/spec/infrastructure/sql/PgQueryParser.d.ts +0 -18
  775. package/dist/spec/infrastructure/sql/PgQueryParser.d.ts.map +0 -1
  776. package/dist/spec/infrastructure/sql/PgQueryParser.js +0 -17
  777. package/dist/spec/infrastructure/sql/PgQueryParser.js.map +0 -1
  778. package/dist/spec/infrastructure/sql/compilePlan.d.ts +0 -37
  779. package/dist/spec/infrastructure/sql/compilePlan.d.ts.map +0 -1
  780. package/dist/spec/infrastructure/sql/compilePlan.js +0 -287
  781. package/dist/spec/infrastructure/sql/compilePlan.js.map +0 -1
  782. package/dist/spec/infrastructure/sql/compileSql.d.ts +0 -35
  783. package/dist/spec/infrastructure/sql/compileSql.d.ts.map +0 -1
  784. package/dist/spec/infrastructure/sql/compileSql.js +0 -92
  785. package/dist/spec/infrastructure/sql/compileSql.js.map +0 -1
  786. package/dist/spec/infrastructure/sql/frontEnd.d.ts +0 -8
  787. package/dist/spec/infrastructure/sql/frontEnd.d.ts.map +0 -1
  788. package/dist/spec/infrastructure/sql/frontEnd.js +0 -100
  789. package/dist/spec/infrastructure/sql/frontEnd.js.map +0 -1
  790. package/dist/spec/infrastructure/sql/index.d.ts +0 -4
  791. package/dist/spec/infrastructure/sql/index.d.ts.map +0 -1
  792. package/dist/spec/infrastructure/sql/index.js +0 -4
  793. package/dist/spec/infrastructure/sql/index.js.map +0 -1
  794. package/dist/spec/kernel/diagnostic.d.ts.map +0 -1
  795. package/dist/spec/kernel/diagnostic.js +0 -301
  796. package/dist/spec/kernel/diagnostic.js.map +0 -1
  797. package/dist/spec/kernel/index.d.ts +0 -8
  798. package/dist/spec/kernel/index.d.ts.map +0 -1
  799. package/dist/spec/kernel/index.js +0 -8
  800. package/dist/spec/kernel/index.js.map +0 -1
  801. package/dist/spec/usecase/EmitTypes.d.ts +0 -22
  802. package/dist/spec/usecase/EmitTypes.d.ts.map +0 -1
  803. package/dist/spec/usecase/EmitTypes.js +0 -182
  804. package/dist/spec/usecase/EmitTypes.js.map +0 -1
  805. package/dist/spec/usecase/ValidateManifestsUseCase.d.ts +0 -8
  806. package/dist/spec/usecase/ValidateManifestsUseCase.d.ts.map +0 -1
  807. package/dist/spec/usecase/ValidateManifestsUseCase.js +0 -101
  808. package/dist/spec/usecase/ValidateManifestsUseCase.js.map +0 -1
  809. package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts +0 -27
  810. package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts.map +0 -1
  811. package/dist/spec/usecase/dto/ValidateManifestsRequest.js +0 -2
  812. package/dist/spec/usecase/dto/ValidateManifestsRequest.js.map +0 -1
  813. package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts +0 -14
  814. package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts.map +0 -1
  815. package/dist/spec/usecase/dto/ValidateManifestsResponse.js +0 -2
  816. package/dist/spec/usecase/dto/ValidateManifestsResponse.js.map +0 -1
  817. package/dist/spec/usecase/dto/index.d.ts +0 -3
  818. package/dist/spec/usecase/dto/index.d.ts.map +0 -1
  819. package/dist/spec/usecase/dto/index.js +0 -3
  820. package/dist/spec/usecase/dto/index.js.map +0 -1
  821. package/dist/spec/usecase/index.d.ts +0 -10
  822. package/dist/spec/usecase/index.d.ts.map +0 -1
  823. package/dist/spec/usecase/index.js +0 -10
  824. package/dist/spec/usecase/index.js.map +0 -1
  825. package/dist/testing/cases/before-hook.d.ts +0 -4
  826. package/dist/testing/cases/before-hook.d.ts.map +0 -1
  827. package/dist/testing/cases/before-hook.js +0 -71
  828. package/dist/testing/cases/before-hook.js.map +0 -1
  829. package/dist/testing/cases/corpus.d.ts +0 -14
  830. package/dist/testing/cases/corpus.d.ts.map +0 -1
  831. package/dist/testing/cases/corpus.js +0 -93
  832. package/dist/testing/cases/corpus.js.map +0 -1
  833. package/dist/testing/cases/policy.d.ts +0 -87
  834. package/dist/testing/cases/policy.d.ts.map +0 -1
  835. package/dist/testing/cases/policy.js +0 -143
  836. package/dist/testing/cases/policy.js.map +0 -1
  837. package/dist/testing/cases/printer.d.ts +0 -4
  838. package/dist/testing/cases/printer.d.ts.map +0 -1
  839. package/dist/testing/cases/printer.js +0 -34
  840. package/dist/testing/cases/printer.js.map +0 -1
  841. package/dist/testing/cases/report-view.d.ts +0 -5
  842. package/dist/testing/cases/report-view.d.ts.map +0 -1
  843. package/dist/testing/cases/report-view.js +0 -51
  844. package/dist/testing/cases/report-view.js.map +0 -1
  845. package/dist/testing/cases/requisition.d.ts +0 -4
  846. package/dist/testing/cases/requisition.d.ts.map +0 -1
  847. package/dist/testing/cases/requisition.js +0 -38
  848. package/dist/testing/cases/requisition.js.map +0 -1
  849. package/dist/testing/cases/search-places.d.ts +0 -4
  850. package/dist/testing/cases/search-places.d.ts.map +0 -1
  851. package/dist/testing/cases/search-places.js +0 -60
  852. package/dist/testing/cases/search-places.js.map +0 -1
  853. package/dist/testing/cases/stock.d.ts +0 -4
  854. package/dist/testing/cases/stock.d.ts.map +0 -1
  855. package/dist/testing/cases/stock.js +0 -35
  856. package/dist/testing/cases/stock.js.map +0 -1
  857. package/dist/testing/cases/store.d.ts +0 -4
  858. package/dist/testing/cases/store.d.ts.map +0 -1
  859. package/dist/testing/cases/store.js +0 -100
  860. package/dist/testing/cases/store.js.map +0 -1
  861. package/dist/testing/harness.d.ts +0 -94
  862. package/dist/testing/harness.d.ts.map +0 -1
  863. package/dist/testing/harness.js +0 -168
  864. package/dist/testing/harness.js.map +0 -1
  865. package/dist/testing/index.d.ts.map +0 -1
  866. package/dist/testing/index.js.map +0 -1
  867. package/dist/testing/report.d.ts +0 -15
  868. package/dist/testing/report.d.ts.map +0 -1
  869. package/dist/testing/report.js +0 -22
  870. package/dist/testing/report.js.map +0 -1
  871. package/dist/web/createRestSurface.d.ts +0 -7
  872. package/dist/web/createRestSurface.d.ts.map +0 -1
  873. package/dist/web/createRestSurface.js +0 -41
  874. package/dist/web/createRestSurface.js.map +0 -1
  875. package/dist/web/index.d.ts +0 -2
  876. package/dist/web/index.d.ts.map +0 -1
  877. package/dist/web/index.js +0 -2
  878. package/dist/web/index.js.map +0 -1
  879. package/docs/adr/0001-four-atom-manifest-model.md +0 -440
  880. package/docs/adr/0002-closed-enums-for-bindings.md +0 -253
  881. package/docs/adr/0007-ai-as-primary-author.md +0 -473
  882. package/docs/adr/0008-structured-diagnostic-shape.md +0 -338
  883. package/docs/adr/0009-consumer-supplied-manifests.md +0 -149
  884. package/docs/adr/0010-locale-and-translates.md +0 -453
  885. package/docs/adr/0011-adapter-port-spec.md +0 -281
  886. package/docs/adr/0012-views-as-public-rest.md +0 -161
  887. package/docs/adr/0013-agent-provisioned-consumer-projects.md +0 -154
  888. package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +0 -939
  889. package/docs/adr/0016-site-semantic-layer.md +0 -70
  890. package/docs/adr/0017-media-multi-variant-agent-side-optimization.md +0 -181
  891. package/docs/adr/0018-core-starters-repository-boundary.md +0 -179
  892. package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +0 -244
  893. package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +0 -199
  894. package/docs/adr/0021-retire-starter-scaffolding.md +0 -30
  895. package/docs/adr/0022-caller-observed-version-occ.md +0 -212
  896. package/docs/adr/0023-port-failure-contract.md +0 -69
  897. package/docs/adr/0024-manifest-native-schema-tables.md +0 -264
  898. package/docs/adr/0025-reserved-native-columns-and-published-only-public-views.md +0 -105
  899. package/docs/adr/0026-progressive-generate.md +0 -36
  900. package/docs/adr/0027-scheduled-procedure-triggers.md +0 -31
  901. package/docs/adr/0028-schema-ttl-expiry.md +0 -33
  902. package/docs/adr/0029-mcp-apps-interaction-contracts.md +0 -324
  903. package/docs/adr/0030-store.md +0 -40
  904. package/docs/adr/0031-host-cloud-core-contract.md +0 -102
  905. package/docs/adr/0032-store-centric-core-and-service-contract.md +0 -384
  906. package/docs/adr/0033-storage-converges-to-the-plan.md +0 -92
  907. package/docs/adr/0034-store-is-authored-as-sql.md +0 -192
  908. package/docs/adr/0035-sql-dialects.md +0 -154
  909. package/docs/adr/0036-host-and-dialect.md +0 -65
  910. package/docs/adr/0037-postgresql-is-the-reference-dialect.md +0 -125
  911. package/docs/adr/0038-bun-native-host.md +0 -63
  912. package/docs/adr/0039-postgresql-is-native.md +0 -130
  913. package/docs/adr/README.md +0 -98
  914. package/docs/adr/adr-lite-1376-admin-extensions.md +0 -330
  915. package/docs/adr/adr-lite-803-request-diagnostics.md +0 -38
  916. package/docs/adr/adr-lite-808-route-readiness.md +0 -47
  917. package/docs/adr/adr-lite-809-bounded-public-content.md +0 -71
  918. package/docs/adr/adr-lite-812-native-parity.md +0 -150
  919. package/docs/adr/adr-lite-823-home-statistics.md +0 -64
  920. package/docs/adr/adr-lite-842-mcp-authoring.md +0 -30
  921. package/docs/adr/adr-lite-845-frontend-client.md +0 -38
  922. package/docs/adr/adr-lite-861-admin-webmcp.md +0 -48
  923. package/docs/adr/adr-lite-909-admin-ui-kit.md +0 -37
  924. package/docs/examples/commerce-inventory.md +0 -498
  925. package/docs/examples/commerce.md +0 -254
  926. package/docs/examples/guarded-api.md +0 -238
  927. package/docs/examples/intake-hooks.md +0 -237
  928. package/docs/examples/intake.md +0 -127
  929. package/docs/examples/legal-documents.md +0 -218
  930. package/docs/examples/procurement.md +0 -226
  931. package/docs/examples/publication.md +0 -211
  932. package/docs/examples/reference-service/.mantle/generated/mantle.ts +0 -174
  933. package/docs/examples/reference-service/.mantle/generated/plan.json +0 -1936
  934. package/docs/examples/reference-service/README.md +0 -33
  935. package/docs/examples/reference-service/manifests/catalog.yaml +0 -103
  936. package/docs/examples/reference-service/manifests/orders.yaml +0 -120
  937. package/docs/examples/reference-service/mantle.config.json +0 -1
  938. package/docs/examples/reference-service/package.json +0 -27
  939. package/docs/examples/reference-service/smoke.mjs +0 -160
  940. package/docs/examples/reference-service/src/handlers.ts +0 -36
  941. package/docs/examples/reference-service/src/index.ts +0 -33
  942. package/docs/examples/reference-service/src/service.ts +0 -78
  943. package/docs/examples/reference-service/wrangler.jsonc +0 -26
  944. package/docs/examples/reservation.md +0 -142
  945. package/docs/handbook/guides/admin-extensions.md +0 -191
  946. /package/docs/examples/{reference-service → app-shell}/.dev.vars.example +0 -0
@@ -0,0 +1,341 @@
1
+ # Internal purchase requests: employees submit, admins approve or reject, approval spends a department budget.
2
+ # requestStatus: submitted -> approved -> ordered -> confirmed, or submitted -> rejected.
3
+ apiVersion: cms.mantle.aotter.net/v2
4
+ kind: Schema
5
+ metadata: { name: budgets }
6
+ spec:
7
+ title: Budgets
8
+ lifecycle: operational
9
+ uniqueIndexes: [[department]]
10
+ # An approval that would overspend fails this check and the whole approval rolls back.
11
+ checks: ["remaining >= 0"]
12
+ uiSchema: { list: { primaryField: department, columns: [remaining] } }
13
+ schema:
14
+ type: object
15
+ additionalProperties: false
16
+ required: [department, remaining]
17
+ properties:
18
+ department: { type: string }
19
+ remaining: { type: integer }
20
+ ---
21
+ apiVersion: cms.mantle.aotter.net/v2
22
+ kind: Schema
23
+ metadata: { name: requests }
24
+ spec:
25
+ title: Purchase requests
26
+ lifecycle: operational
27
+ indexes: [[authorId, createdAt, id], [requestStatus, createdAt, id]]
28
+ # Sidebar: in the Approvals group (src/admin.tsx), after the queue of requests waiting for a decision.
29
+ uiSchema: { list: { primaryField: title, columns: [department, amount, requestStatus], filterField: requestStatus }, nav: { group: approvals, order: 2 } }
30
+ schema:
31
+ type: object
32
+ # Admin reads requests but cannot edit them generically: a generic edit could move requestStatus back to
33
+ # 'submitted' and spend the budget twice. Every change goes through the guarded Procedures below.
34
+ readOnly: true
35
+ additionalProperties: false
36
+ required: [title, amount, department, requestStatus]
37
+ properties:
38
+ title: { type: string, minLength: 1 }
39
+ amount: { type: integer, minimum: 1 }
40
+ department: { type: string }
41
+ requestStatus: { type: string, enum: [submitted, approved, rejected, ordered, confirmed] }
42
+ supplierOrderId: { type: string }
43
+ ---
44
+ apiVersion: cms.mantle.aotter.net/v2
45
+ kind: Schema
46
+ metadata: { name: ledger }
47
+ spec:
48
+ title: Budget ledger
49
+ lifecycle: operational
50
+ indexes: [[createdAt, id]]
51
+ uiSchema: { list: { primaryField: department, columns: [amount, remainingAfter, requestId] } }
52
+ schema:
53
+ type: object
54
+ readOnly: true # written only by approve-request-write
55
+ additionalProperties: false
56
+ required: [requestId, department, amount, remainingAfter]
57
+ properties:
58
+ requestId: { type: string }
59
+ department: { type: string }
60
+ amount: { type: integer }
61
+ remainingAfter: { type: integer }
62
+ ---
63
+ # Employees see only the requests they submitted.
64
+ apiVersion: cms.mantle.aotter.net/v2
65
+ kind: View
66
+ metadata: { name: my-requests }
67
+ spec:
68
+ surface: public
69
+ requires: { auth: { all: [ctx.user] } }
70
+ restrict: { requests: "author_id = auth.uid()" }
71
+ sql: |
72
+ SELECT id, title, amount, department, requestStatus AS "requestStatus", version
73
+ FROM requests ORDER BY created_at DESC, id DESC
74
+ ---
75
+ apiVersion: cms.mantle.aotter.net/v2
76
+ kind: View
77
+ metadata: { name: pending-requests }
78
+ spec:
79
+ title: Pending purchase requests
80
+ surface: admin
81
+ requires: { auth: { all: [ctx.admin] } }
82
+ uiSchema: { nav: { group: approvals, order: 1 } }
83
+ sql: |
84
+ SELECT id, title, amount, department, version
85
+ FROM requests WHERE requestStatus = 'submitted' ORDER BY created_at, id
86
+ ---
87
+ # The daily reminder reads this from src/schedule.ts; no route or tool exposes it.
88
+ apiVersion: cms.mantle.aotter.net/v2
89
+ kind: View
90
+ metadata: { name: stale-requests }
91
+ spec:
92
+ surface: internal
93
+ input:
94
+ type: object
95
+ additionalProperties: false
96
+ required: [before]
97
+ properties:
98
+ before: { type: string, format: date-time }
99
+ sql: |
100
+ SELECT id, title, amount, department FROM requests
101
+ WHERE requestStatus = 'submitted' AND created_at < input.before
102
+ ORDER BY created_at, id LIMIT 100
103
+ ---
104
+ # Approved but not yet ordered (the supplier call failed): the cron retries these.
105
+ apiVersion: cms.mantle.aotter.net/v2
106
+ kind: View
107
+ metadata: { name: approved-requests }
108
+ spec:
109
+ surface: internal
110
+ sql: |
111
+ SELECT id, title, amount FROM requests WHERE requestStatus = 'approved'
112
+ ORDER BY created_at, id LIMIT 20
113
+ ---
114
+ # Selecting from budgets refuses a department that has no budget, so approval always has a budget row to deduct.
115
+ apiVersion: cms.mantle.aotter.net/v2
116
+ kind: Procedure
117
+ metadata: { name: submit-request }
118
+ spec:
119
+ title: Submit a purchase request
120
+ requires: { auth: { all: [ctx.user] } }
121
+ input:
122
+ type: object
123
+ additionalProperties: false
124
+ required: [title, amount, department]
125
+ properties:
126
+ title: { type: string, minLength: 1 }
127
+ amount: { type: integer, minimum: 1 }
128
+ department: { type: string }
129
+ output: { type: object }
130
+ handler:
131
+ sql: |
132
+ INSERT INTO requests (title, amount, department, requestStatus)
133
+ SELECT input.title, input.amount, b.department, 'submitted' FROM budgets b WHERE b.department = input.department
134
+ RETURNING id, version
135
+ ---
136
+ # The requester may change the amount while the request is still 'submitted'. The version moves on, so an admin
137
+ # approving the version they reviewed before the change gets a 409 and looks again.
138
+ apiVersion: cms.mantle.aotter.net/v2
139
+ kind: Procedure
140
+ metadata: { name: change-amount }
141
+ spec:
142
+ title: Change the amount of my request
143
+ requires: { auth: { all: [ctx.user] } }
144
+ restrict: { requests: "author_id = auth.uid()" }
145
+ input:
146
+ type: object
147
+ additionalProperties: false
148
+ required: [id, expectedVersion, amount]
149
+ properties:
150
+ id: { type: string }
151
+ expectedVersion: { type: integer }
152
+ amount: { type: integer, minimum: 1 }
153
+ output: { type: object }
154
+ handler:
155
+ sql: |
156
+ UPDATE requests SET amount = input.amount
157
+ WHERE id = input.id AND version = input.expectedVersion AND requestStatus = 'submitted'
158
+ RETURNING id, version
159
+ ---
160
+ # Admin-only. The ref handler runs the write below, then places the supplier order and emails the requester.
161
+ apiVersion: cms.mantle.aotter.net/v2
162
+ kind: Procedure
163
+ metadata: { name: approve-request }
164
+ spec:
165
+ title: Approve a purchase request
166
+ description: Approve a submitted request; deducts the department budget, records a ledger row and places the supplier order.
167
+ requires: { auth: { all: [ctx.admin] } }
168
+ target: { schema: requests, id: id, version: expectedVersion }
169
+ input:
170
+ type: object
171
+ additionalProperties: false
172
+ required: [id, expectedVersion]
173
+ properties:
174
+ id: { type: string }
175
+ expectedVersion: { type: integer }
176
+ output: { type: object }
177
+ handler: { ref: approve-request }
178
+ ---
179
+ # One program, one transaction. Statement 1 is the guarded transition: a stale version or a request that is no longer
180
+ # 'submitted' matches 0 rows -> CONFLICT (409). Statement 2 fails remaining >= 0 when over budget. Either failure rolls
181
+ # back all three statements.
182
+ apiVersion: cms.mantle.aotter.net/v2
183
+ kind: Procedure
184
+ metadata: { name: approve-request-write }
185
+ spec:
186
+ requires: { auth: { all: [ctx.admin] } }
187
+ input:
188
+ type: object
189
+ additionalProperties: false
190
+ required: [id, expectedVersion]
191
+ properties:
192
+ id: { type: string }
193
+ expectedVersion: { type: integer }
194
+ output: { type: object }
195
+ handler:
196
+ sql: |
197
+ UPDATE requests SET requestStatus = 'approved'
198
+ WHERE id = input.id AND version = input.expectedVersion AND requestStatus = 'submitted'
199
+ RETURNING id, title, amount, author_id AS "authorId";
200
+ UPDATE budgets SET remaining = remaining - (SELECT r.amount FROM requests r WHERE r.id = input.id)
201
+ WHERE department = (SELECT r.department FROM requests r WHERE r.id = input.id);
202
+ INSERT INTO ledger (requestId, department, amount, remainingAfter)
203
+ SELECT r.id, r.department, r.amount, b.remaining FROM requests r JOIN budgets b ON b.department = r.department
204
+ WHERE r.id = input.id
205
+ ---
206
+ apiVersion: cms.mantle.aotter.net/v2
207
+ kind: Procedure
208
+ metadata: { name: reject-request }
209
+ spec:
210
+ title: Reject a purchase request
211
+ requires: { auth: { all: [ctx.admin] } }
212
+ target: { schema: requests, id: id, version: expectedVersion }
213
+ input:
214
+ type: object
215
+ additionalProperties: false
216
+ required: [id, expectedVersion]
217
+ properties:
218
+ id: { type: string }
219
+ expectedVersion: { type: integer }
220
+ output: { type: object }
221
+ handler: { ref: reject-request }
222
+ ---
223
+ apiVersion: cms.mantle.aotter.net/v2
224
+ kind: Procedure
225
+ metadata: { name: reject-request-write }
226
+ spec:
227
+ requires: { auth: { all: [ctx.admin] } }
228
+ input:
229
+ type: object
230
+ additionalProperties: false
231
+ required: [id, expectedVersion]
232
+ properties:
233
+ id: { type: string }
234
+ expectedVersion: { type: integer }
235
+ output: { type: object }
236
+ handler:
237
+ sql: |
238
+ UPDATE requests SET requestStatus = 'rejected'
239
+ WHERE id = input.id AND version = input.expectedVersion AND requestStatus = 'submitted'
240
+ RETURNING id, title, author_id AS "authorId"
241
+ ---
242
+ # Called after the supplier accepted the order: by the approve handler (admin caller) and by the cron retry (system
243
+ # caller). System callers satisfy no `requires` predicate, so it has none; no Trigger exposes it.
244
+ apiVersion: cms.mantle.aotter.net/v2
245
+ kind: Procedure
246
+ metadata: { name: mark-ordered }
247
+ spec:
248
+ input:
249
+ type: object
250
+ additionalProperties: false
251
+ required: [id, supplierOrderId]
252
+ properties:
253
+ id: { type: string }
254
+ supplierOrderId: { type: string }
255
+ output: { type: object }
256
+ handler:
257
+ sql: |
258
+ UPDATE requests SET requestStatus = 'ordered', supplierOrderId = input.supplierOrderId
259
+ WHERE id = input.id AND requestStatus = 'approved'
260
+ RETURNING id
261
+ ---
262
+ # Called only by POST /callbacks/supplier (src/routes.ts) as a system caller after the signature checks out.
263
+ # The callback can arrive before mark-ordered ran, so 'approved' is accepted too.
264
+ # No Trigger exposes it; system callers satisfy no `requires` predicate, so it has none.
265
+ apiVersion: cms.mantle.aotter.net/v2
266
+ kind: Procedure
267
+ metadata: { name: confirm-order }
268
+ spec:
269
+ input:
270
+ type: object
271
+ additionalProperties: false
272
+ required: [id, supplierOrderId]
273
+ properties:
274
+ id: { type: string }
275
+ supplierOrderId: { type: string }
276
+ output: { type: object }
277
+ handler:
278
+ sql: |
279
+ UPDATE requests SET requestStatus = 'confirmed', supplierOrderId = input.supplierOrderId
280
+ WHERE id = input.id AND (
281
+ (requestStatus = 'ordered' AND supplierOrderId = input.supplierOrderId)
282
+ OR requestStatus = 'approved')
283
+ RETURNING id
284
+ ---
285
+ apiVersion: cms.mantle.aotter.net/v2
286
+ kind: Trigger
287
+ metadata: { name: submit-request-http }
288
+ spec:
289
+ source: { kind: http, method: POST, path: /api/requests }
290
+ target: { procedure: submit-request }
291
+ ---
292
+ apiVersion: cms.mantle.aotter.net/v2
293
+ kind: Trigger
294
+ metadata: { name: change-amount-http }
295
+ spec:
296
+ source: { kind: http, method: POST, path: '/api/requests/{id}/amount' }
297
+ target: { procedure: change-amount }
298
+ ---
299
+ # Admin MCP tools: an AI agent connected to /mcp/admin can approve or reject.
300
+ apiVersion: cms.mantle.aotter.net/v2
301
+ kind: Trigger
302
+ metadata: { name: approve-request-mcp }
303
+ spec:
304
+ source: { kind: mcp, surface: admin }
305
+ target: { procedure: approve-request }
306
+ ---
307
+ apiVersion: cms.mantle.aotter.net/v2
308
+ kind: Trigger
309
+ metadata: { name: reject-request-mcp }
310
+ spec:
311
+ source: { kind: mcp, surface: admin }
312
+ target: { procedure: reject-request }
313
+ ---
314
+ # Admins open a department's budget from the Budgets list header (operational collections have no generic create);
315
+ # adjusting `remaining` later is an ordinary Admin edit.
316
+ apiVersion: cms.mantle.aotter.net/v2
317
+ kind: Procedure
318
+ metadata: { name: open-budget }
319
+ spec:
320
+ title: Open a budget
321
+ description: Give a department a purchasing budget.
322
+ requires: { auth: { all: [ctx.admin] } }
323
+ uiSchema: { collectionAction: budgets }
324
+ input:
325
+ type: object
326
+ required: [department, remaining]
327
+ additionalProperties: false
328
+ properties:
329
+ department: { type: string, minLength: 1, maxLength: 100, title: Department }
330
+ remaining: { type: integer, minimum: 0, title: Budget }
331
+ output: { type: object }
332
+ handler:
333
+ sql: |
334
+ INSERT INTO budgets (department, remaining) VALUES (input.department, input.remaining) RETURNING id
335
+ ---
336
+ apiVersion: cms.mantle.aotter.net/v2
337
+ kind: Trigger
338
+ metadata: { name: open-budget-admin }
339
+ spec:
340
+ source: { kind: mcp, surface: admin }
341
+ target: { procedure: open-budget }
@@ -0,0 +1,4 @@
1
+ -- Department budgets (whole currency units). Admins edit them in Admin > Budgets.
2
+ INSERT INTO budgets (id, created_at, updated_at, department, remaining) VALUES
3
+ ('budget-engineering', 1767225600000000, 1767225600000000, 'Engineering', 5000),
4
+ ('budget-design', 1767225600000000, 1767225600000000, 'Design', 1000);
@@ -0,0 +1,177 @@
1
+ // Purchase requests end to end: submit, guarded transitions, admin-only approve/reject (Admin + admin MCP),
2
+ // optimistic concurrency, one-transaction approval with a budget check, supplier order + signed callback, emails, cron.
3
+ import assert from "node:assert/strict";
4
+ import { createHmac } from "node:crypto";
5
+ import { createServer } from "node:http";
6
+ import { assertMcpDiscovery, smoke } from "./smoke-kit.mjs";
7
+ import { developerConsole } from "./generated/admin-descriptors.ts";
8
+
9
+ const SECRET = "local-supplier-secret", DAILY = "0 9 * * *", DAY_US = 86_400 * 1_000_000;
10
+
11
+ // A stand-in supplier API: accepts an order and answers with its order id, or 503 while `supplierDown`.
12
+ const received = [];
13
+ let supplierDown = false;
14
+ const supplier = createServer((request, response) => {
15
+ let body = "";
16
+ request.on("data", chunk => { body += chunk; });
17
+ request.on("end", () => {
18
+ if (supplierDown) return response.writeHead(503).end();
19
+ received.push({ ...JSON.parse(body), idempotencyKey: request.headers["idempotency-key"] });
20
+ response.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ orderId: `SUP-${received.length}` }));
21
+ });
22
+ });
23
+ await new Promise(resolve => supplier.listen(0, "127.0.0.1", resolve));
24
+
25
+ try {
26
+ await smoke(async ({ origin, owner, call, mcp, signIn, sql, cron, waitForLog, step, logs }) => {
27
+ const query = sql;
28
+ const row = async id => (await query(`SELECT requeststatus AS status, version, supplierorderid AS "supplierOrderId" FROM requests WHERE id = '${id}'`))[0];
29
+ const statusAndOrder = async id => { const { status, supplierOrderId } = await row(id); return { status, supplierOrderId }; };
30
+ const remaining = async department => (await query(`SELECT remaining FROM budgets WHERE department = '${department}'`))[0].remaining;
31
+ const ledgerRows = () => query("SELECT requestid AS \"requestId\", amount, remainingafter AS \"remainingAfter\" FROM ledger");
32
+ const operation = (cookie, name, body) => call("POST", `/admin/api/operations/${name}`, { cookie, body });
33
+ const signed = (payload, secret = SECRET) => {
34
+ const body = JSON.stringify(payload), timestamp = String(Math.floor(Date.now() / 1000));
35
+ const signature = createHmac("sha256", secret).update(`${timestamp}.${body}`).digest("hex");
36
+ return call("POST", "/callbacks/supplier", { body, headers: { "x-supplier-timestamp": timestamp, "x-supplier-signature": signature } });
37
+ };
38
+
39
+ const admin = await signIn(owner), alice = await signIn("alice@example.test"), bob = await signIn("bob@example.test");
40
+ const carol = await signIn("carol@example.test");
41
+ await query(`UPDATE "user" SET role = 'admin' WHERE email = 'carol@example.test'`);
42
+ assert.equal((await call("GET", "/admin/api/me", { cookie: carol })).status, 200);
43
+
44
+ const submit = async (cookie, title, amount, department) => {
45
+ const response = await call("POST", "/api/requests", { cookie, body: { title, amount, department } });
46
+ assert.equal(response.status, 200, JSON.stringify(response.body));
47
+ return response.body.results[0][0]?.id;
48
+ };
49
+ assert.equal((await call("POST", "/api/requests", { body: { title: "Pens", amount: 5, department: "Design" } })).status, 401);
50
+ const laptop = await submit(alice, "Laptop", 1200, "Engineering");
51
+ const monitors = await submit(alice, "Monitors", 1500, "Design");
52
+ const chairs = await submit(alice, "Chairs", 300, "Design");
53
+ const desk = await submit(bob, "Desk", 400, "Engineering");
54
+ const projector = await submit(bob, "Projector", 600, "Engineering");
55
+ assert.equal(await submit(bob, "Rocket", 10, "Space"), undefined);
56
+ assert.equal((await query("SELECT count(*) AS n FROM requests"))[0].n, 5);
57
+ const mine = (await call("GET", "/api/views/my-requests", { cookie: alice })).body.rows;
58
+ assert.deepEqual(mine.map(r => r.title).sort(), ["Chairs", "Laptop", "Monitors"]);
59
+ assert.deepEqual((await call("GET", "/api/views/my-requests", { cookie: bob })).body.rows.map(r => r.title).sort(), ["Desk", "Projector"]);
60
+ step("employees submit requests (unknown department creates nothing) and see only their own");
61
+
62
+ // fetch follows the 303, so an anonymous visitor ends on the sign-in page.
63
+ assert.match((await call("GET", "/requests")).body, /<h1>Sign in<\/h1>/);
64
+ assert.match((await call("GET", "/sign-in?return=%2Frequests")).body, /sign-in\/email-otp/);
65
+ const page = (await call("GET", "/requests", { cookie: bob })).body;
66
+ assert.match(page, /Projector/); assert.doesNotMatch(page, /Laptop/); assert.match(page, /<option>Design<\/option>/);
67
+ // Writes go through the REST Trigger the page's form names, never through the page itself.
68
+ assert.match(page, /<form action="\/api\/requests" method="post"/);
69
+ assert.equal((await call("POST", "/requests", { cookie: bob })).status, 404);
70
+ assert.equal((await call("POST", "/api/requests", { cookie: bob, body: { title: "Pens", amount: 0, department: "Design" } })).status, 400);
71
+ step("the /requests page sends anonymous visitors to /sign-in, lists only the employee's own requests and submits to the REST Trigger");
72
+
73
+ assert.equal((await operation(admin, "open-budget", { department: "Marketing", remaining: 500 })).status, 200);
74
+ assert.equal((await operation(admin, "open-budget", { department: "Design", remaining: 1 })).status, 409);
75
+ assert.equal(await remaining("Marketing"), 500);
76
+ assert.equal((await operation(alice, "open-budget", { department: "Ops", remaining: 1 })).status, 403);
77
+ step("admins open a department budget from the Budgets list header (open-budget; a second one for the same department is 409); employees cannot");
78
+
79
+ const version = async id => (await row(id)).version;
80
+ assert.equal((await operation(alice, "approve-request", { id: laptop, expectedVersion: await version(laptop) })).status, 403);
81
+ // Generated static metadata uses the MCP tool names; the app chooses the surface and test identity.
82
+ const declared = developerConsole.interfaces.callable;
83
+ const publicTools = await assertMcpDiscovery(`${origin}/mcp`, { headers: { cookie: alice, origin }, tools: declared.filter(tool => tool.surface === "public") });
84
+ assert.ok(!publicTools.includes("approve_request") && !publicTools.includes("reject_request"), publicTools.join());
85
+ const adminTools = await assertMcpDiscovery(`${origin}/mcp/admin`, { headers: { cookie: admin, origin }, tools: declared.filter(tool => tool.surface === "admin") });
86
+ // Denial is separate from successful initialized discovery.
87
+ assert.equal((await mcp("/mcp/admin")).status, 401);
88
+ assert.equal((await mcp("/mcp/admin", alice)).status, 403);
89
+ assert.ok(adminTools.includes("approve_request") && adminTools.includes("reject_request"), adminTools.join());
90
+ for (const hidden of ["confirm_order", "mark_ordered", "approve_request_write", "reject_request_write"])
91
+ assert.ok(!adminTools.includes(hidden) && !publicTools.includes(hidden), hidden);
92
+ step("approve/reject are admin-only: an employee gets 403 in Admin and the tools exist only on /mcp/admin");
93
+
94
+ const rejected = await mcp("/mcp/admin", admin, "reject_request", { id: chairs, expectedVersion: await version(chairs) });
95
+ assert.equal(rejected.body.result.isError, undefined, JSON.stringify(rejected.body));
96
+ assert.equal((await row(chairs)).status, "rejected");
97
+ await waitForLog(/purchasing\.rejected → alice@example\.test[\s\S]*?Rejected: Chairs/);
98
+ const guarded = await operation(admin, "approve-request", { id: chairs, expectedVersion: await version(chairs) });
99
+ assert.equal(guarded.status, 409, JSON.stringify(guarded.body));
100
+ assert.equal((await row(chairs)).status, "rejected");
101
+ step("admin MCP rejects (requester emailed); approving it with its current version is 409: WHERE requestStatus = 'submitted' matched 0 rows");
102
+
103
+ const overBudget = await operation(admin, "approve-request", { id: monitors, expectedVersion: await version(monitors) });
104
+ assert.equal(overBudget.status, 409, JSON.stringify(overBudget.body));
105
+ assert.match(overBudget.body.error.message, /budget cannot cover/);
106
+ assert.equal((await row(monitors)).status, "submitted");
107
+ assert.equal(await remaining("Design"), 1000);
108
+ assert.equal((await ledgerRows()).length, 0);
109
+ step("over budget: remaining >= 0 fails statement 2, so the status change and ledger insert roll back too");
110
+
111
+ const seen = await version(monitors); // the version the admin reviewed
112
+ const generic = await call("PATCH", `/admin/api/entries/${monitors}?collection=requests`, { cookie: admin, body: { expectedVersion: seen, data: { requestStatus: "approved" } } });
113
+ assert.ok(generic.status >= 400 && generic.status < 500, JSON.stringify(generic.body));
114
+ assert.deepEqual([(await row(monitors)).status, await version(monitors)], ["submitted", seen]);
115
+ const changeAmount = (cookie, expectedVersion) => call("POST", `/api/requests/${monitors}/amount`, { cookie, body: { expectedVersion, amount: 900 } });
116
+ assert.equal((await changeAmount(bob, seen)).status, 409);
117
+ const changed = await changeAmount(alice, seen);
118
+ assert.equal(changed.status, 200, JSON.stringify(changed.body));
119
+ assert.equal((await changeAmount(alice, seen)).status, 409);
120
+ const stale = await operation(admin, "approve-request", { id: monitors, expectedVersion: seen });
121
+ assert.equal(stale.status, 409, JSON.stringify(stale.body));
122
+ assert.equal((await row(monitors)).status, "submitted");
123
+ assert.equal(await remaining("Design"), 1000);
124
+ step("Admin cannot edit requests generically; once the requester changes the amount, approving the reviewed version is 409");
125
+
126
+ const lock = (await call("GET", "/api/views/my-requests", { cookie: alice })).body.rows.find(r => r.id === laptop).version;
127
+ const race = await Promise.all([admin, carol].map(cookie => operation(cookie, "approve-request", { id: laptop, expectedVersion: lock })));
128
+ assert.deepEqual(race.map(r => r.status).sort(), [200, 409], JSON.stringify(race.map(r => r.body)));
129
+ assert.equal(await remaining("Engineering"), 3800);
130
+ assert.deepEqual(await ledgerRows(), [{ requestId: laptop, amount: 1200, remainingAfter: 3800 }]);
131
+ step("two admins approve the same version at once: one 200, one 409; the budget and ledger change once");
132
+
133
+ assert.deepEqual(received, [{ reference: laptop, item: "Laptop", amount: 1200, idempotencyKey: laptop }]);
134
+ assert.deepEqual(await row(laptop), { status: "ordered", version: lock + 2, supplierOrderId: "SUP-1" });
135
+ await waitForLog(/purchasing\.approved → alice@example\.test[\s\S]*?Approved: Laptop/);
136
+ step("approval places the supplier order (status 'ordered') and emails the requester");
137
+
138
+ supplierDown = true;
139
+ const viaAi = await mcp("/mcp/admin", admin, "approve_request", { id: desk, expectedVersion: await version(desk) });
140
+ assert.equal(viaAi.body.result.isError, undefined, JSON.stringify(viaAi.body));
141
+ assert.equal((await operation(carol, "approve-request", { id: projector, expectedVersion: await version(projector) })).status, 200);
142
+ assert.deepEqual([(await row(desk)).status, (await row(projector)).status], ["approved", "approved"]);
143
+ assert.equal(await remaining("Engineering"), 2800);
144
+ await waitForLog(/purchasing\.approved → bob@example\.test[\s\S]*?Approved: Desk/);
145
+ step("the admin MCP tool approves too; with the supplier down, approvals still commit and stay 'approved'");
146
+
147
+ assert.equal((await signed({ reference: laptop, orderId: "SUP-1" }, "wrong-secret")).status, 401);
148
+ const tampered = await call("POST", "/callbacks/supplier", { body: JSON.stringify({ reference: laptop, orderId: "SUP-1" }),
149
+ headers: { "x-supplier-timestamp": String(Math.floor(Date.now() / 1000)), "x-supplier-signature": "0".repeat(64) } });
150
+ assert.equal(tampered.status, 401);
151
+ assert.equal((await row(laptop)).status, "ordered");
152
+ assert.equal((await signed({ reference: laptop, orderId: "SUP-9" })).status, 409);
153
+ assert.equal((await signed({ reference: laptop, orderId: "SUP-1" })).status, 204);
154
+ assert.equal((await row(laptop)).status, "confirmed");
155
+ assert.equal((await signed({ reference: laptop, orderId: "SUP-1" })).status, 204);
156
+ assert.equal((await signed({ reference: monitors, orderId: "SUP-1" })).status, 409);
157
+ // The callback can beat mark-ordered: an 'approved' request is confirmed and keeps the supplier's order id.
158
+ assert.equal((await signed({ reference: desk, orderId: "SUP-EARLY" })).status, 204);
159
+ assert.deepEqual(await statusAndOrder(desk), { status: "confirmed", supplierOrderId: "SUP-EARLY" });
160
+ step("supplier callback: bad signatures are 401 with no change; a signed one confirms (also before 'ordered'); a replay is 204; a wrong order id or a submitted request is 409");
161
+
162
+ const late = await submit(bob, "Whiteboard", 150, "Engineering");
163
+ await query(`UPDATE requests SET created_at = created_at - ${4 * DAY_US} WHERE id = '${late}'`);
164
+ const before = logs().length;
165
+ supplierDown = false;
166
+ assert.equal(await cron(DAILY), 200);
167
+ for (const to of [owner, "carol@example.test"])
168
+ await waitForLog(new RegExp(`purchasing\\.reminder → ${to.replace(/[.+]/g, "\\$&")}[\\s\\S]*?Whiteboard`));
169
+ const reminder = logs().slice(before);
170
+ assert.ok(!reminder.includes("Monitors"), "a request submitted today is not in the reminder");
171
+ assert.deepEqual(received.map(order => order.reference), [laptop, projector]);
172
+ assert.deepEqual(await statusAndOrder(projector), { status: "ordered", supplierOrderId: "SUP-2" });
173
+ step("daily cron retries the failed supplier order (system caller) and emails every admin about requests pending more than 3 days, and only those");
174
+ }, { vars: { EMPLOYEE_DOMAIN: "example.test", SUPPLIER_API_URL: `http://127.0.0.1:${supplier.address().port}/orders`, SUPPLIER_WEBHOOK_SECRET: SECRET } });
175
+ } finally {
176
+ supplier.close();
177
+ }
@@ -0,0 +1,13 @@
1
+ import { defineAdmin } from "@aotter/mantle-admin/app";
2
+ import { admin } from "../generated/admin-client.js";
3
+
4
+ /**
5
+ * The Admin entry, built by `mantle bundle`. The approver's daily work gets its own sidebar group above Admin's
6
+ * built-in ones (content 10, operations 20, reports 30; More stays last); manifests place `pending-requests` and
7
+ * `requests` in it with `uiSchema.nav`. `tsc` refuses a manifest group left undeclared here.
8
+ * AGENT: add groups for how the staff work; titles take one string or a { locale: text } map.
9
+ */
10
+ export default defineAdmin(admin, {
11
+ nav: { groups: { approvals: { title: { en: "Approvals", "zh-TW": "簽核" }, order: 5 } } },
12
+ pages: [{ path: "guide", title: "Approver guide", element: <p>Approve a request when the amount fits the budget; reject it with a reason otherwise.</p>, nav: { group: "approvals", order: 9 } }],
13
+ });
@@ -0,0 +1,33 @@
1
+ import { ContractError } from "@aotter/mantle/contracts";
2
+ import type { Handlers } from "../generated/generated.js";
3
+ import { notifyUser } from "./notify.js";
4
+ import { placeOrder } from "./supplier.js";
5
+
6
+ type Decided = { id: string; title: string; amount: number; authorId: string };
7
+
8
+ export const handlers: Handlers = {
9
+ "approve-request": async ({ store }, input) => {
10
+ let decided: Decided;
11
+ try {
12
+ // One transaction: the guarded status change, the budget deduction and the ledger row.
13
+ decided = (await store.procedures["approve-request-write"](input)).results[0]![0] as Decided;
14
+ } catch (error) {
15
+ // The declared budget check is a business refusal, not a server error. Nothing was written.
16
+ // The approval's only Schema check is the budget one.
17
+ if (error instanceof ContractError && error.code === "CONFLICT" && error.message.startsWith("A check of the Schema failed"))
18
+ throw new ContractError("CONFLICT", "The department budget cannot cover this request.", "procedures/approve-request");
19
+ throw error;
20
+ }
21
+ // After commit: nothing below may turn the committed approval into an error response.
22
+ const ordered = await placeOrder(store, decided);
23
+ await notifyUser(decided.authorId, `Approved: ${decided.title}`,
24
+ `Your purchase request "${decided.title}" was approved${ordered ? " and ordered from the supplier" : ""}.`, "purchasing.approved");
25
+ return { id: decided.id, requestStatus: ordered ? "ordered" : "approved" };
26
+ },
27
+ "reject-request": async ({ store }, input) => {
28
+ const decided = (await store.procedures["reject-request-write"](input)).results[0]![0] as Decided;
29
+ await notifyUser(decided.authorId, `Rejected: ${decided.title}`,
30
+ `Your purchase request "${decided.title}" was rejected.`, "purchasing.rejected");
31
+ return { id: decided.id, requestStatus: "rejected" };
32
+ },
33
+ };
@@ -0,0 +1,29 @@
1
+ import { ConsoleEmailSender, type EmailSender } from "@aotter/mantle/email";
2
+ import { env } from "cloudflare:workers";
3
+
4
+ // AGENT: replace with a real sender before deploying (Cloudflare `send_email` binding, docs/handbook/guides/email.md).
5
+ // ConsoleEmailSender only logs; it sends nothing.
6
+ export const sender: EmailSender = new ConsoleEmailSender();
7
+
8
+ // Recipients come from Better Auth through Mantle's server-side read (no session, no SQL on Better Auth's tables).
9
+ // Loaded lazily: Better Auth stays out of the Worker's startup graph.
10
+ const identity = async () => (await import("@aotter/mantle/auth/identity")).readIdentity((await import("./auth.js")).createAuth(env));
11
+
12
+ /** Active admins (Better Auth adminRoles / adminUserIds). */
13
+ export async function adminEmails(): Promise<string[]> {
14
+ return (await (await identity()).admins()).map(user => user.email);
15
+ }
16
+
17
+ /** Email failures never undo a decision that has already committed. */
18
+ export async function notify(to: string, subject: string, text: string, category: string) {
19
+ try { await sender.send({ to, subject, text, locale: "en", category }); }
20
+ catch (error) { console.error(`[purchasing] ${category} email failed`, error); }
21
+ }
22
+
23
+ /** Looks up the user's email and sends; a failed lookup is logged like a failed send. */
24
+ export async function notifyUser(userId: string, subject: string, text: string, category: string) {
25
+ let to: string | undefined;
26
+ try { to = (await (await identity()).user(userId))?.email; }
27
+ catch (error) { console.error(`[purchasing] ${category} recipient lookup failed`, error); }
28
+ if (to) await notify(to, subject, text, category);
29
+ }
@@ -0,0 +1,57 @@
1
+ import type { Caller } from "@aotter/mantle/contracts";
2
+ import { store } from "../generated/generated.js";
3
+ import myRequests from "../generated/paged/views/my-requests.js";
4
+ import { handlers } from "./handlers.js";
5
+ import { signInRedirect } from "./sign-in.js";
6
+
7
+ /**
8
+ * GET /requests: the employee's own page. Anonymous visitors go to /sign-in and come back.
9
+ * Reads run here as the signed-in caller (`my-requests` restricts rows to `author_id = auth.uid()`). Writes do not:
10
+ * the form submits to `POST /api/requests`, the REST Trigger the manifest declares for `submit-request`, so input
11
+ * validation, `requires` and the origin check happen there. Request data never reaches a Procedure through app code.
12
+ * AGENT: unstyled on purpose; add the app's styling, copy and a change-amount action (its own Trigger) as needed.
13
+ */
14
+ export async function requestsPage(request: Request, env: Env, caller: Caller): Promise<Response> {
15
+ if (caller.kind === "anonymous") return signInRedirect(request);
16
+ const mine = await myRequests(env.DB, caller, {}, { limit: 50 });
17
+ // Department names only; the budget amounts stay admin-side.
18
+ const budgets = await store(env.DB, { kind: "system", reason: "department list" }, { handlers }).collection("budgets").find({ limit: 100 });
19
+ return new Response(`<!doctype html>
20
+ <html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
21
+ <meta name="robots" content="noindex"><title>My purchase requests</title>
22
+ <h1>My purchase requests</h1>
23
+ <form action="/api/requests" method="post" id="new-request">
24
+ <label>What <input name="title" required></label>
25
+ <label>Amount <input name="amount" type="number" min="1" step="1" required></label>
26
+ <label>Department <select name="department" required>${budgets.rows.map(b => `<option>${escape(String(b.department))}</option>`).join("")}</select></label>
27
+ <button>Submit</button>
28
+ <p role="alert" id="error" hidden></p>
29
+ </form>
30
+ <table>
31
+ <tr><th>What</th><th>Amount</th><th>Department</th><th>Status</th></tr>
32
+ ${mine.rows.map(r => `<tr><td>${escape(String(r.title))}</td><td>${escape(String(r.amount))}</td><td>${escape(String(r.department))}</td><td>${escape(String(r.requestStatus))}</td></tr>`).join("\n ")}
33
+ </table>
34
+ <script type="module">
35
+ // The submit event fires only after the browser's own checks (required, min) pass; the Trigger checks again.
36
+ const form = document.getElementById("new-request"), error = document.getElementById("error");
37
+ form.addEventListener("submit", async event => {
38
+ event.preventDefault();
39
+ // Field types come from the inputs, so a number input sends a JSON number.
40
+ const body = Object.fromEntries([...form.elements].filter(field => field.name).map(field => [field.name, field.type === "number" ? field.valueAsNumber : field.value]));
41
+ const button = form.querySelector("button");
42
+ button.disabled = true;
43
+ try {
44
+ const response = await fetch(form.action, { method: form.method, headers: { "content-type": "application/json" }, body: JSON.stringify(body) });
45
+ if (response.ok) return location.reload(); // the page reads the list again
46
+ error.textContent = (await response.json().catch(() => null))?.error?.message ?? "Not submitted. Try again.";
47
+ } catch {
48
+ error.textContent = "Not submitted: the network is unavailable.";
49
+ }
50
+ error.hidden = false;
51
+ button.disabled = false;
52
+ });
53
+ </script>
54
+ `, { headers: { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" } });
55
+ }
56
+
57
+ const escape = (text: string) => text.replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`);