@voltro/cli 0.1.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 (626) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +57 -0
  3. package/README.md +26 -0
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +20236 -0
  6. package/bin/voltro.mjs +43 -0
  7. package/dist/bin.d.ts +1 -0
  8. package/dist/bin.js +9 -0
  9. package/dist/commands-CfPH2Wf4.js +18061 -0
  10. package/dist/frameworkInspectState-CX2250XB.js +86 -0
  11. package/dist/index.d.ts +48 -0
  12. package/dist/index.js +5 -0
  13. package/dist/inspectState.d.ts +116 -0
  14. package/dist/inspectState.js +2 -0
  15. package/dist/startup.d.ts +26 -0
  16. package/dist/startup.js +2 -0
  17. package/dist/startupRunner-CRhuUl91.js +71 -0
  18. package/package.json +88 -0
  19. package/templates/AGENTS.core.md +258 -0
  20. package/templates/AGENTS.md +351 -0
  21. package/templates/agent-docs/_index.md +93 -0
  22. package/templates/agent-docs/_manifest.json +655 -0
  23. package/templates/agent-docs/ai.md +1845 -0
  24. package/templates/agent-docs/authentication.md +1788 -0
  25. package/templates/agent-docs/caching.md +624 -0
  26. package/templates/agent-docs/cli.md +1650 -0
  27. package/templates/agent-docs/configuration.md +295 -0
  28. package/templates/agent-docs/data.md +2172 -0
  29. package/templates/agent-docs/database/advancedqueries.md +1583 -0
  30. package/templates/agent-docs/database/columntypes.md +1200 -0
  31. package/templates/agent-docs/database/hosting.md +881 -0
  32. package/templates/agent-docs/database/migrations.md +2938 -0
  33. package/templates/agent-docs/database/misc.md +270 -0
  34. package/templates/agent-docs/database/overview.md +108 -0
  35. package/templates/agent-docs/database/querying.md +1622 -0
  36. package/templates/agent-docs/database/scaling.md +331 -0
  37. package/templates/agent-docs/database/schema.md +1458 -0
  38. package/templates/agent-docs/database/seedsdialects.md +1235 -0
  39. package/templates/agent-docs/database/transactions.md +285 -0
  40. package/templates/agent-docs/deployment.md +999 -0
  41. package/templates/agent-docs/internationalization.md +359 -0
  42. package/templates/agent-docs/introduction.md +438 -0
  43. package/templates/agent-docs/multi-tenancy.md +610 -0
  44. package/templates/agent-docs/observability.md +350 -0
  45. package/templates/agent-docs/plugins.md +1273 -0
  46. package/templates/agent-docs/reference.md +978 -0
  47. package/templates/agent-docs/routing.md +1553 -0
  48. package/templates/agent-docs/scheduling.md +666 -0
  49. package/templates/agent-docs/schema-driven-ui.md +607 -0
  50. package/templates/agent-docs/security.md +42 -0
  51. package/templates/agent-docs/templates/apibackends.md +3214 -0
  52. package/templates/agent-docs/templates/appshells.md +2062 -0
  53. package/templates/agent-docs/templates/custom.md +128 -0
  54. package/templates/agent-docs/templates/overview.md +122 -0
  55. package/templates/agent-docs/templates/serverless.md +315 -0
  56. package/templates/agent-docs/testing.md +376 -0
  57. package/templates/agent-docs/workflows.md +1351 -0
  58. package/templates/apps/api-ai/README.md +105 -0
  59. package/templates/apps/api-ai/actions/summarize.action.server.tsx +32 -0
  60. package/templates/apps/api-ai/actions/summarize.action.ts +33 -0
  61. package/templates/apps/api-ai/agents/support.agent.server.tsx +31 -0
  62. package/templates/apps/api-ai/agents/support.agent.tsx +27 -0
  63. package/templates/apps/api-ai/app.config.ts +57 -0
  64. package/templates/apps/api-ai/database/schema.ts +67 -0
  65. package/templates/apps/api-ai/package.json +27 -0
  66. package/templates/apps/api-ai/seeds/docs.seed.ts +67 -0
  67. package/templates/apps/api-ai/template.json +6 -0
  68. package/templates/apps/api-ai/tests/summarize.test.ts +50 -0
  69. package/templates/apps/api-ai/tools/searchDocs.tool.tsx +60 -0
  70. package/templates/apps/api-ai/tsconfig.json +5 -0
  71. package/templates/apps/api-auth/.env +17 -0
  72. package/templates/apps/api-auth/README.md +109 -0
  73. package/templates/apps/api-auth/actions/me.action.server.ts +20 -0
  74. package/templates/apps/api-auth/actions/me.action.ts +19 -0
  75. package/templates/apps/api-auth/app.config.ts +59 -0
  76. package/templates/apps/api-auth/database/schema.ts +26 -0
  77. package/templates/apps/api-auth/package.json +28 -0
  78. package/templates/apps/api-auth/template.json +6 -0
  79. package/templates/apps/api-auth/tests/me.test.ts +37 -0
  80. package/templates/apps/api-auth/tsconfig.json +5 -0
  81. package/templates/apps/api-backend/README.md +25 -0
  82. package/templates/apps/api-backend/app.config.ts +39 -0
  83. package/templates/apps/api-backend/database/schema.ts +57 -0
  84. package/templates/apps/api-backend/mutations/notes.create.mutation.server.ts +19 -0
  85. package/templates/apps/api-backend/mutations/notes.create.mutation.ts +37 -0
  86. package/templates/apps/api-backend/package.json +28 -0
  87. package/templates/apps/api-backend/queries/notes.query.server.ts +14 -0
  88. package/templates/apps/api-backend/queries/notes.query.ts +20 -0
  89. package/templates/apps/api-backend/template.json +6 -0
  90. package/templates/apps/api-backend/tests/notes.create.test.ts +50 -0
  91. package/templates/apps/api-backend/tsconfig.json +5 -0
  92. package/templates/apps/api-backend-deactivation/README.md +49 -0
  93. package/templates/apps/api-backend-deactivation/actions/users.get.action.server.ts +17 -0
  94. package/templates/apps/api-backend-deactivation/actions/users.get.action.ts +18 -0
  95. package/templates/apps/api-backend-deactivation/app.config.ts +20 -0
  96. package/templates/apps/api-backend-deactivation/database/schema.ts +41 -0
  97. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.server.ts +6 -0
  98. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.ts +16 -0
  99. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.server.ts +10 -0
  100. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.ts +19 -0
  101. package/templates/apps/api-backend-deactivation/package.json +28 -0
  102. package/templates/apps/api-backend-deactivation/template.json +6 -0
  103. package/templates/apps/api-backend-deactivation/tests/users.deactivate.test.ts +47 -0
  104. package/templates/apps/api-backend-deactivation/tsconfig.json +5 -0
  105. package/templates/apps/api-backend-mail/README.md +39 -0
  106. package/templates/apps/api-backend-mail/actions/sendWelcome.action.server.ts +15 -0
  107. package/templates/apps/api-backend-mail/actions/sendWelcome.action.ts +21 -0
  108. package/templates/apps/api-backend-mail/app.config.ts +34 -0
  109. package/templates/apps/api-backend-mail/database/schema.ts +57 -0
  110. package/templates/apps/api-backend-mail/emails/welcome.email.tsx +106 -0
  111. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.server.ts +19 -0
  112. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.ts +37 -0
  113. package/templates/apps/api-backend-mail/package.json +30 -0
  114. package/templates/apps/api-backend-mail/queries/notes.query.server.ts +14 -0
  115. package/templates/apps/api-backend-mail/queries/notes.query.ts +20 -0
  116. package/templates/apps/api-backend-mail/template.json +6 -0
  117. package/templates/apps/api-backend-mail/tests/notes.create.test.ts +50 -0
  118. package/templates/apps/api-backend-mail/tsconfig.json +5 -0
  119. package/templates/apps/api-backend-mariadb/.env.example +35 -0
  120. package/templates/apps/api-backend-mariadb/README.md +31 -0
  121. package/templates/apps/api-backend-mariadb/app.config.ts +68 -0
  122. package/templates/apps/api-backend-mariadb/database/schema.ts +57 -0
  123. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.server.ts +19 -0
  124. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.ts +37 -0
  125. package/templates/apps/api-backend-mariadb/package.json +30 -0
  126. package/templates/apps/api-backend-mariadb/queries/notes.query.server.ts +14 -0
  127. package/templates/apps/api-backend-mariadb/queries/notes.query.ts +20 -0
  128. package/templates/apps/api-backend-mariadb/template.json +6 -0
  129. package/templates/apps/api-backend-mariadb/tests/notes.create.test.ts +50 -0
  130. package/templates/apps/api-backend-mariadb/tsconfig.json +5 -0
  131. package/templates/apps/api-backend-storage/README.md +86 -0
  132. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.server.ts +21 -0
  133. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.ts +21 -0
  134. package/templates/apps/api-backend-storage/actions/uploadDocument.action.server.ts +21 -0
  135. package/templates/apps/api-backend-storage/actions/uploadDocument.action.ts +20 -0
  136. package/templates/apps/api-backend-storage/app.config.ts +38 -0
  137. package/templates/apps/api-backend-storage/database/schema.ts +57 -0
  138. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.server.ts +19 -0
  139. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.ts +37 -0
  140. package/templates/apps/api-backend-storage/package.json +27 -0
  141. package/templates/apps/api-backend-storage/queries/notes.query.server.ts +14 -0
  142. package/templates/apps/api-backend-storage/queries/notes.query.ts +20 -0
  143. package/templates/apps/api-backend-storage/template.json +6 -0
  144. package/templates/apps/api-backend-storage/tests/notes.create.test.ts +50 -0
  145. package/templates/apps/api-backend-storage/tsconfig.json +5 -0
  146. package/templates/apps/api-data-advanced/.env +17 -0
  147. package/templates/apps/api-data-advanced/README.md +88 -0
  148. package/templates/apps/api-data-advanced/app.config.ts +56 -0
  149. package/templates/apps/api-data-advanced/database/actors.entity.ts +14 -0
  150. package/templates/apps/api-data-advanced/database/authors.entity.ts +30 -0
  151. package/templates/apps/api-data-advanced/database/authors.relations.ts +15 -0
  152. package/templates/apps/api-data-advanced/database/books.entity.ts +59 -0
  153. package/templates/apps/api-data-advanced/database/books.relations.ts +10 -0
  154. package/templates/apps/api-data-advanced/database/index.ts +23 -0
  155. package/templates/apps/api-data-advanced/database/tenants.entity.ts +11 -0
  156. package/templates/apps/api-data-advanced/package.json +28 -0
  157. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.server.ts +18 -0
  158. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.ts +40 -0
  159. package/templates/apps/api-data-advanced/queries/books.search.query.server.ts +17 -0
  160. package/templates/apps/api-data-advanced/queries/books.search.query.ts +39 -0
  161. package/templates/apps/api-data-advanced/seeds/catalog.seed.ts +101 -0
  162. package/templates/apps/api-data-advanced/template.json +6 -0
  163. package/templates/apps/api-data-advanced/tests/queries.test.ts +124 -0
  164. package/templates/apps/api-data-advanced/tsconfig.json +5 -0
  165. package/templates/apps/api-durable/README.md +81 -0
  166. package/templates/apps/api-durable/aggregates/orderStats.aggregate.ts +49 -0
  167. package/templates/apps/api-durable/app.config.ts +41 -0
  168. package/templates/apps/api-durable/database/schema.ts +65 -0
  169. package/templates/apps/api-durable/mutations/orders.approve.mutation.server.ts +43 -0
  170. package/templates/apps/api-durable/mutations/orders.approve.mutation.ts +23 -0
  171. package/templates/apps/api-durable/mutations/orders.place.mutation.server.ts +45 -0
  172. package/templates/apps/api-durable/mutations/orders.place.mutation.ts +40 -0
  173. package/templates/apps/api-durable/package.json +28 -0
  174. package/templates/apps/api-durable/schedules/nightlyReport.cron.tsx +37 -0
  175. package/templates/apps/api-durable/startup/warm.startup.tsx +33 -0
  176. package/templates/apps/api-durable/subscribers/orderChanges.subscribe.ts +27 -0
  177. package/templates/apps/api-durable/template.json +6 -0
  178. package/templates/apps/api-durable/tests/orders.place.test.ts +91 -0
  179. package/templates/apps/api-durable/triggers/order.placed.trigger.tsx +21 -0
  180. package/templates/apps/api-durable/tsconfig.json +5 -0
  181. package/templates/apps/api-durable/workflows/order.fulfill.workflow.server.tsx +103 -0
  182. package/templates/apps/api-durable/workflows/order.fulfill.workflow.tsx +25 -0
  183. package/templates/apps/api-feature-flags/README.md +63 -0
  184. package/templates/apps/api-feature-flags/actions/notes.export.action.server.ts +11 -0
  185. package/templates/apps/api-feature-flags/actions/notes.export.action.ts +18 -0
  186. package/templates/apps/api-feature-flags/app.config.ts +41 -0
  187. package/templates/apps/api-feature-flags/database/schema.ts +37 -0
  188. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.server.ts +29 -0
  189. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.ts +28 -0
  190. package/templates/apps/api-feature-flags/package.json +29 -0
  191. package/templates/apps/api-feature-flags/template.json +6 -0
  192. package/templates/apps/api-feature-flags/tests/notes.create.test.ts +67 -0
  193. package/templates/apps/api-feature-flags/tsconfig.json +5 -0
  194. package/templates/apps/api-governance/.env +4 -0
  195. package/templates/apps/api-governance/README.md +61 -0
  196. package/templates/apps/api-governance/actions/profiles.get.action.server.ts +17 -0
  197. package/templates/apps/api-governance/actions/profiles.get.action.ts +17 -0
  198. package/templates/apps/api-governance/app.config.ts +35 -0
  199. package/templates/apps/api-governance/database/schema.ts +41 -0
  200. package/templates/apps/api-governance/mutations/profiles.create.mutation.server.ts +17 -0
  201. package/templates/apps/api-governance/mutations/profiles.create.mutation.ts +21 -0
  202. package/templates/apps/api-governance/package.json +29 -0
  203. package/templates/apps/api-governance/template.json +6 -0
  204. package/templates/apps/api-governance/tests/profiles.create.test.ts +59 -0
  205. package/templates/apps/api-governance/tsconfig.json +5 -0
  206. package/templates/apps/api-kv/README.md +100 -0
  207. package/templates/apps/api-kv/actions/sync.pull.action.server.ts +75 -0
  208. package/templates/apps/api-kv/actions/sync.pull.action.ts +25 -0
  209. package/templates/apps/api-kv/actions/sync.reset.action.server.ts +25 -0
  210. package/templates/apps/api-kv/actions/sync.reset.action.ts +22 -0
  211. package/templates/apps/api-kv/actions/sync.status.action.server.ts +28 -0
  212. package/templates/apps/api-kv/actions/sync.status.action.ts +17 -0
  213. package/templates/apps/api-kv/app.config.ts +48 -0
  214. package/templates/apps/api-kv/database/schema.ts +62 -0
  215. package/templates/apps/api-kv/package.json +28 -0
  216. package/templates/apps/api-kv/queries/events.list.query.server.ts +14 -0
  217. package/templates/apps/api-kv/queries/events.list.query.ts +23 -0
  218. package/templates/apps/api-kv/template.json +6 -0
  219. package/templates/apps/api-kv/tests/sync.test.ts +103 -0
  220. package/templates/apps/api-kv/tsconfig.json +5 -0
  221. package/templates/apps/api-moderation/README.md +46 -0
  222. package/templates/apps/api-moderation/app.config.ts +33 -0
  223. package/templates/apps/api-moderation/database/schema.ts +45 -0
  224. package/templates/apps/api-moderation/mutations/comments.create.mutation.server.ts +8 -0
  225. package/templates/apps/api-moderation/mutations/comments.create.mutation.ts +20 -0
  226. package/templates/apps/api-moderation/mutations/posts.create.mutation.server.ts +9 -0
  227. package/templates/apps/api-moderation/mutations/posts.create.mutation.ts +25 -0
  228. package/templates/apps/api-moderation/package.json +29 -0
  229. package/templates/apps/api-moderation/template.json +6 -0
  230. package/templates/apps/api-moderation/tests/posts.create.test.ts +79 -0
  231. package/templates/apps/api-moderation/tsconfig.json +5 -0
  232. package/templates/apps/api-observability/README.md +106 -0
  233. package/templates/apps/api-observability/app.config.ts +32 -0
  234. package/templates/apps/api-observability/database/schema.ts +38 -0
  235. package/templates/apps/api-observability/mutations/notes.create.mutation.server.ts +33 -0
  236. package/templates/apps/api-observability/mutations/notes.create.mutation.ts +15 -0
  237. package/templates/apps/api-observability/package.json +29 -0
  238. package/templates/apps/api-observability/queries/notes.list.query.server.ts +7 -0
  239. package/templates/apps/api-observability/queries/notes.list.query.ts +14 -0
  240. package/templates/apps/api-observability/template.json +6 -0
  241. package/templates/apps/api-observability/tests/notes.create.test.ts +36 -0
  242. package/templates/apps/api-observability/tsconfig.json +5 -0
  243. package/templates/apps/api-ratelimit/README.md +49 -0
  244. package/templates/apps/api-ratelimit/app.config.ts +42 -0
  245. package/templates/apps/api-ratelimit/database/schema.ts +37 -0
  246. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.server.ts +16 -0
  247. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.ts +34 -0
  248. package/templates/apps/api-ratelimit/package.json +29 -0
  249. package/templates/apps/api-ratelimit/template.json +6 -0
  250. package/templates/apps/api-ratelimit/tests/notes.create.test.ts +69 -0
  251. package/templates/apps/api-ratelimit/tsconfig.json +5 -0
  252. package/templates/apps/api-rbac/README.md +59 -0
  253. package/templates/apps/api-rbac/app.config.ts +48 -0
  254. package/templates/apps/api-rbac/database/schema.ts +37 -0
  255. package/templates/apps/api-rbac/mutations/notes.create.mutation.server.ts +22 -0
  256. package/templates/apps/api-rbac/mutations/notes.create.mutation.ts +26 -0
  257. package/templates/apps/api-rbac/package.json +29 -0
  258. package/templates/apps/api-rbac/template.json +6 -0
  259. package/templates/apps/api-rbac/tests/notes.create.test.ts +80 -0
  260. package/templates/apps/api-rbac/tsconfig.json +5 -0
  261. package/templates/apps/api-rest/README.md +85 -0
  262. package/templates/apps/api-rest/app.config.ts +70 -0
  263. package/templates/apps/api-rest/database/schema.ts +52 -0
  264. package/templates/apps/api-rest/lib/product.ts +30 -0
  265. package/templates/apps/api-rest/package.json +27 -0
  266. package/templates/apps/api-rest/routes/v1/products.create.route.tsx +45 -0
  267. package/templates/apps/api-rest/routes/v1/products.delete.route.tsx +25 -0
  268. package/templates/apps/api-rest/routes/v1/products.get.route.tsx +29 -0
  269. package/templates/apps/api-rest/routes/v1/products.list.route.tsx +43 -0
  270. package/templates/apps/api-rest/template.json +6 -0
  271. package/templates/apps/api-rest/tests/products.create.test.ts +53 -0
  272. package/templates/apps/api-rest/tsconfig.json +5 -0
  273. package/templates/apps/api-saas/README.md +106 -0
  274. package/templates/apps/api-saas/app.config.ts +51 -0
  275. package/templates/apps/api-saas/database/schema.ts +50 -0
  276. package/templates/apps/api-saas/mutations/projects.create.mutation.server.ts +52 -0
  277. package/templates/apps/api-saas/mutations/projects.create.mutation.ts +18 -0
  278. package/templates/apps/api-saas/package.json +31 -0
  279. package/templates/apps/api-saas/queries/projects.list.query.server.ts +7 -0
  280. package/templates/apps/api-saas/queries/projects.list.query.ts +18 -0
  281. package/templates/apps/api-saas/template.json +6 -0
  282. package/templates/apps/api-saas/tests/projects.create.test.ts +47 -0
  283. package/templates/apps/api-saas/tsconfig.json +5 -0
  284. package/templates/apps/api-search/README.md +68 -0
  285. package/templates/apps/api-search/app.config.ts +31 -0
  286. package/templates/apps/api-search/database/schema.ts +47 -0
  287. package/templates/apps/api-search/lib/search.ts +27 -0
  288. package/templates/apps/api-search/mutations/articles.create.mutation.server.ts +19 -0
  289. package/templates/apps/api-search/mutations/articles.create.mutation.ts +35 -0
  290. package/templates/apps/api-search/package.json +29 -0
  291. package/templates/apps/api-search/queries/articles.list.query.server.ts +14 -0
  292. package/templates/apps/api-search/queries/articles.list.query.ts +19 -0
  293. package/templates/apps/api-search/seeds/articles.seed.ts +41 -0
  294. package/templates/apps/api-search/startup/searchBackfill.startup.tsx +24 -0
  295. package/templates/apps/api-search/template.json +6 -0
  296. package/templates/apps/api-search/tests/articles.create.test.ts +69 -0
  297. package/templates/apps/api-search/tsconfig.json +5 -0
  298. package/templates/apps/api-versioning/README.md +51 -0
  299. package/templates/apps/api-versioning/actions/documents.asOf.action.server.ts +13 -0
  300. package/templates/apps/api-versioning/actions/documents.asOf.action.ts +14 -0
  301. package/templates/apps/api-versioning/actions/documents.history.action.server.ts +15 -0
  302. package/templates/apps/api-versioning/actions/documents.history.action.ts +17 -0
  303. package/templates/apps/api-versioning/app.config.ts +24 -0
  304. package/templates/apps/api-versioning/database/schema.ts +38 -0
  305. package/templates/apps/api-versioning/mutations/documents.create.mutation.server.ts +8 -0
  306. package/templates/apps/api-versioning/mutations/documents.create.mutation.ts +21 -0
  307. package/templates/apps/api-versioning/mutations/documents.update.mutation.server.ts +9 -0
  308. package/templates/apps/api-versioning/mutations/documents.update.mutation.ts +21 -0
  309. package/templates/apps/api-versioning/package.json +29 -0
  310. package/templates/apps/api-versioning/template.json +6 -0
  311. package/templates/apps/api-versioning/tests/documents.create.test.ts +37 -0
  312. package/templates/apps/api-versioning/tsconfig.json +5 -0
  313. package/templates/apps/api-webhooks/.env +6 -0
  314. package/templates/apps/api-webhooks/README.md +106 -0
  315. package/templates/apps/api-webhooks/app.config.ts +16 -0
  316. package/templates/apps/api-webhooks/database/schema.ts +49 -0
  317. package/templates/apps/api-webhooks/events/order.completed.webhook.tsx +22 -0
  318. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.server.ts +37 -0
  319. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.ts +15 -0
  320. package/templates/apps/api-webhooks/package.json +28 -0
  321. package/templates/apps/api-webhooks/queries/orders.list.query.server.ts +7 -0
  322. package/templates/apps/api-webhooks/queries/orders.list.query.ts +15 -0
  323. package/templates/apps/api-webhooks/template.json +6 -0
  324. package/templates/apps/api-webhooks/tests/orders.fulfill.test.ts +51 -0
  325. package/templates/apps/api-webhooks/tsconfig.json +5 -0
  326. package/templates/apps/api-webhooks/webhooks/orders.webhook.tsx +35 -0
  327. package/templates/apps/changelog/README.md +77 -0
  328. package/templates/apps/changelog/app.config.ts +27 -0
  329. package/templates/apps/changelog/content/releases/0.1.0.mdx +19 -0
  330. package/templates/apps/changelog/content/releases/0.2.0.mdx +28 -0
  331. package/templates/apps/changelog/package.json +30 -0
  332. package/templates/apps/changelog/scripts/generate-rss.mjs +38 -0
  333. package/templates/apps/changelog/src/globals.css +66 -0
  334. package/templates/apps/changelog/src/globals.d.ts +16 -0
  335. package/templates/apps/changelog/src/lib/locale.test.ts +72 -0
  336. package/templates/apps/changelog/src/lib/locale.ts +55 -0
  337. package/templates/apps/changelog/src/lib/releases.ts +21 -0
  338. package/templates/apps/changelog/src/locales/de.ts +22 -0
  339. package/templates/apps/changelog/src/locales/en.ts +30 -0
  340. package/templates/apps/changelog/src/pages/[locale]/[slug].tsx +24 -0
  341. package/templates/apps/changelog/src/pages/[locale]/index.tsx +13 -0
  342. package/templates/apps/changelog/src/pages/[locale]/mirrors.test.tsx +95 -0
  343. package/templates/apps/changelog/src/pages/[slug].test.tsx +127 -0
  344. package/templates/apps/changelog/src/pages/[slug].tsx +52 -0
  345. package/templates/apps/changelog/src/pages/index.test.tsx +112 -0
  346. package/templates/apps/changelog/src/pages/index.tsx +55 -0
  347. package/templates/apps/changelog/src/pages/layout.tsx +84 -0
  348. package/templates/apps/changelog/template.json +6 -0
  349. package/templates/apps/changelog/tsconfig.json +11 -0
  350. package/templates/apps/edge-functions/README.md +55 -0
  351. package/templates/apps/edge-functions/functions/aiComplete.serverless.ts +58 -0
  352. package/templates/apps/edge-functions/functions/currencyConvert.serverless.ts +47 -0
  353. package/templates/apps/edge-functions/functions/geoGreeting.serverless.ts +44 -0
  354. package/templates/apps/edge-functions/functions/health.serverless.ts +29 -0
  355. package/templates/apps/edge-functions/functions/resolveLink.serverless.ts +32 -0
  356. package/templates/apps/edge-functions/functions/shareLink.serverless.ts +30 -0
  357. package/templates/apps/edge-functions/functions/slackNotify.serverless.ts +40 -0
  358. package/templates/apps/edge-functions/functions/verifySignature.serverless.ts +52 -0
  359. package/templates/apps/edge-functions/package.json +21 -0
  360. package/templates/apps/edge-functions/template.json +6 -0
  361. package/templates/apps/edge-functions/tsconfig.json +10 -0
  362. package/templates/apps/frontend-admin/README.md +40 -0
  363. package/templates/apps/frontend-admin/app.config.ts +37 -0
  364. package/templates/apps/frontend-admin/package.json +30 -0
  365. package/templates/apps/frontend-admin/src/config.ts +8 -0
  366. package/templates/apps/frontend-admin/src/globals.css +76 -0
  367. package/templates/apps/frontend-admin/src/globals.d.ts +6 -0
  368. package/templates/apps/frontend-admin/src/lib/admin.ts +16 -0
  369. package/templates/apps/frontend-admin/src/lib/auth.ts +24 -0
  370. package/templates/apps/frontend-admin/src/locales/de.ts +67 -0
  371. package/templates/apps/frontend-admin/src/locales/en.ts +79 -0
  372. package/templates/apps/frontend-admin/src/locales/index.ts +15 -0
  373. package/templates/apps/frontend-admin/src/pages/(marketing)/index.test.tsx +55 -0
  374. package/templates/apps/frontend-admin/src/pages/(marketing)/index.tsx +32 -0
  375. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +29 -0
  376. package/templates/apps/frontend-admin/src/pages/(marketing)/login.test.tsx +73 -0
  377. package/templates/apps/frontend-admin/src/pages/(marketing)/login.tsx +35 -0
  378. package/templates/apps/frontend-admin/src/pages/admin/[entity].tsx +121 -0
  379. package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +119 -0
  380. package/templates/apps/frontend-admin/src/pages/admin/error.tsx +20 -0
  381. package/templates/apps/frontend-admin/src/pages/admin/fallbacks.test.tsx +68 -0
  382. package/templates/apps/frontend-admin/src/pages/admin/index.test.tsx +88 -0
  383. package/templates/apps/frontend-admin/src/pages/admin/index.tsx +65 -0
  384. package/templates/apps/frontend-admin/src/pages/admin/layout.test.tsx +114 -0
  385. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +97 -0
  386. package/templates/apps/frontend-admin/src/pages/admin/loading.tsx +15 -0
  387. package/templates/apps/frontend-admin/src/pages/admin/not-found.tsx +15 -0
  388. package/templates/apps/frontend-admin/src/pages/layout.tsx +12 -0
  389. package/templates/apps/frontend-admin/src/pages/layouts.test.tsx +54 -0
  390. package/templates/apps/frontend-admin/template.json +6 -0
  391. package/templates/apps/frontend-admin/tsconfig.json +11 -0
  392. package/templates/apps/frontend-app/README.md +98 -0
  393. package/templates/apps/frontend-app/app.config.ts +43 -0
  394. package/templates/apps/frontend-app/package.json +30 -0
  395. package/templates/apps/frontend-app/src/locales/de.ts +36 -0
  396. package/templates/apps/frontend-app/src/locales/en.ts +43 -0
  397. package/templates/apps/frontend-app/src/locales/index.ts +15 -0
  398. package/templates/apps/frontend-app/src/pages/index.test.tsx +167 -0
  399. package/templates/apps/frontend-app/src/pages/index.tsx +136 -0
  400. package/templates/apps/frontend-app/src/pages/layout.tsx +41 -0
  401. package/templates/apps/frontend-app/src/pages/schema-ui.test.tsx +99 -0
  402. package/templates/apps/frontend-app/src/pages/schema-ui.tsx +74 -0
  403. package/templates/apps/frontend-app/template.json +6 -0
  404. package/templates/apps/frontend-app/tsconfig.json +11 -0
  405. package/templates/apps/frontend-blank/README.md +18 -0
  406. package/templates/apps/frontend-blank/app.config.ts +29 -0
  407. package/templates/apps/frontend-blank/package.json +29 -0
  408. package/templates/apps/frontend-blank/src/locales/de.ts +15 -0
  409. package/templates/apps/frontend-blank/src/locales/en.ts +22 -0
  410. package/templates/apps/frontend-blank/src/locales/index.ts +15 -0
  411. package/templates/apps/frontend-blank/src/pages/index.test.tsx +55 -0
  412. package/templates/apps/frontend-blank/src/pages/index.tsx +27 -0
  413. package/templates/apps/frontend-blank/src/pages/layout.test.tsx +54 -0
  414. package/templates/apps/frontend-blank/src/pages/layout.tsx +35 -0
  415. package/templates/apps/frontend-blank/template.json +6 -0
  416. package/templates/apps/frontend-blank/tsconfig.json +11 -0
  417. package/templates/apps/frontend-contact/README.md +65 -0
  418. package/templates/apps/frontend-contact/app.config.ts +25 -0
  419. package/templates/apps/frontend-contact/functions/sendMessage.serverless.ts +69 -0
  420. package/templates/apps/frontend-contact/package.json +33 -0
  421. package/templates/apps/frontend-contact/src/components/ContactForm.island.test.tsx +142 -0
  422. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +104 -0
  423. package/templates/apps/frontend-contact/src/config.ts +12 -0
  424. package/templates/apps/frontend-contact/src/globals.css +84 -0
  425. package/templates/apps/frontend-contact/src/lib/locale.ts +55 -0
  426. package/templates/apps/frontend-contact/src/locales/de.ts +26 -0
  427. package/templates/apps/frontend-contact/src/locales/en.ts +29 -0
  428. package/templates/apps/frontend-contact/src/pages/[locale]/index.tsx +14 -0
  429. package/templates/apps/frontend-contact/src/pages/index.test.tsx +70 -0
  430. package/templates/apps/frontend-contact/src/pages/index.tsx +63 -0
  431. package/templates/apps/frontend-contact/src/pages/layout.tsx +65 -0
  432. package/templates/apps/frontend-contact/template.json +6 -0
  433. package/templates/apps/frontend-contact/tsconfig.json +11 -0
  434. package/templates/apps/frontend-dashboard/README.md +54 -0
  435. package/templates/apps/frontend-dashboard/app.config.ts +39 -0
  436. package/templates/apps/frontend-dashboard/package.json +29 -0
  437. package/templates/apps/frontend-dashboard/src/config.ts +8 -0
  438. package/templates/apps/frontend-dashboard/src/globals.css +72 -0
  439. package/templates/apps/frontend-dashboard/src/globals.d.ts +6 -0
  440. package/templates/apps/frontend-dashboard/src/lib/auth.ts +27 -0
  441. package/templates/apps/frontend-dashboard/src/locales/de.ts +49 -0
  442. package/templates/apps/frontend-dashboard/src/locales/en.ts +60 -0
  443. package/templates/apps/frontend-dashboard/src/locales/index.ts +15 -0
  444. package/templates/apps/frontend-dashboard/src/pages/(marketing)/index.test.tsx +55 -0
  445. package/templates/apps/frontend-dashboard/src/pages/(marketing)/index.tsx +34 -0
  446. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +32 -0
  447. package/templates/apps/frontend-dashboard/src/pages/(marketing)/login.test.tsx +74 -0
  448. package/templates/apps/frontend-dashboard/src/pages/(marketing)/login.tsx +40 -0
  449. package/templates/apps/frontend-dashboard/src/pages/dashboard/error.tsx +21 -0
  450. package/templates/apps/frontend-dashboard/src/pages/dashboard/fallbacks.test.tsx +68 -0
  451. package/templates/apps/frontend-dashboard/src/pages/dashboard/index.test.tsx +55 -0
  452. package/templates/apps/frontend-dashboard/src/pages/dashboard/index.tsx +38 -0
  453. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.test.tsx +88 -0
  454. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +69 -0
  455. package/templates/apps/frontend-dashboard/src/pages/dashboard/loading.tsx +21 -0
  456. package/templates/apps/frontend-dashboard/src/pages/dashboard/not-found.tsx +19 -0
  457. package/templates/apps/frontend-dashboard/src/pages/dashboard/settings.test.tsx +69 -0
  458. package/templates/apps/frontend-dashboard/src/pages/dashboard/settings.tsx +35 -0
  459. package/templates/apps/frontend-dashboard/src/pages/layout.tsx +12 -0
  460. package/templates/apps/frontend-dashboard/src/pages/layouts.test.tsx +54 -0
  461. package/templates/apps/frontend-dashboard/template.json +6 -0
  462. package/templates/apps/frontend-dashboard/tsconfig.json +11 -0
  463. package/templates/apps/frontend-docs/README.md +19 -0
  464. package/templates/apps/frontend-docs/app.config.ts +25 -0
  465. package/templates/apps/frontend-docs/package.json +29 -0
  466. package/templates/apps/frontend-docs/src/globals.css +32 -0
  467. package/templates/apps/frontend-docs/src/lib/locale.test.ts +72 -0
  468. package/templates/apps/frontend-docs/src/lib/locale.ts +56 -0
  469. package/templates/apps/frontend-docs/src/locales/de.ts +24 -0
  470. package/templates/apps/frontend-docs/src/locales/en.ts +28 -0
  471. package/templates/apps/frontend-docs/src/pages/[locale]/docs/[...slug].tsx +18 -0
  472. package/templates/apps/frontend-docs/src/pages/[locale]/index.tsx +13 -0
  473. package/templates/apps/frontend-docs/src/pages/[locale]/mirrors.test.tsx +67 -0
  474. package/templates/apps/frontend-docs/src/pages/docs/[...slug].test.tsx +115 -0
  475. package/templates/apps/frontend-docs/src/pages/docs/[...slug].tsx +82 -0
  476. package/templates/apps/frontend-docs/src/pages/index.test.tsx +90 -0
  477. package/templates/apps/frontend-docs/src/pages/index.tsx +45 -0
  478. package/templates/apps/frontend-docs/src/pages/layout.test.tsx +84 -0
  479. package/templates/apps/frontend-docs/src/pages/layout.tsx +66 -0
  480. package/templates/apps/frontend-docs/template.json +6 -0
  481. package/templates/apps/frontend-docs/tsconfig.json +11 -0
  482. package/templates/apps/frontend-i18n/README.md +61 -0
  483. package/templates/apps/frontend-i18n/app.config.ts +33 -0
  484. package/templates/apps/frontend-i18n/package.json +28 -0
  485. package/templates/apps/frontend-i18n/src/globals.css +46 -0
  486. package/templates/apps/frontend-i18n/src/globals.d.ts +6 -0
  487. package/templates/apps/frontend-i18n/src/lib/locale.test.ts +72 -0
  488. package/templates/apps/frontend-i18n/src/lib/locale.ts +55 -0
  489. package/templates/apps/frontend-i18n/src/locales/de.ts +24 -0
  490. package/templates/apps/frontend-i18n/src/locales/en.ts +25 -0
  491. package/templates/apps/frontend-i18n/src/pages/[locale]/about.tsx +11 -0
  492. package/templates/apps/frontend-i18n/src/pages/[locale]/index.tsx +13 -0
  493. package/templates/apps/frontend-i18n/src/pages/[locale]/mirrors.test.tsx +50 -0
  494. package/templates/apps/frontend-i18n/src/pages/about.test.tsx +75 -0
  495. package/templates/apps/frontend-i18n/src/pages/about.tsx +31 -0
  496. package/templates/apps/frontend-i18n/src/pages/index.test.tsx +102 -0
  497. package/templates/apps/frontend-i18n/src/pages/index.tsx +43 -0
  498. package/templates/apps/frontend-i18n/src/pages/layout.test.tsx +86 -0
  499. package/templates/apps/frontend-i18n/src/pages/layout.tsx +70 -0
  500. package/templates/apps/frontend-i18n/template.json +6 -0
  501. package/templates/apps/frontend-i18n/tsconfig.json +11 -0
  502. package/templates/apps/frontend-landing/README.md +17 -0
  503. package/templates/apps/frontend-landing/app.config.ts +25 -0
  504. package/templates/apps/frontend-landing/package.json +29 -0
  505. package/templates/apps/frontend-landing/src/globals.css +23 -0
  506. package/templates/apps/frontend-landing/src/lib/locale.test.ts +72 -0
  507. package/templates/apps/frontend-landing/src/lib/locale.ts +55 -0
  508. package/templates/apps/frontend-landing/src/locales/de.ts +24 -0
  509. package/templates/apps/frontend-landing/src/locales/en.ts +26 -0
  510. package/templates/apps/frontend-landing/src/pages/[locale]/index.tsx +13 -0
  511. package/templates/apps/frontend-landing/src/pages/[locale]/mirrors.test.tsx +37 -0
  512. package/templates/apps/frontend-landing/src/pages/index.test.tsx +110 -0
  513. package/templates/apps/frontend-landing/src/pages/index.tsx +75 -0
  514. package/templates/apps/frontend-landing/src/pages/layout.test.tsx +84 -0
  515. package/templates/apps/frontend-landing/src/pages/layout.tsx +66 -0
  516. package/templates/apps/frontend-landing/template.json +6 -0
  517. package/templates/apps/frontend-landing/tsconfig.json +11 -0
  518. package/templates/apps/frontend-spa/README.md +45 -0
  519. package/templates/apps/frontend-spa/app.config.ts +27 -0
  520. package/templates/apps/frontend-spa/package.json +29 -0
  521. package/templates/apps/frontend-spa/src/globals.css +84 -0
  522. package/templates/apps/frontend-spa/src/locales/de.ts +22 -0
  523. package/templates/apps/frontend-spa/src/locales/en.ts +29 -0
  524. package/templates/apps/frontend-spa/src/locales/index.ts +15 -0
  525. package/templates/apps/frontend-spa/src/pages/index.test.tsx +137 -0
  526. package/templates/apps/frontend-spa/src/pages/index.tsx +123 -0
  527. package/templates/apps/frontend-spa/src/pages/layout.tsx +27 -0
  528. package/templates/apps/frontend-spa/template.json +6 -0
  529. package/templates/apps/frontend-spa/tsconfig.json +11 -0
  530. package/templates/apps/frontend-ssr/README.md +68 -0
  531. package/templates/apps/frontend-ssr/app.config.ts +32 -0
  532. package/templates/apps/frontend-ssr/package.json +29 -0
  533. package/templates/apps/frontend-ssr/src/globals.css +67 -0
  534. package/templates/apps/frontend-ssr/src/locales/de.ts +41 -0
  535. package/templates/apps/frontend-ssr/src/locales/en.ts +54 -0
  536. package/templates/apps/frontend-ssr/src/locales/index.ts +16 -0
  537. package/templates/apps/frontend-ssr/src/pages/feed-swr.test.tsx +69 -0
  538. package/templates/apps/frontend-ssr/src/pages/feed-swr.tsx +54 -0
  539. package/templates/apps/frontend-ssr/src/pages/feed.test.tsx +73 -0
  540. package/templates/apps/frontend-ssr/src/pages/feed.tsx +64 -0
  541. package/templates/apps/frontend-ssr/src/pages/index.test.tsx +89 -0
  542. package/templates/apps/frontend-ssr/src/pages/index.tsx +72 -0
  543. package/templates/apps/frontend-ssr/src/pages/layout.tsx +37 -0
  544. package/templates/apps/frontend-ssr/template.json +6 -0
  545. package/templates/apps/frontend-ssr/tsconfig.json +11 -0
  546. package/templates/apps/frontend-ssr-api/README.md +50 -0
  547. package/templates/apps/frontend-ssr-api/app.config.ts +43 -0
  548. package/templates/apps/frontend-ssr-api/package.json +30 -0
  549. package/templates/apps/frontend-ssr-api/src/globals.css +38 -0
  550. package/templates/apps/frontend-ssr-api/src/globals.d.ts +6 -0
  551. package/templates/apps/frontend-ssr-api/src/locales/de.ts +20 -0
  552. package/templates/apps/frontend-ssr-api/src/locales/en.ts +31 -0
  553. package/templates/apps/frontend-ssr-api/src/locales/index.ts +16 -0
  554. package/templates/apps/frontend-ssr-api/src/pages/index.test.tsx +105 -0
  555. package/templates/apps/frontend-ssr-api/src/pages/index.tsx +83 -0
  556. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +28 -0
  557. package/templates/apps/frontend-ssr-api/template.json +6 -0
  558. package/templates/apps/frontend-ssr-api/tsconfig.json +11 -0
  559. package/templates/apps/frontend-static-blog/README.md +49 -0
  560. package/templates/apps/frontend-static-blog/app.config.ts +34 -0
  561. package/templates/apps/frontend-static-blog/package.json +28 -0
  562. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.test.tsx +65 -0
  563. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +35 -0
  564. package/templates/apps/frontend-static-blog/src/content/posts.ts +64 -0
  565. package/templates/apps/frontend-static-blog/src/globals.css +75 -0
  566. package/templates/apps/frontend-static-blog/src/lib/locale.test.ts +72 -0
  567. package/templates/apps/frontend-static-blog/src/lib/locale.ts +55 -0
  568. package/templates/apps/frontend-static-blog/src/locales/de.ts +19 -0
  569. package/templates/apps/frontend-static-blog/src/locales/en.ts +26 -0
  570. package/templates/apps/frontend-static-blog/src/pages/[locale]/blog/[slug].tsx +20 -0
  571. package/templates/apps/frontend-static-blog/src/pages/[locale]/index.tsx +13 -0
  572. package/templates/apps/frontend-static-blog/src/pages/[locale]/mirrors.test.tsx +62 -0
  573. package/templates/apps/frontend-static-blog/src/pages/blog/[slug].test.tsx +116 -0
  574. package/templates/apps/frontend-static-blog/src/pages/blog/[slug].tsx +69 -0
  575. package/templates/apps/frontend-static-blog/src/pages/index.test.tsx +100 -0
  576. package/templates/apps/frontend-static-blog/src/pages/index.tsx +58 -0
  577. package/templates/apps/frontend-static-blog/src/pages/layout.tsx +63 -0
  578. package/templates/apps/frontend-static-blog/template.json +6 -0
  579. package/templates/apps/frontend-static-blog/tsconfig.json +11 -0
  580. package/templates/baselines/bare/.env.example +37 -0
  581. package/templates/baselines/bare/README.md +47 -0
  582. package/templates/baselines/bare/baseline.json +31 -0
  583. package/templates/baselines/bare/deploy/README.md +43 -0
  584. package/templates/baselines/bare/deploy/voltro.service.example +36 -0
  585. package/templates/baselines/compose/.env.example +46 -0
  586. package/templates/baselines/compose/README.md +69 -0
  587. package/templates/baselines/compose/baseline.json +51 -0
  588. package/templates/baselines/compose/docker/.dockerignore +38 -0
  589. package/templates/baselines/compose/docker/api.Dockerfile +57 -0
  590. package/templates/baselines/compose/docker/dev.Dockerfile +35 -0
  591. package/templates/baselines/compose/docker/web.Dockerfile +59 -0
  592. package/templates/baselines/compose/docker-compose.dev.yml +89 -0
  593. package/templates/baselines/compose/docker-compose.prod.yml +87 -0
  594. package/templates/baselines/compose/docker-compose.yml +41 -0
  595. package/templates/baselines/compose-mariadb/.env.example +57 -0
  596. package/templates/baselines/compose-mariadb/README.md +78 -0
  597. package/templates/baselines/compose-mariadb/baseline.json +51 -0
  598. package/templates/baselines/compose-mariadb/docker/.dockerignore +38 -0
  599. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +57 -0
  600. package/templates/baselines/compose-mariadb/docker/dev.Dockerfile +35 -0
  601. package/templates/baselines/compose-mariadb/docker/mariadb-init.sql +6 -0
  602. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +59 -0
  603. package/templates/baselines/compose-mariadb/docker-compose.dev.yml +117 -0
  604. package/templates/baselines/compose-mariadb/docker-compose.prod.yml +114 -0
  605. package/templates/baselines/compose-mariadb/docker-compose.yml +79 -0
  606. package/templates/baselines/helm/.env.example +39 -0
  607. package/templates/baselines/helm/README.md +98 -0
  608. package/templates/baselines/helm/baseline.json +53 -0
  609. package/templates/baselines/helm/charts/voltro-app/.helmignore +10 -0
  610. package/templates/baselines/helm/charts/voltro-app/Chart.yaml +10 -0
  611. package/templates/baselines/helm/charts/voltro-app/templates/_helpers.tpl +36 -0
  612. package/templates/baselines/helm/charts/voltro-app/templates/configmap.yaml +13 -0
  613. package/templates/baselines/helm/charts/voltro-app/templates/deployment-api.yaml +120 -0
  614. package/templates/baselines/helm/charts/voltro-app/templates/deployment-web.yaml +45 -0
  615. package/templates/baselines/helm/charts/voltro-app/templates/ingress.yaml +37 -0
  616. package/templates/baselines/helm/charts/voltro-app/templates/postgres-service.yaml +19 -0
  617. package/templates/baselines/helm/charts/voltro-app/templates/postgres-statefulset.yaml +73 -0
  618. package/templates/baselines/helm/charts/voltro-app/templates/secret.yaml +33 -0
  619. package/templates/baselines/helm/charts/voltro-app/templates/service-api.yaml +19 -0
  620. package/templates/baselines/helm/charts/voltro-app/templates/service-web.yaml +19 -0
  621. package/templates/baselines/helm/charts/voltro-app/values-dev.yaml +21 -0
  622. package/templates/baselines/helm/charts/voltro-app/values-prod.yaml +58 -0
  623. package/templates/baselines/helm/charts/voltro-app/values-staging.yaml +25 -0
  624. package/templates/baselines/helm/charts/voltro-app/values.yaml +109 -0
  625. package/templates/baselines/helm/deploy/README.md +94 -0
  626. package/templates/patches/@effect__cluster@0.59.0.patch +262 -0
@@ -0,0 +1,978 @@
1
+ # Reference
2
+
3
+ > The client-side hook surface, grouped by purpose.
4
+
5
+
6
+
7
+ ---
8
+
9
+ <!-- source: en/reference/hooks-overview.md -->
10
+ ## React hooks — overview
11
+
12
+ _The client-side hook surface, grouped by purpose._
13
+
14
+ The web side of a Voltro app talks to API apps through React hooks. Data hooks are keyed by API name and RPC tag; routing hooks are provided by `@voltro/web`.
15
+
16
+ ## Data Hooks
17
+
18
+ | Hook | Purpose |
19
+ |---|---|
20
+ | [`useSubscription`](/docs/reference/hooks-data) | Subscribe to a reactive query (`*.query.ts`). |
21
+ | [`useMutation`](/docs/reference/hooks-data) | Run an atomic write (`*.mutation.ts`). |
22
+ | [`useAction`](/docs/reference/hooks-data) | Run a unary non-transactional action (`*.action.ts`). |
23
+ | [`useWorkflow`](/docs/reference/hooks-data) | Start, cancel, resume, or signal a durable workflow (`*.workflow.tsx`). |
24
+ | [`useWorkflowRun`](/docs/reference/hooks-data) | Subscribe to one workflow run's reactive status row. |
25
+ | [`useWorkflowRuns`](/docs/reference/hooks-data) | Subscribe to a bounded/filterable workflow run list. |
26
+ | [`useWorkflowRunSteps`](/docs/reference/hooks-data) | Subscribe to one run's checkpointed step timeline. |
27
+ | [`useWorkflowRunEvents`](/docs/reference/hooks-data) | Subscribe to one run's lifecycle/timer/signal event timeline. |
28
+ | [`useAgentStream`](/docs/reference/hooks-data) | Consume a one-shot element stream (`*.stream.ts`). |
29
+ | [`useAgent`](/docs/reference/hooks-data) | Convenience wrapper for transient AI streams. |
30
+
31
+ ## Routing Hooks
32
+
33
+ | Hook | Purpose |
34
+ |---|---|
35
+ | [`useLocation`](/docs/reference/hooks-routing) | Current pathname and route state. |
36
+ | [`useParams`](/docs/reference/hooks-routing) | URL params from `[name]` segments. |
37
+ | [`useNavigate`](/docs/reference/hooks-routing) | Programmatic navigation. |
38
+ | [`usePrefetch`](/docs/reference/hooks-routing) | Trigger loader-data prefetch. |
39
+ | [`useLoaderData`](/docs/reference/hooks-routing) | Page loader output. |
40
+
41
+ ## Server / Context Hooks
42
+
43
+ | Hook | Purpose |
44
+ |---|---|
45
+ | [`useServerRequest`](/docs/reference/hooks-server) | Request snapshot during SSR and hydration-sensitive client code. |
46
+
47
+ ## Where To Read Next
48
+
49
+ - [Data hooks](/docs/reference/hooks-data)
50
+ - [Routing hooks](/docs/reference/hooks-routing)
51
+ - [Server hooks](/docs/reference/hooks-server)
52
+ - [Runtime context](/docs/reference/runtime-context)
53
+
54
+
55
+
56
+ ---
57
+
58
+ <!-- source: en/reference/hooks-data.md -->
59
+ ## Data hooks
60
+
61
+ _useSubscription, useMutation, useAction, useWorkflow, workflow status hooks, useAgentStream, and useAgent._
62
+
63
+ Data hooks from `@voltro/client` are keyed by **api name** plus **RPC tag**. The tags come from descriptors discovered in the API app.
64
+
65
+ ## `useSubscription(apiName, rpcTag, input?, options?)`
66
+
67
+ Subscribes to a reactive `defineQuery` RPC.
68
+
69
+ ```tsx
70
+ const { data, error, revision, pendingPatches } = useSubscription(
71
+ 'app',
72
+ 'notes.list',
73
+ { archived: false },
74
+ )
75
+ ```
76
+
77
+ Returns:
78
+
79
+ | Field | Meaning |
80
+ |---|---|
81
+ | `data` | Latest typed query output, or `undefined` before the first snapshot. |
82
+ | `error` | Subscription setup error, if no snapshot could be delivered. |
83
+ | `revision` | Server revision counter. |
84
+ | `emittedAt` | Timestamp for the latest server delta. |
85
+ | `pendingPatches` | Number of active optimistic patches applied to this cache entry. |
86
+
87
+ Use `{ skip }` to defer until inputs are ready:
88
+
89
+ ```tsx
90
+ const { data } = useSubscription(
91
+ 'app',
92
+ 'messages.list',
93
+ { channelId },
94
+ { skip: channelId === undefined },
95
+ )
96
+ ```
97
+
98
+ ## `useMutation(apiName, rpcTag)`
99
+
100
+ Calls a `defineMutation` RPC.
101
+
102
+ ```tsx
103
+ const create = useMutation<{ title: string }, { id: string }>('app', 'notes.create')
104
+
105
+ await create.mutate({ title: 'Hello' })
106
+ ```
107
+
108
+ Returns:
109
+
110
+ | Field | Meaning |
111
+ |---|---|
112
+ | `mutate(input)` | Calls the mutation and resolves the typed output. |
113
+ | `pending` | `true` while a call is in flight. |
114
+ | `error` | Last failure, or `undefined`. |
115
+ | `data` | Last successful result, or `undefined`. |
116
+ | `withOptimistic(fn)` | Override descriptor-derived optimistic patches. |
117
+ | `withoutOptimistic()` | Disable optimistic patches for this mutation handle. |
118
+
119
+ Custom optimistic example:
120
+
121
+ ```tsx
122
+ const create = useMutation('app', 'notes.create').withOptimistic((cache, input) => {
123
+ cache.forTag<ReadonlyArray<{ id: string; title: string }>>('notes.list', (rows) => [
124
+ { id: `temp:${Date.now()}`, title: String(input.title) },
125
+ ...rows,
126
+ ])
127
+ })
128
+ ```
129
+
130
+ ## `useAction(apiName, rpcTag)`
131
+
132
+ Calls a `defineAction` RPC. Actions are unary like mutations, but the client has no optimistic/cache surface for them.
133
+
134
+ ```tsx
135
+ const invite = useAction<{ email: string }, { ok: boolean }>('app', 'invites.send')
136
+
137
+ await invite.run({ email })
138
+ ```
139
+
140
+ Returns `run`, `pending`, `error`, and `lastResult`.
141
+
142
+ ## `useWorkflow(apiName, workflowName)`
143
+
144
+ Starts and controls a discovered `*.workflow.tsx`. Starting returns a `WorkflowRunHandle` immediately; it does not wait for the workflow's success payload.
145
+
146
+ ```tsx
147
+ const summarise = useWorkflow<{ noteId: string }>('app', 'notes.summarise')
148
+
149
+ const run = await summarise.start({ noteId })
150
+ ```
151
+
152
+ `voltro codegen` also emits workflow type maps from your `*.workflow.tsx`
153
+ definitions:
154
+
155
+ ```tsx
156
+ import type {
157
+ WorkflowMessages,
158
+ WorkflowPayloads,
159
+ WorkflowResults,
160
+ } from '@app/api/rpcGroup.generated'
161
+
162
+ const summarise = useWorkflow<
163
+ WorkflowPayloads['notes.summarise'],
164
+ WorkflowMessages['notes.summarise']
165
+ >('app', 'notes.summarise')
166
+
167
+ type SummaryResult = WorkflowResults['notes.summarise']
168
+ ```
169
+
170
+ Returns:
171
+
172
+ | Field | Meaning |
173
+ |---|---|
174
+ | `start(payload)` | Starts the durable workflow and resolves a run handle. |
175
+ | `cancel({ workflowName, executionId })` | Cancels a running execution. |
176
+ | `resume({ workflowName, executionId })` | Resumes a suspended execution. |
177
+ | `signal({ id }, signalName, payload?)` | Sends an external signal to a run id or execution id. |
178
+ | `update({ id }, updateName, payload?, options?)` | Sends a tracked update and resolves with the workflow handler result. |
179
+ | `pending` | `true` while `start(...)` is in flight. |
180
+ | `error` | Last start failure, or `undefined`. |
181
+ | `data` | Last returned run handle, or `undefined`. |
182
+
183
+ ## `useWorkflowSignal(apiName)`
184
+
185
+ Focused helper for signal buttons and approval forms that do not also start workflows:
186
+
187
+ ```tsx
188
+ const signal = useWorkflowSignal('app')
189
+
190
+ await signal.signal({ id: runId }, 'approval', { approved: true })
191
+ ```
192
+
193
+ It returns `signal(...)`, `pending`, `error`, and the last `{ eventId }`.
194
+
195
+ ## `useWorkflowUpdate(apiName)`
196
+
197
+ Focused helper for tracked workflow updates. Unlike signals, updates wait for the workflow's `awaitUpdate(...)` handler to validate and return a result:
198
+
199
+ ```tsx
200
+ const approve = useWorkflowUpdate('app')
201
+
202
+ const result = await approve.update(
203
+ { id: runId },
204
+ 'approve',
205
+ { decision: true },
206
+ { timeoutMs: 30_000 },
207
+ )
208
+ ```
209
+
210
+ It returns `update(...)`, `pending`, `error`, and the last `{ eventId, updateId, completedEventId, result }`.
211
+
212
+ ## `useWorkflowRun(apiName, id)`
213
+
214
+ Subscribes to Voltro's built-in reactive workflow-run query. `id` can be the durable `executionId` returned by `useWorkflow().start(...)` or the `_voltro_workflow_runs.id` from inspection data.
215
+
216
+ ```tsx
217
+ const { run, data, error } = useWorkflowRun('app', runId)
218
+ ```
219
+
220
+ `run` is the first row from the built-in query. It updates through the normal reactivity engine as `_voltro_workflow_runs` changes, so workflow status UIs do not need polling.
221
+
222
+ ## `useWorkflowRuns(apiName, filters?, options?)`
223
+
224
+ Subscribes to a bounded workflow-run list:
225
+
226
+ ```tsx
227
+ const { runs } = useWorkflowRuns('app', {
228
+ tag: 'notes.summarise',
229
+ status: 'running',
230
+ limit: 25,
231
+ })
232
+ ```
233
+
234
+ Filters are optional. `limit` defaults to `100` and is capped by the server, so app-level job centers do not accidentally subscribe to the entire run history.
235
+
236
+ ## `useWorkflowRunSteps(apiName, runId)`
237
+
238
+ Subscribes to the step timeline for one `_voltro_workflow_runs.id`:
239
+
240
+ ```tsx
241
+ const { steps } = useWorkflowRunSteps('app', liveRun?.id)
242
+ ```
243
+
244
+ Step rows update reactively as checkpointed `step({...})` activities start, succeed, or fail.
245
+
246
+ ## `useWorkflowRunEvents(apiName, runId)`
247
+
248
+ Subscribes to the event timeline for one `_voltro_workflow_runs.id`:
249
+
250
+ ```tsx
251
+ const { events } = useWorkflowRunEvents('app', liveRun?.id)
252
+ ```
253
+
254
+ Events include lifecycle changes, timers, signals, and updates recorded by the workflow runtime.
255
+
256
+ `useWorkflowEvents(apiName, runId)` is a shorter alias for the same hook.
257
+
258
+ ## `useAgentStream(apiName, rpcTag)`
259
+
260
+ Consumes a `defineStream` RPC. Despite the name, this hook is not limited to AI agents; it handles any one-shot element stream.
261
+
262
+ ```tsx
263
+ const ticker = useAgentStream<{ price: number }>('app', 'ticker.watch')
264
+
265
+ ticker.start({ symbol: 'BTC' })
266
+ ticker.cancel()
267
+ ```
268
+
269
+ Returns:
270
+
271
+ | Field | Meaning |
272
+ |---|---|
273
+ | `events` | Elements received so far, in order. |
274
+ | `status` | `'idle'`, `'streaming'`, `'done'`, or `'error'`. |
275
+ | `error` | Failure when `status === 'error'`. |
276
+ | `start(input?)` | Starts a new run and clears old events. |
277
+ | `cancel()` | Interrupts the in-flight run. |
278
+
279
+ ## `useAgent(apiName, rpcTag)`
280
+
281
+ Ergonomic wrapper over `useAgentStream` for transient AI chat streams. It derives `tokens` from token events and folds completed turns into `history`.
282
+
283
+ ```tsx
284
+ const support = useAgent('app', 'support.run')
285
+
286
+ support.send({ message: 'Help me', history: support.history })
287
+ support.cancel()
288
+ ```
289
+
290
+ For durable chat generated by `defineAgent`, use the normal pair: `useSubscription('app', '<name>.messages', input)` plus `useAction('app', '<name>.send')`.
291
+
292
+ ## Connection Lifecycle
293
+
294
+ All hooks share the API WebSocket. Query subscriptions resubscribe after reconnect and get fresh snapshots. In-flight unary calls reject on disconnect. In-flight streams end with an error and must be started again.
295
+
296
+ ## See Also
297
+
298
+ - [Queries](/docs/data/queries)
299
+ - [Mutations](/docs/data/mutations)
300
+ - [Actions](/docs/data/actions)
301
+ - [Streams](/docs/data/streams)
302
+ - [Workflows](/docs/workflows/overview)
303
+
304
+
305
+
306
+ ---
307
+
308
+ <!-- source: en/reference/hooks-routing.md -->
309
+ ## Routing hooks
310
+
311
+ _useLocation, useParams, useNavigate, usePrefetch, useLoaderData — navigating + reading URL state._
312
+
313
+ The routing hooks from `@voltro/web`. They read URL state, trigger navigation, and access loader data.
314
+
315
+ ## `useLocation()`
316
+
317
+ The current pathname (just the path; query string is separate).
318
+
319
+ ```ts
320
+ import { useLocation } from '@voltro/web'
321
+
322
+ const pathname = useLocation()
323
+ // '/docs/intro/getting-started'
324
+ ```
325
+
326
+ Updates on every navigation. Use for:
327
+
328
+ - Active-link styling
329
+ - "Did the URL change?" effect dependencies
330
+ - Conditional rendering based on path
331
+
332
+ ```tsx
333
+ const Nav = () => {
334
+ const pathname = useLocation()
335
+ return (
336
+ <ul>
337
+ <li><Link to="/" className={pathname === '/' ? 'active' : ''}>Home</Link></li>
338
+ <li><Link to="/about" className={pathname === '/about' ? 'active' : ''}>About</Link></li>
339
+ </ul>
340
+ )
341
+ }
342
+ ```
343
+
344
+ For "active if URL starts with prefix":
345
+
346
+ ```tsx
347
+ className={pathname.startsWith('/dashboard') ? 'active' : ''}
348
+ ```
349
+
350
+ ## `useParams<T>()`
351
+
352
+ URL params from `[name]` segments. Typed via the generic.
353
+
354
+ ```tsx
355
+ // src/pages/users/[id].tsx
356
+ import { useParams } from '@voltro/web'
357
+
358
+ const { id } = useParams<{ id: string }>()
359
+ ```
360
+
361
+ For catch-all queries:
362
+
363
+ ```tsx
364
+ // src/pages/docs/[...slug].tsx
365
+ const { slug } = useParams<{ slug: string }>()
366
+ // /docs/intro/getting-started → slug = "intro/getting-started"
367
+ ```
368
+
369
+ For multi-segment dynamic paths:
370
+
371
+ ```tsx
372
+ // src/pages/orgs/[orgId]/projects/[projectId].tsx
373
+ const { orgId, projectId } = useParams<{ orgId: string; projectId: string }>()
374
+ ```
375
+
376
+ Params are always strings — convert numbers explicitly:
377
+
378
+ ```ts
379
+ const id = Number(params.id)
380
+ if (Number.isNaN(id)) throw new NotFoundError()
381
+ ```
382
+
383
+ ## `useNavigate()`
384
+
385
+ Programmatic navigation.
386
+
387
+ ```tsx
388
+ import { useNavigate } from '@voltro/web'
389
+
390
+ const SignOutButton = () => {
391
+ const navigate = useNavigate()
392
+ const onSignOut = async () => {
393
+ await fetch('/auth/signout', { method: 'POST' })
394
+ navigate('/login')
395
+ }
396
+ return <button onClick={onSignOut}>Sign out</button>
397
+ }
398
+ ```
399
+
400
+ Returns a function `(to: string, options?) => void`.
401
+
402
+ | Option | Notes |
403
+ |---|---|
404
+ | `replace: true` | Replace the history entry (no back-button entry). |
405
+ | `scroll: false` | Don't scroll to top after navigation. |
406
+
407
+ `navigate` takes a path string only — there is no numeric history overload. For back / forward, reach for the browser API:
408
+
409
+ ```ts
410
+ window.history.back() // back
411
+ window.history.forward() // forward
412
+ ```
413
+
414
+ ## `useBlocker()`
415
+
416
+ Hold a pending navigation so you can prompt before the user leaves — the unsaved-changes guard.
417
+
418
+ ```tsx
419
+ import { useBlocker } from '@voltro/web'
420
+
421
+ const blocker = useBlocker(form.isDirty) // boolean or a predicate
422
+ // …
423
+ {blocker.blocked && (
424
+ <ConfirmDialog onConfirm={blocker.retry} onCancel={blocker.reset} />
425
+ )}
426
+ ```
427
+
428
+ Pass `true`/`false` or a predicate `({ to, opts }) => boolean` (to allow some destinations). When a navigation is held, the hook returns `{ blocked: true, to, retry, reset }`: `retry()` proceeds, `reset()` cancels. A full-page unload also triggers the browser's native prompt while any blocker is active. See [Navigation](/docs/routing/navigation) for the full example.
429
+
430
+ ## `useSearchParams()` + `useSetSearchParams()`
431
+
432
+ Read the query string as a `URLSearchParams` (SSR-aware — the request URL on the server, `window.location.search` on the client):
433
+
434
+ ```tsx
435
+ import { useSearchParams } from '@voltro/web'
436
+
437
+ const tab = useSearchParams().get('tab') ?? 'overview'
438
+ ```
439
+
440
+ Write it with `useSetSearchParams()` — the setter updates the query via `navigate`, so readers re-render immediately:
441
+
442
+ ```tsx
443
+ import { useSetSearchParams } from '@voltro/web'
444
+
445
+ const setParams = useSetSearchParams()
446
+ setParams({ tab: 'members' }) // set (default: replace)
447
+ setParams((p) => { p.set('page', '2'); return p }) // patch one param
448
+ setParams({ page: '2' }, { push: true }) // distinct history entry
449
+ ```
450
+
451
+ Writes default to a history replace; pass `{ push: true }` for a Back entry or `{ scroll: false }` to keep scroll. See [Navigation](/docs/routing/navigation#reading--writing-search-params).
452
+
453
+ ## `usePrefetch()`
454
+
455
+ Trigger loader-data prefetch on hover / focus. Wired automatically by `<Link prefetch />`; export only useful for custom triggers.
456
+
457
+ ```tsx
458
+ import { usePrefetch } from '@voltro/web'
459
+
460
+ const Card = ({ id }) => {
461
+ const prefetch = usePrefetch()
462
+ return (
463
+ <article onMouseEnter={() => prefetch(`/notes/${id}`)}>
464
+ {/* …card body, no Link inside */}
465
+ </article>
466
+ )
467
+ }
468
+ ```
469
+
470
+ Idempotent — multiple calls for the same path fire one loader. The prefetched result is held in the loader cache until it's consumed by the actual navigation (or invalidated on an error reset).
471
+
472
+ ## `useLoaderData<T>()`
473
+
474
+ Page's loader output, typed.
475
+
476
+ ```tsx
477
+ // src/pages/notes/[id].tsx
478
+ import { useLoaderData } from '@voltro/web'
479
+
480
+ interface Note {
481
+ id: string
482
+ title: string
483
+ }
484
+
485
+ export const loader = async ({ params }): Promise<Note> => {
486
+ return await fetchNote(params.id)
487
+ }
488
+
489
+ export default function NotePage(): ReactNode {
490
+ const note = useLoaderData<Note>()
491
+ return <article><h1>{note.title}</h1></article>
492
+ }
493
+ ```
494
+
495
+ Available in:
496
+
497
+ - The page component itself
498
+ - Any layout in the page's chain
499
+ - Any descendant of the layout
500
+
501
+ Returns `null` on pages without a `loader`. The generic narrows the type.
502
+
503
+ See [Loaders & meta](/docs/routing/loaders-and-meta) for the server-side counterpart.
504
+
505
+ ## Compositions
506
+
507
+ ```tsx
508
+ // "go to next page after a delay"
509
+ const navigate = useNavigate()
510
+ useEffect(() => {
511
+ const t = setTimeout(() => navigate('/welcome'), 3000)
512
+ return () => clearTimeout(t)
513
+ }, [navigate])
514
+ ```
515
+
516
+ ```tsx
517
+ // "save the URL the user came from for after-signin redirect"
518
+ const pathname = useLocation()
519
+ const fromUrl = useMemo(() => pathname, []) // capture at mount, not every render
520
+ ```
521
+
522
+ ```tsx
523
+ // "active link with hover-prefetch"
524
+ const Link = ({ to, children }) => {
525
+ const pathname = useLocation()
526
+ const prefetch = usePrefetch()
527
+ const active = pathname === to
528
+ return (
529
+ <a
530
+ href={to}
531
+ onMouseEnter={() => prefetch(to)}
532
+ className={active ? 'active' : ''}
533
+ >
534
+ {children}
535
+ </a>
536
+ )
537
+ }
538
+ // (You don't usually write this — `<Link>` from `@voltro/web` does it all.)
539
+ ```
540
+
541
+ ## Anti-patterns
542
+
543
+ - **`window.location.href = '/foo'` for internal nav.** Full reload — defeats the SPA. Use `useNavigate`.
544
+ - **Reading `params` outside the page tree.** Layouts above the page CAN read params (they share the chain), but components imported as siblings can't. Pass params down explicitly.
545
+ - **`useEffect(() => navigate(...), [])` for default redirects.** Triggers a flash of the original page. Do redirects in the LOADER instead (`throw new RedirectError(...)`).
546
+
547
+ ## See also
548
+
549
+ - [Navigation](/docs/routing/navigation) — `<Link>` + prefetch patterns
550
+ - [Loaders & meta](/docs/routing/loaders-and-meta) — what populates `useLoaderData`
551
+
552
+
553
+
554
+ ---
555
+
556
+ <!-- source: en/reference/hooks-server.md -->
557
+ ## Server hooks
558
+
559
+ _useServerRequest — the SSR-only escape hatch for reading cookies, headers, and the URL during render._
560
+
561
+ The only true "server hook" in Voltro is `useServerRequest`. It exposes the request snapshot during SSR so layouts + pages can read cookies, headers, and the URL during the render pass.
562
+
563
+ ## `useServerRequest()`
564
+
565
+ ```tsx
566
+ import { useServerRequest } from '@voltro/web'
567
+
568
+ const req = useServerRequest()
569
+ // req is { cookies, headers, url } on the server, null on the client
570
+ ```
571
+
572
+ Returns:
573
+
574
+ ```ts
575
+ interface ServerRequest {
576
+ readonly cookies: Readonly<Record<string, string>>
577
+ readonly headers: Readonly<Record<string, string>>
578
+ readonly url: string // includes query string
579
+ }
580
+ ```
581
+
582
+ Or `null` on the client (after hydration).
583
+
584
+ ## What it's for
585
+
586
+ The classic use case: decode the session cookie during SSR so the layout renders the right subject-aware UI:
587
+
588
+ ```tsx
589
+ // src/pages/layout.tsx
590
+ import { useServerRequest } from '@voltro/web'
591
+ import { SubjectProvider } from '@voltro/plugin-auth/web'
592
+ import { decodeSubjectFromRequest } from './lib/auth'
593
+
594
+ export default function Layout({ children }) {
595
+ const req = useServerRequest()
596
+ const subject = decodeSubjectFromRequest(req)
597
+ return <SubjectProvider subject={subject}>{children}</SubjectProvider>
598
+ }
599
+ ```
600
+
601
+ `decodeSubjectFromRequest` is app code (it knows the cookie name + how to verify the signature). The hook just hands you the cookies.
602
+
603
+ ## Reading query params
604
+
605
+ For SSR pages that need to parse the URL's query string:
606
+
607
+ ```tsx
608
+ import { useSearchParams } from '@voltro/web'
609
+
610
+ export const renderMode = 'ssr' as const
611
+
612
+ export default function SearchPage() {
613
+ // Native `URLSearchParams`, resolved server-side from the SSR request
614
+ // URL (correct in the first paint) and from `window.location.search`
615
+ // on the client — same call site on both sides.
616
+ const q = useSearchParams().get('q') ?? ''
617
+ const results = q ? searchDocs(q) : []
618
+ return /* … */
619
+ }
620
+ ```
621
+
622
+ `useSearchParams()` returns the request's query as a native `URLSearchParams`. SPA pages
623
+ that must react to router-pushed query changes without a reload re-render through the router
624
+ (`useNavigate`/`useLocation`); the hook then re-resolves on that render.
625
+
626
+ ## Reading cookies
627
+
628
+ ```ts
629
+ const req = useServerRequest()
630
+ const sessionCookie = req?.cookies['voltro:session']
631
+ ```
632
+
633
+ `cookies` is already parsed — no manual `Cookie:` header splitting needed.
634
+
635
+ ## Reading headers
636
+
637
+ ```ts
638
+ const req = useServerRequest()
639
+ const userAgent = req?.headers['user-agent']
640
+ const tenant = req?.headers['x-tenant']
641
+ ```
642
+
643
+ Headers are lower-cased keys. Multi-value headers are joined with `, `.
644
+
645
+ ## Conditional rendering by SSR vs client
646
+
647
+ ```tsx
648
+ const req = useServerRequest()
649
+ if (req) {
650
+ // SSR — req available
651
+ } else {
652
+ // Post-hydration — read browser-side equivalents
653
+ const ua = navigator.userAgent
654
+ }
655
+ ```
656
+
657
+ For values that need to flow from SSR to client (cookie-derived subject, locale), serialise them via `SubjectProvider`-style context. The client doesn't re-read cookies — it inherits what the SSR pass decoded.
658
+
659
+ ## What it's NOT for
660
+
661
+ - **Reading database state.** Use a `loader` — it runs server-side too, but with a typed `params` + abort signal + a clear server/client divide.
662
+ - **Triggering side effects during render.** React's render must be pure. For SSR side effects (logging a request), use middleware in `app.config.ts.runtime`.
663
+ - **Client-side cookie reading.** The session cookie is `HttpOnly` — JS can't read it. The server decoded it during SSR + handed you the subject; that's what the client sees.
664
+
665
+ ## Mounting check pattern
666
+
667
+ ```tsx
668
+ const req = useServerRequest()
669
+ const isSSR = req !== null
670
+
671
+ return (
672
+ <div>
673
+ {isSSR ? <ServerOnlyBranch /> : <ClientOnlyBranch />}
674
+ </div>
675
+ )
676
+ ```
677
+
678
+ Use sparingly — divergent SSR / client rendering causes hydration mismatches. The cleaner pattern is `useEffect(() => setHydrated(true), [])` + render the same JSX in both paths.
679
+
680
+ ## See also
681
+
682
+ - [Loaders & meta](/docs/routing/loaders-and-meta) — server-side data fetch (preferred for data)
683
+ - [Authentication / React](/docs/authentication/react) — `SubjectProvider` pattern
684
+ - [Wire protocol](/docs/data/wire-protocol) — the server's view of the request
685
+
686
+
687
+
688
+ ---
689
+
690
+ <!-- source: en/reference/runtime-context.md -->
691
+ ## Runtime context
692
+
693
+ _The `AppContext` passed to server executors._
694
+
695
+ Every server executor receives an `AppContext` as its second argument:
696
+
697
+ ```ts
698
+ import type { AppContext } from '@voltro/runtime'
699
+
700
+ export default async (input: Input, ctx: AppContext) => {
701
+ const subject = ctx.request.subject
702
+ const rows = await ctx.store.query(/* ... */)
703
+ }
704
+ ```
705
+
706
+ Query, mutation, action, stream, and workflow files export both descriptor metadata and the default executor. The default executor receives `ctx`; descriptor objects stay data-only and browser-safe.
707
+
708
+ ## `ctx.request`
709
+
710
+ Per-call runtime metadata:
711
+
712
+ ```ts
713
+ ctx.request.subject // user, apiKey, system, or anonymous subject
714
+ ctx.request.traceId // trace id shared with client/server spans
715
+ ctx.request.spanId // current span id when tracing is active
716
+ ctx.request.clientId // WebSocket connection id for RPC calls
717
+ ```
718
+
719
+ Most auth and tenant checks read `ctx.request.subject`:
720
+
721
+ ```ts
722
+ const tenantId = ctx.request.subject.tenantId
723
+ if (ctx.request.subject.id == null) throw new Error('sign-in required')
724
+ ```
725
+
726
+ ## `ctx.store`
727
+
728
+ The typed mutation store. It applies schema mixin behavior for `audit()`, `tenant()`, and `softDelete()` where configured.
729
+
730
+ ```ts
731
+ await ctx.store.insert('notes', { title: 'Hello' })
732
+ await ctx.store.update('notes', noteId, { title: 'Updated' })
733
+ await ctx.store.delete('notes', noteId)
734
+
735
+ const rows = await ctx.store.query(database.notes.descriptor)
736
+ ```
737
+
738
+ Mutations receive a transactional store view. Actions and streams receive a normal store view; writes from them are not automatically rolled back as one unit.
739
+
740
+ ## `ctx.cache`
741
+
742
+ Async cache facade for request handlers:
743
+
744
+ ```ts
745
+ const value = await ctx.cache.wrap(
746
+ `summary:${id}`,
747
+ { ttlMs: 60_000, tags: ['notes'] },
748
+ () => computeSummary(id),
749
+ )
750
+
751
+ await ctx.cache.invalidateTag('notes')
752
+ ```
753
+
754
+ Mutation `target` metadata can invalidate matching tagged cache entries automatically.
755
+
756
+ ## `ctx.kv`
757
+
758
+ Durable key-value facade — always present, and unlike `ctx.cache` its entries are **never evicted for capacity** (they live until deleted or their TTL lapses). Use it for state you can't recompute; the default backend on a sql app is the database, so values survive restarts.
759
+
760
+ ```ts
761
+ const state = await ctx.kv.getOrElse(`onboarding:${userId}`, () => ({ step: 0 }))
762
+ await ctx.kv.set(`onboarding:${userId}`, { step: state.step + 1 })
763
+ ```
764
+
765
+ `get` / `getOrElse` / `set` (optional `{ ttlMs }`) / `delete` / `has` / `list(prefix)` / `clear`. See **[Durable key-value](/docs/caching/key-value)**.
766
+
767
+ ## `ctx.webhooks`
768
+
769
+ Present only when the webhooks plugin is configured. Plugin-specific packages expose typed helpers for their optional context slots; the core runtime keeps the slot structurally typed so apps do not pay for unused plugins.
770
+
771
+ ## `ctx.workflows`
772
+
773
+ Present when the API app has discovered workflows. It starts durable work and controls existing runs:
774
+
775
+ ```ts
776
+ const run = await ctx.workflows.start('notes.summarise', { noteId })
777
+ await ctx.workflows.signal({ id: run.id }, 'approval', { approved: true })
778
+ const approval = await ctx.workflows.update({ id: run.id }, 'approve', { decision: true })
779
+ const latest = await ctx.workflows.query('notes.summarise', run.executionId)
780
+ const snapshot = await ctx.workflows.wait('notes.summarise', run.executionId)
781
+ ```
782
+
783
+ Use `signal(...)` for fire-and-forget external events. Use `update(...)` when the caller needs a tracked result from the workflow's `awaitUpdate(...)` handler.
784
+
785
+ Inside a mutation, `ctx.workflows.start(...)` queues the actual launch until after the transaction commits. If the mutation rolls back, the workflow is not started. `ctx.workflows.run(...)` and `start(..., { wait: true })` are intentionally rejected inside mutation transactions.
786
+
787
+ Workflow starts record their start source (`workflow-rpc`, `app-context`, `schedule:<name>`, `incoming:<id>`, or `inspect`). Request-backed starts also carry the current request trace, and authenticated request starts carry the resolved subject into the run context. Keep authorization-critical tenant/user ids in the workflow payload so resumed work stays deterministic.
788
+
789
+ ## Effect Services
790
+
791
+ Server executors may return `Effect`s. Actions and streams receive the base platform layer, including `HttpClient`. AI helpers are imported from `@voltro/ai`:
792
+
793
+ ```ts
794
+ import { generateText } from '@voltro/ai'
795
+ import { Effect } from 'effect'
796
+
797
+ export default (input: { prompt: string }) =>
798
+ Effect.gen(function* () {
799
+ const { text } = yield* generateText({ prompt: input.prompt })
800
+ return { text }
801
+ })
802
+ ```
803
+
804
+ ## Context By Primitive
805
+
806
+ | Server file | Transaction | Typical store usage | External I/O | Returns |
807
+ |---|---|---|---|---|
808
+ | `*.query.server.ts` | No | Read/query | Avoid | Query descriptor or computed value |
809
+ | `*.mutation.server.ts` | Yes | Atomic writes | Avoid | Unary output |
810
+ | `*.action.server.ts` | No | Optional, non-atomic | Yes | Unary output |
811
+ | `*.stream.server.ts` | No | Optional, non-atomic | Yes | `Stream`, `Effect<Stream>`, or `Promise<Stream>` |
812
+ | `*.workflow.tsx` | Step-specific | Durable reads/writes | Yes, inside activities | Workflow result |
813
+
814
+ Use mutations for atomic state changes, actions for one-shot side effects, streams for progressive element output, and workflows for durable multi-step work.
815
+
816
+
817
+
818
+ ---
819
+
820
+ <!-- source: en/reference/startup.md -->
821
+ ## Startup hooks
822
+
823
+ _"*.startup.tsx — run code once when the app boots: warm a cache, open a long-lived connection, start a background consumer. Default-export a function; register teardown via onShutdown."_
824
+
825
+ A **startup hook** runs code once when the app boots — after migrations, once the rpc server is listening. Use it for the long-lived, app-singleton work that doesn't fit any request-driven primitive: warm a cache, open a persistent connection (a message-broker consumer, a websocket to an upstream), start a background interval, or register a process-wide service.
826
+
827
+ A `*.startup.tsx` (or `*.startup.ts`) file **default-exports a function** — there's no `define*` wrapper:
828
+
829
+ ```tsx
830
+ // startup/warmCache.startup.ts
831
+ import type { StartupContext } from '@voltro/runtime'
832
+
833
+ export default async ({ store, log, onShutdown, id }: StartupContext) => {
834
+ log.info('warming the dashboard cache')
835
+ const timer = setInterval(() => void refreshDashboardCache(store), 60_000)
836
+
837
+ // Register teardown — runs on SIGTERM / SIGINT, LIFO across all startups.
838
+ onShutdown(() => clearInterval(timer))
839
+ }
840
+ ```
841
+
842
+ Discovery walks every `*.startup.tsx`; the `default` export must be a function. Multiple startups in one app are fine — each gets its own scope and is torn down independently.
843
+
844
+ ## The context
845
+
846
+ ```ts
847
+ interface StartupContext {
848
+ readonly store: DataStore // already-migrated
849
+ readonly log: SyncLogger // scope=startup:<id>
850
+ readonly onShutdown: (cb: () => void | Promise<void>) => void // register teardown
851
+ readonly id: string // basename without .startup.tsx
852
+ }
853
+ ```
854
+
855
+ - **`store`** is the same framework `DataStore` handlers use — already migrated by the time the hook runs.
856
+ - **`log`** is scoped to the file's basename, so `voltro logs --filter startup:<id>` isolates a hook's output.
857
+ - **`onShutdown(cb)`** registers a teardown callback. On `SIGTERM` / `SIGINT` the framework runs every registered callback in **reverse** order (LIFO), awaiting each — with a hard 5s timeout per callback so a hung teardown can't block shutdown. Always release what you acquire here.
858
+ - **`id`** is the stable basename (no `.startup.tsx`), handy for keys / log scoping.
859
+
860
+ ## Lifecycle
861
+
862
+ - **Runs once, at boot** — after the schema is migrated and the rpc server is listening. A throw/rejection is logged and does NOT block boot; the rpc surface stays up regardless.
863
+ - **Long-lived** — the function may hold sockets, intervals, or a fiber that resolves only on shutdown. That's the point — startups are for persistent process-wide work, unlike [seeds](/docs/database/seeds) which run once and return.
864
+ - **Torn down cleanly** — every `onShutdown` callback fires on process exit (LIFO), so connections and timers release without leaking across supervisor restarts.
865
+
866
+ ## When to use it vs the alternatives
867
+
868
+ | Need | Use |
869
+ |---|---|
870
+ | Seed rows once at boot, then return | [`*.seed.ts`](/docs/database/seeds) |
871
+ | Hold a long-lived connection / interval / background consumer for the process lifetime | `*.startup.tsx` (this) |
872
+ | React to every commit on a table | [`*.subscribe.ts`](/docs/data/subscribers) |
873
+ | Periodic work on a cron schedule | [`*.cron.tsx`](/docs/scheduling/overview) |
874
+ | Durable, crash-surviving multi-step work | [`*.workflow.tsx`](/docs/workflows/overview) |
875
+
876
+ If the work is "do X once and finish", it's a seed. If it's "keep X running until the process stops", it's a startup.
877
+
878
+
879
+
880
+ ---
881
+
882
+ <!-- source: en/reference/templates.md -->
883
+ ## App templates
884
+
885
+ _The scaffolding catalogue — every api / web / serverless template, what it demonstrates, and when to pick it._
886
+
887
+ Every template is a dogfooded, runnable reference. Scaffold one with
888
+ `voltro create-project --api <id> --web <id>` (or `voltro add-app <name>
889
+ --template <id>`), and run `voltro list-templates` for the live list.
890
+
891
+ Templates come in **three kinds**, matching the three things you deploy:
892
+
893
+ - **`api`** — a long-running backend (`app.config` `type: 'api'`).
894
+ - **`web`** — a frontend (`type: 'web'`); gets a dev-server port.
895
+ - **`serverless`** — a bundle of standalone [`*.serverless.ts`
896
+ functions](/docs/deployment/serverless-functions) shipped on their own with
897
+ `voltro serverless`. No long-running server, no port — add it to a project
898
+ with `voltro add-app`.
899
+
900
+ ## API backends (`kind: api`)
901
+
902
+ | Template | What you get |
903
+ |---|---|
904
+ | `api-backend` | The minimal base: `app.config` + a `*.entity.ts` schema + one streaming query + one mutation. Tenant-aware out of the box. Start here. |
905
+ | `api-backend-mail` | `api-backend` + [`@voltro/plugin-mail`](/docs/plugins/mail) and a React-Email welcome template you preview/send from the dashboard. |
906
+ | `api-backend-storage` | `api-backend` + [`@voltro/plugin-storage`](/docs/plugins/storage): public (CDN-direct) + private (policy + per-object grants) objects, with upload examples. |
907
+ | `api-backend-mariadb` | MariaDB-backed: binlog CDC real-time, file storage, tenant-aware schema — the shape for K8s multi-replica apps. |
908
+ | [`api-durable`](/docs/templates/api-durable) | The whole durable + reactive surface in one order-fulfillment domain: a workflow (`step`/`sleep`/`awaitSignal`), an event trigger, a cron schedule, a table subscriber, a materialized aggregate, and a startup hook. |
909
+ | [`api-ai`](/docs/templates/api-ai) | A RAG support agent: a `vectorEmbedding()` docs table, a search tool, a real `defineAgent`/`defineAgentExecutor` model loop, and a `generateObject` action. |
910
+ | [`api-data-advanced`](/docs/templates/api-data-advanced) | The advanced schema DSL: `*.entity.ts`/`*.relations.ts` split + eager `.with()`, full-text search, `dbEnum`, array/generated/encrypted columns, and declarative query caching. |
911
+ | [`api-auth`](/docs/templates/api-auth) | Real user auth — `@voltro/plugin-auth` turnkey: password sign-up/in/out over HttpOnly session cookies + a strategy resolving the session to a typed Subject. Zero-infra boot. |
912
+ | [`api-rest`](/docs/templates/api-rest) | Public REST API — `defineRestRoute` (query/path/body, scope guards, Idempotency-Key) + `@voltro/plugin-openapi` (OpenAPI 3.1 spec + Swagger UI at `/docs`). Zero-infra boot. |
913
+ | [`api-saas`](/docs/templates/api-saas) | The SaaS plugin bundle — billing entitlements + notifications + analytics + presence, wired turnkey; one `projects.create` exercises three together. Zero-infra boot. |
914
+ | [`api-observability`](/docs/templates/api-observability) | Production-readiness — Prometheus `/metrics` + a custom counter, Sentry (inert without a DSN), tracing, and a `@voltro/testing` unit test (`voltro test`). Zero-infra boot. |
915
+ | [`api-webhooks`](/docs/templates/api-webhooks) | First-class webhooks both ways — a signature-verified incoming `*.webhook.tsx` receiver + an outgoing `defineOutgoingEvent` emitted via a durable signed delivery workflow. Zero-infra boot. |
916
+
917
+ ## Web frontends (`kind: web`)
918
+
919
+ | Template | Render mode | What it demonstrates |
920
+ |---|---|---|
921
+ | `frontend-blank` | — | Empty React + layout shell + one page. The blank canvas. |
922
+ | [`frontend-app`](/docs/templates/app) | `full` · reactive | **The reactive end-to-end loop** — a web frontend wired to an api (`useSubscription` + `useMutation` + auto-optimistic). The only fullstack template; pairs with `api-backend`. |
923
+ | `frontend-landing` | `static` · `interactive: 'none'` | Marketing page that ships **zero JS** on the wire. |
924
+ | `frontend-static-blog` | `static` + `islands` | **SSG from a content source**: dynamic `[slug]` routes pre-rendered via `getStaticPaths`, per-post `meta` from loader data, and ONE island (reading-progress bar) showing selective hydration. |
925
+ | `frontend-spa` | `spa` | A **pure client-rendered** tool — state lives in the browser (`localStorage`), so there's nothing to SSR. Shows where a single-page app is the right call. |
926
+ | `frontend-ssr` | `ssr` + `isr` | **Server-rendered pages**: a per-request SSR page (`useServerRequest()` for cookies/headers) + ISR pages (`revalidate`, `staleWhileRevalidate`, tenant-aware caching). Needs a runtime (`voltro start`), not a CDN. Self-contained; swap the loader for `ctx.query` to read from your api. |
927
+ | `frontend-contact` | `static` + serverless | **Static page + a serverless email form** (see combos below). |
928
+ | `frontend-docs` | `static` (catch-all SSG) | Docs site: `docs/[...slug].tsx`, per-section layout, URL-prefix i18n. |
929
+ | `changelog` | `static` | Release-notes site: MDX in `content/releases/`, rendered list + per-release pages, RSS feed. |
930
+
931
+ ## Serverless functions (`kind: serverless`)
932
+
933
+ | Template | What you get |
934
+ |---|---|
935
+ | `edge-functions` | A **library of `*.serverless.ts` functions** covering the range of what edge functions do — pure compute, request-header/geo, outbound HTTP (fire-and-forget + fetch-and-transform), Web Crypto HMAC verify, an LLM call, and status-controlled errors. Run with `voltro serverless dev`, ship to node / Cloudflare / Scaleway. |
936
+
937
+ ## Static + serverless combos
938
+
939
+ The most common shape for a no-always-on-server product: **a static page on a
940
+ CDN + a serverless function for the one dynamic bit.** Two templates show it:
941
+
942
+ - **`frontend-contact`** — a static marketing page whose contact form (an
943
+ island) POSTs to `functions/sendMessage.serverless.ts`, which sends mail via
944
+ Resend. The page ships to a CDN; the function scales to zero. The function's
945
+ local dev server sends CORS headers (same as the edge hosts), so the
946
+ cross-origin form works out of the box.
947
+ - **`edge-functions` + any static web template** — add the function library to
948
+ a project that also has a `frontend-static-blog` or `frontend-landing`, and
949
+ wire the page to whichever function it needs.
950
+
951
+ ```bash
952
+ # Scaffold the combo:
953
+ voltro create-project acme --web frontend-contact --no-input
954
+ # → apps/acme/contact/ (static page + functions/sendMessage.serverless.ts)
955
+
956
+ # Run both halves locally (two terminals):
957
+ pnpm --filter @acme/contact dev # the static site
958
+ pnpm --filter @acme/contact fn:dev # the serverless function on :8910
959
+ ```
960
+
961
+ ## Picking a template
962
+
963
+ | You want… | Start with |
964
+ |---|---|
965
+ | A reactive backend (queries/mutations/workflows) | `api-backend` (+ `-mail` / `-storage` for those features) |
966
+ | A marketing / brochure site | `frontend-landing` |
967
+ | A blog or content site generated at build time | `frontend-static-blog` |
968
+ | A heavily-interactive tool with no backend | `frontend-spa` |
969
+ | Server-rendered pages (per-request SSR, or cached + revalidated ISR) | `frontend-ssr` |
970
+ | A static site that needs ONE dynamic endpoint (email, webhook, …) | `frontend-contact` |
971
+ | Docs | `frontend-docs` |
972
+ | Standalone functions to deploy to the edge | `edge-functions` |
973
+
974
+ ## See also
975
+
976
+ - [Scaffolding](/docs/cli/scaffolding) — the `create-project` / `add-app` / `list-templates` commands + writing your own template
977
+ - [Serverless functions](/docs/deployment/serverless-functions) — the `*.serverless.ts` model + deploy targets
978
+ - [Static-site deploy](/docs/deployment/static-sites) — shipping a web template's `dist/` to a CDN