@starci/hfs 4.2.17 → 4.4.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 (564) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +7 -0
  3. package/db/migrate.mjs +361 -0
  4. package/db/post-cutover.mjs +136 -0
  5. package/emit/db-types.mjs +10 -1
  6. package/lint/run.mjs +1 -1
  7. package/package.json +4 -1
  8. package/release/gate.mjs +298 -0
  9. package/release/index.mjs +103 -0
  10. package/release/push.mjs +110 -0
  11. package/runtime/knowledge/hfs/canon-pins.yaml +11 -11
  12. package/runtime/knowledge/hfs/fe-stack.yaml +22 -1
  13. package/runtime/knowledge/hfs/rules.yaml +3437 -160
  14. package/runtime/knowledge/hfs/slots.yaml +430 -92
  15. package/runtime/knowledge/patterns/be/api.yaml +92 -2
  16. package/runtime/knowledge/patterns/be/cli.yaml +37 -9
  17. package/runtime/knowledge/patterns/be/event-bus.yaml +3 -3
  18. package/runtime/knowledge/patterns/be/jobs.yaml +20 -2
  19. package/runtime/knowledge/patterns/be/projections.yaml +4 -2
  20. package/runtime/knowledge/patterns/be/queues.yaml +11 -3
  21. package/runtime/knowledge/patterns/be/reactors.yaml +20 -1
  22. package/runtime/knowledge/patterns/be/realtime.yaml +25 -3
  23. package/runtime/knowledge/patterns/be/saga.yaml +20 -3
  24. package/runtime/knowledge/patterns/be/webhooks.yaml +210 -36
  25. package/runtime/knowledge/patterns/fe/folder.yaml +4 -0
  26. package/runtime/knowledge/sonar-gate.yaml +1 -1
  27. package/runtime/modules/kernel/failure-codes.yaml +3128 -47
  28. package/runtime/modules/models/runtimes.yaml +1 -1
  29. package/runtime/modules/schemas/application-stacks.schema.yaml +663 -0
  30. package/runtime/packages/cli/src/catalog.generated.mjs +14104 -0
  31. package/runtime/packages/cli/src/validate-args.mjs +213 -0
  32. package/runtime/scripts/api/git/add.mjs +5 -0
  33. package/runtime/scripts/api/git/cat-file.mjs +5 -0
  34. package/runtime/scripts/api/git/init.mjs +7 -0
  35. package/runtime/scripts/api/git/lib.mjs +3 -0
  36. package/runtime/scripts/api/git/tag.mjs +5 -0
  37. package/runtime/scripts/api/node/lib.mjs +20 -0
  38. package/runtime/scripts/api/node/run-node.mjs +6 -0
  39. package/runtime/scripts/api/sops/lib.mjs +41 -0
  40. package/runtime/scripts/api/sops/resolve-sops.mjs +7 -0
  41. package/runtime/scripts/api/sops/seal.mjs +1 -1
  42. package/runtime/scripts/api/sops/selected-age-recipient.mjs +7 -0
  43. package/runtime/scripts/api/supabase/database-dump.mjs +5 -0
  44. package/runtime/scripts/api/supabase/database-query.mjs +5 -0
  45. package/runtime/scripts/api/supabase/lib.mjs +44 -0
  46. package/runtime/scripts/api/supabase/migration-repair.mjs +5 -0
  47. package/runtime/scripts/hfs/app-wiring.mjs +201 -0
  48. package/runtime/scripts/hfs/architecture/backend-app-files.mjs +103 -0
  49. package/runtime/scripts/hfs/architecture/backend.mjs +22 -10
  50. package/runtime/scripts/hfs/architecture/background-unowned.mjs +157 -41
  51. package/runtime/scripts/hfs/architecture/canon-clones.mjs +240 -0
  52. package/runtime/scripts/hfs/architecture/canon-jsx-clones.mjs +143 -0
  53. package/runtime/scripts/hfs/architecture/client-reaches-server.mjs +6 -3
  54. package/runtime/scripts/hfs/architecture/clones.mjs +17 -8
  55. package/runtime/scripts/hfs/architecture/connection-map.mjs +14 -12
  56. package/runtime/scripts/hfs/architecture/context-map.mjs +25 -14
  57. package/runtime/scripts/hfs/architecture/context-owner.mjs +1 -2
  58. package/runtime/scripts/hfs/architecture/dead-exports-bindings.mjs +149 -0
  59. package/runtime/scripts/hfs/architecture/dead-exports.mjs +23 -50
  60. package/runtime/scripts/hfs/architecture/default-deny.mjs +8 -6
  61. package/runtime/scripts/hfs/architecture/frontend-block-render.mjs +104 -0
  62. package/runtime/scripts/hfs/architecture/frontend-world-render.mjs +30 -11
  63. package/runtime/scripts/hfs/architecture/frontend-world.mjs +1 -1
  64. package/runtime/scripts/hfs/architecture/function-spec-providers.mjs +153 -0
  65. package/runtime/scripts/hfs/architecture/hfs.mjs +3 -3
  66. package/runtime/scripts/hfs/architecture/i18n-keys.mjs +16 -3
  67. package/runtime/scripts/hfs/architecture/machine-ast.mjs +17 -0
  68. package/runtime/scripts/hfs/architecture/module-per-transport.mjs +49 -25
  69. package/runtime/scripts/hfs/architecture/next-data-inference.mjs +176 -0
  70. package/runtime/scripts/hfs/architecture/next-data-symbols.mjs +26 -0
  71. package/runtime/scripts/hfs/architecture/next-data.mjs +31 -23
  72. package/runtime/scripts/hfs/architecture/reachability.mjs +14 -0
  73. package/runtime/scripts/hfs/architecture/register-once.mjs +15 -7
  74. package/runtime/scripts/hfs/architecture/required-files.mjs +2 -1
  75. package/runtime/scripts/hfs/architecture/source-names.mjs +48 -3
  76. package/runtime/scripts/hfs/architecture/staged-consumers.mjs +37 -0
  77. package/runtime/scripts/hfs/architecture/supabase-ast.mjs +214 -17
  78. package/runtime/scripts/hfs/architecture/supabase-be.mjs +1 -6
  79. package/runtime/scripts/hfs/architecture/supabase.mjs +59 -21
  80. package/runtime/scripts/hfs/architecture/surface.mjs +2 -1
  81. package/runtime/scripts/hfs/architecture/tiers.mjs +11 -4
  82. package/runtime/scripts/hfs/architecture/typescript.mjs +1 -8
  83. package/runtime/scripts/hfs/architecture/unit-spec-providers.mjs +9 -13
  84. package/runtime/scripts/hfs/check-results.mjs +28 -0
  85. package/runtime/scripts/hfs/check.mjs +63 -72
  86. package/runtime/scripts/hfs/coverage-from.mjs +70 -0
  87. package/runtime/scripts/hfs/db-baseline-verb.mjs +276 -0
  88. package/runtime/scripts/hfs/db-plan-verb.mjs +254 -0
  89. package/runtime/scripts/hfs/db-restamp-verb.mjs +60 -0
  90. package/runtime/scripts/hfs/declaration-shape.mjs +39 -3
  91. package/runtime/scripts/hfs/doc-commands.mjs +367 -0
  92. package/runtime/scripts/hfs/edition-slots.mjs +2 -2
  93. package/runtime/scripts/hfs/example-secrets.mjs +158 -0
  94. package/runtime/scripts/hfs/manifest-shape.mjs +91 -6
  95. package/runtime/scripts/hfs/path-findings.mjs +32 -2
  96. package/runtime/scripts/hfs/refusal-codes.mjs +6 -0
  97. package/runtime/scripts/hfs/rule-catalog.mjs +156 -11
  98. package/runtime/scripts/hfs/rule-params-shape.mjs +22 -10
  99. package/runtime/scripts/hfs/rules/a15-findings.mjs +88 -0
  100. package/runtime/scripts/hfs/rules/app-env-required.mjs +20 -0
  101. package/runtime/scripts/hfs/rules/app-root.mjs +2 -2
  102. package/runtime/scripts/hfs/rules/assets.mjs +79 -0
  103. package/runtime/scripts/hfs/rules/boot-proof.mjs +16 -0
  104. package/runtime/scripts/hfs/rules/canon-copy-drift.mjs +59 -0
  105. package/runtime/scripts/hfs/rules/contract.mjs +66 -5
  106. package/runtime/scripts/hfs/rules/coverage-below.mjs +230 -0
  107. package/runtime/scripts/hfs/rules/database-access.mjs +343 -0
  108. package/runtime/scripts/hfs/rules/database-baseline.mjs +142 -0
  109. package/runtime/scripts/hfs/rules/database-config.mjs +250 -2
  110. package/runtime/scripts/hfs/rules/database-constants.mjs +9 -0
  111. package/runtime/scripts/hfs/rules/database-migrations.mjs +317 -37
  112. package/runtime/scripts/hfs/rules/database-plpgsql.mjs +119 -9
  113. package/runtime/scripts/hfs/rules/database-queue-sources.mjs +176 -0
  114. package/runtime/scripts/hfs/rules/database-queues.mjs +361 -0
  115. package/runtime/scripts/hfs/rules/database-sql.mjs +91 -9
  116. package/runtime/scripts/hfs/rules/database.mjs +11 -2
  117. package/runtime/scripts/hfs/rules/deploy-scan.mjs +192 -0
  118. package/runtime/scripts/hfs/rules/deploy-workflow.mjs +219 -0
  119. package/runtime/scripts/hfs/rules/doc-fresh.mjs +286 -0
  120. package/runtime/scripts/hfs/rules/docker-health.mjs +249 -0
  121. package/runtime/scripts/hfs/rules/docker.mjs +24 -7
  122. package/runtime/scripts/hfs/rules/edition.mjs +11 -10
  123. package/runtime/scripts/hfs/rules/env-parity.mjs +373 -0
  124. package/runtime/scripts/hfs/rules/env-value-shape.mjs +113 -0
  125. package/runtime/scripts/hfs/rules/event-bus.mjs +3 -2
  126. package/runtime/scripts/hfs/rules/event-tables.mjs +100 -0
  127. package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +115 -15
  128. package/runtime/scripts/hfs/rules/fe-stack.mjs +57 -0
  129. package/runtime/scripts/hfs/rules/feature-files.mjs +28 -0
  130. package/runtime/scripts/hfs/rules/frontend-tree.mjs +54 -35
  131. package/runtime/scripts/hfs/rules/integration-specs.mjs +3 -2
  132. package/runtime/scripts/hfs/rules/lexicon.mjs +62 -0
  133. package/runtime/scripts/hfs/rules/lite-proof-lane.mjs +89 -0
  134. package/runtime/scripts/hfs/rules/monorepo.mjs +14 -1
  135. package/runtime/scripts/hfs/rules/pipeline.mjs +8 -1
  136. package/runtime/scripts/hfs/rules/proof-commands.mjs +2 -0
  137. package/runtime/scripts/hfs/rules/release-provenance.mjs +211 -0
  138. package/runtime/scripts/hfs/rules/saga-delivery.mjs +66 -0
  139. package/runtime/scripts/hfs/rules/saga.mjs +8 -16
  140. package/runtime/scripts/hfs/rules/script-hygiene.mjs +151 -0
  141. package/runtime/scripts/hfs/rules/secret-custody-only.mjs +65 -0
  142. package/runtime/scripts/hfs/rules/secrets.mjs +26 -0
  143. package/runtime/scripts/hfs/rules/services.mjs +4 -4
  144. package/runtime/scripts/hfs/rules/stack-tooling.mjs +93 -0
  145. package/runtime/scripts/hfs/rules/stacks-deploy.mjs +76 -0
  146. package/runtime/scripts/hfs/rules/stacks-ingress.mjs +87 -0
  147. package/runtime/scripts/hfs/rules/stacks-lite-backing.mjs +111 -0
  148. package/runtime/scripts/hfs/rules/stacks-release.mjs +366 -0
  149. package/runtime/scripts/hfs/rules/stacks-runtime.mjs +168 -0
  150. package/runtime/scripts/hfs/rules/stacks-swarm.mjs +417 -0
  151. package/runtime/scripts/hfs/rules/stacks.mjs +13 -8
  152. package/runtime/scripts/hfs/rules/supabase-secrets.mjs +1 -1
  153. package/runtime/scripts/hfs/rules/supply-chain.mjs +167 -0
  154. package/runtime/scripts/hfs/rules/unused-symbol-flow.mjs +101 -0
  155. package/runtime/scripts/hfs/rules/unused-symbol-ledger.mjs +77 -0
  156. package/runtime/scripts/hfs/rules/unused-symbol-translators.mjs +165 -0
  157. package/runtime/scripts/hfs/rules/unused-symbol-values.mjs +103 -0
  158. package/runtime/scripts/hfs/rules/unused-symbol.mjs +320 -0
  159. package/runtime/scripts/hfs/runtime-rules/source-ast.mjs +185 -0
  160. package/runtime/scripts/hfs/runtime-rules/workflow-source.mjs +19 -0
  161. package/runtime/scripts/hfs/sealed-members.mjs +101 -0
  162. package/runtime/scripts/hfs/secret-bootstrap-crypto.mjs +200 -0
  163. package/runtime/scripts/hfs/secret-document.mjs +97 -0
  164. package/runtime/scripts/hfs/secret-edit.mjs +170 -0
  165. package/runtime/scripts/hfs/secret-errors.mjs +20 -0
  166. package/runtime/scripts/hfs/secret-files.mjs +124 -0
  167. package/runtime/scripts/hfs/secret-init.mjs +300 -0
  168. package/runtime/scripts/hfs/secret-output.mjs +100 -0
  169. package/runtime/scripts/hfs/secret-sops.mjs +130 -0
  170. package/runtime/scripts/hfs/secret-store.mjs +163 -0
  171. package/runtime/scripts/hfs/secret.mjs +162 -193
  172. package/runtime/scripts/hfs/slot-imports.mjs +18 -3
  173. package/runtime/scripts/hfs/slot-required.mjs +13 -0
  174. package/runtime/scripts/hfs/slot-semantic-problems.mjs +2 -1
  175. package/runtime/scripts/hfs/slots.mjs +1 -0
  176. package/runtime/scripts/hfs/stack-config-kit.mjs +34 -0
  177. package/runtime/scripts/hfs/stack-deploy-config.mjs +313 -0
  178. package/runtime/scripts/hfs/stack-ingress-config.mjs +237 -0
  179. package/runtime/scripts/hfs/stacks-gate.mjs +414 -0
  180. package/runtime/scripts/hfs/starcistacks-runtime.mjs +61 -0
  181. package/runtime/scripts/hfs/tree-findings.mjs +22 -0
  182. package/runtime/scripts/lib/command-tokens.mjs +126 -0
  183. package/runtime/scripts/lib/compose-values.mjs +11 -0
  184. package/runtime/scripts/lib/deployment-findings.mjs +7 -0
  185. package/runtime/scripts/lib/json-clone.mjs +61 -0
  186. package/runtime/scripts/lib/list.mjs +4 -0
  187. package/runtime/scripts/lib/roots.mjs +59 -0
  188. package/runtime/scripts/lib/runtime-example.mjs +13 -0
  189. package/runtime/scripts/lib/secret-patterns.mjs +60 -5
  190. package/runtime/scripts/lib/sql-ast.mjs +32 -0
  191. package/runtime/scripts/lib/stack-services.mjs +1 -1
  192. package/runtime/scripts/lib/swarm-stack.mjs +126 -0
  193. package/runtime/scripts/lib/trim-end.mjs +8 -0
  194. package/runtime/scripts/lib/ts-analysis.mjs +23 -0
  195. package/runtime/scripts/lib/ts-ast.mjs +27 -2
  196. package/runtime/scripts/lib/workflow-events.mjs +8 -0
  197. package/scaffold/add-app.mjs +77 -59
  198. package/scaffold/add-cli-lite.mjs +24 -17
  199. package/scaffold/add-compose.mjs +79 -0
  200. package/scaffold/add-database-lite.mjs +14 -0
  201. package/scaffold/add-fe-overlay.mjs +122 -0
  202. package/scaffold/add-fe-page.mjs +269 -0
  203. package/scaffold/add-inbox-lite.mjs +87 -124
  204. package/scaffold/add-plan.mjs +183 -0
  205. package/scaffold/add-table.mjs +132 -70
  206. package/scaffold/add.mjs +186 -204
  207. package/scaffold/app.mjs +128 -43
  208. package/scaffold/edition-gate.mjs +3 -3
  209. package/scaffold/image.mjs +2 -2
  210. package/scaffold/lite-exports.mjs +2 -1
  211. package/scaffold/service.mjs +2 -2
  212. package/src/main.mjs +238 -119
  213. package/stack/age-install.mjs +37 -0
  214. package/stack/backup.mjs +100 -0
  215. package/stack/build-args.mjs +42 -0
  216. package/stack/build.mjs +173 -0
  217. package/stack/cli.mjs +130 -0
  218. package/stack/config.mjs +57 -0
  219. package/stack/context.mjs +57 -0
  220. package/stack/converge.mjs +107 -0
  221. package/stack/deploy.mjs +301 -0
  222. package/stack/digest.mjs +16 -0
  223. package/stack/docker-transport.mjs +53 -0
  224. package/stack/edge-alias.mjs +118 -0
  225. package/stack/errors.mjs +21 -0
  226. package/stack/image-scan.mjs +152 -0
  227. package/stack/ingress-create.mjs +114 -0
  228. package/stack/ingress-publish.mjs +273 -0
  229. package/stack/ingress.mjs +706 -0
  230. package/stack/jobs.mjs +51 -0
  231. package/stack/live-restore.mjs +177 -0
  232. package/stack/prepare.mjs +266 -0
  233. package/stack/private-file.mjs +22 -0
  234. package/stack/provision.mjs +90 -0
  235. package/stack/prune.mjs +46 -0
  236. package/stack/release-store.mjs +87 -0
  237. package/stack/remote.mjs +205 -0
  238. package/stack/render.mjs +149 -0
  239. package/stack/retire.mjs +47 -0
  240. package/stack/sealed.mjs +149 -0
  241. package/stack/task.mjs +42 -0
  242. package/stack/verify.mjs +99 -0
  243. package/sync/ci-commands.mjs +13 -0
  244. package/sync/index.mjs +127 -64
  245. package/sync/stack-images.mjs +127 -0
  246. package/templates/app/ci-workflows/github/workflows/ci.yml +5 -1
  247. package/templates/app/ci-workflows/github/workflows/images.yml +15 -3
  248. package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +148 -0
  249. package/templates/app/ci-workflows-lite/github/workflows/ci.yml +7 -3
  250. package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +38 -6
  251. package/templates/app/ci-workflows-lite/github/workflows/images.yml +14 -2
  252. package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +148 -0
  253. package/templates/app/codegen-graphql.mjs.partial +13 -2
  254. package/templates/app/codegen-lite/scripts/codegen.mjs +6 -1
  255. package/templates/app/codegen-prelude.mjs.partial +8 -0
  256. package/templates/app/gitignore +4 -0
  257. package/templates/app/gitignore-lite +4 -0
  258. package/templates/app/hooks/husky/pre-commit +7 -12
  259. package/templates/app/package-scripts/package.json +1 -0
  260. package/templates/app/package-scripts/supabase.json +7 -0
  261. package/templates/app/package-scripts-lite/package.json +1 -7
  262. package/templates/app/skeleton/.editorconfig +1 -0
  263. package/templates/app/skeleton/.gitattributes +7 -1
  264. package/templates/app/skeleton/.github/dependabot.yml +17 -0
  265. package/templates/app/skeleton/.nvmrc +1 -1
  266. package/templates/app/skeleton/.sops.yaml +1 -1
  267. package/templates/app/skeleton/.starcistacks/application-stacks.yaml +134 -1
  268. package/templates/app/skeleton/.starcistacks/dev/README.md +16 -0
  269. package/templates/app/skeleton/.starcistacks/dev/environment.json +5 -0
  270. package/templates/app/skeleton/.starcistacks/dev/infra/compose/stack.yaml +71 -0
  271. package/templates/app/skeleton/.starcistacks/dev/runtime/env/KEYS.md +14 -0
  272. package/templates/app/skeleton/.starcistacks/production/README.md +37 -0
  273. package/templates/app/skeleton/.starcistacks/production/environment.json +5 -0
  274. package/templates/app/skeleton/.starcistacks/production/infra/swarm/Caddyfile +15 -0
  275. package/templates/app/skeleton/.starcistacks/production/infra/swarm/owner-actions.md +11 -0
  276. package/templates/app/skeleton/.starcistacks/production/infra/swarm/recovery/restore-proof.md +7 -0
  277. package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/current.yaml +6 -0
  278. package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/images.lock.yaml +9 -0
  279. package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/previous.yaml +6 -0
  280. package/templates/app/skeleton/.starcistacks/production/infra/swarm/stack.yaml +142 -0
  281. package/templates/app/skeleton/.starcistacks/production/runtime/env/KEYS.md +14 -0
  282. package/templates/app/skeleton/README.md +6 -6
  283. package/templates/app/skeleton/scripts/codegen.mjs +1 -2
  284. package/templates/app/skeleton-lite/.editorconfig +16 -0
  285. package/templates/app/skeleton-lite/.gitattributes +8 -0
  286. package/templates/app/skeleton-lite/.github/dependabot.yml +17 -0
  287. package/templates/app/skeleton-lite/.nvmrc +1 -0
  288. package/templates/app/skeleton-lite/.sops.yaml +3 -2
  289. package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +193 -0
  290. package/templates/app/skeleton-lite/.starcistacks/dev/README.md +20 -0
  291. package/templates/app/skeleton-lite/.starcistacks/dev/environment.json +2 -1
  292. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/Caddyfile +16 -0
  293. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/owner-actions.md +11 -0
  294. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/recovery/restore-proof.md +7 -0
  295. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/current.yaml +6 -0
  296. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/images.lock.yaml +8 -0
  297. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/previous.yaml +6 -0
  298. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/stack.yaml +120 -0
  299. package/templates/app/skeleton-lite/.starcistacks/dev/runtime/env/KEYS.md +18 -0
  300. package/templates/app/skeleton-lite/.starcistacks/production/README.md +38 -0
  301. package/templates/app/skeleton-lite/.starcistacks/production/environment.json +6 -0
  302. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/Caddyfile +11 -0
  303. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/owner-actions.md +11 -0
  304. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/recovery/restore-proof.md +7 -0
  305. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/releases/current.yaml +6 -0
  306. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/releases/images.lock.yaml +8 -0
  307. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/releases/previous.yaml +6 -0
  308. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/stack.yaml +121 -0
  309. package/templates/app/skeleton-lite/.starcistacks/production/runtime/env/KEYS.md +21 -0
  310. package/templates/app/skeleton-lite/.starciwork/brand/index.yaml +12 -0
  311. package/templates/app/skeleton-lite/.starciwork/workspace.yaml +9 -0
  312. package/templates/app/skeleton-lite/README.md +8 -4
  313. package/templates/app/skeleton-lite/supabase/config.toml +8 -1
  314. package/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql +15 -6
  315. package/templates/app/starciwork.gitignore-lite +6 -0
  316. package/templates/app/upgrade-full/.starcistacks/dev/README.md +13 -7
  317. package/templates/be/image/worker/Dockerfile +1 -1
  318. package/templates/be/inbox/database-client.spec.ts.tpl +22 -28
  319. package/templates/be/inbox/database-client.ts.tpl +14 -28
  320. package/templates/be/inbox/delivery-recorded.event.ts.tpl +36 -0
  321. package/templates/be/inbox/event-index.ts.tpl +1 -0
  322. package/templates/be/inbox/events.json.tpl +10 -0
  323. package/templates/be/inbox/migration.sql.tpl +1 -0
  324. package/templates/be/inbox/platform/event-bus/event-bus.contracts.ts.tpl +42 -0
  325. package/templates/be/inbox/platform/event-bus/event-bus.decorators.ts.tpl +9 -0
  326. package/templates/be/inbox/platform/event-bus/event-bus.module-definition.ts.tpl +6 -0
  327. package/templates/be/inbox/platform/event-bus/event-bus.module.ts.tpl +19 -0
  328. package/templates/be/inbox/platform/event-bus/event-bus.options.ts.tpl +2 -0
  329. package/templates/be/inbox/platform/event-bus/event-bus.port.ts.tpl +16 -0
  330. package/templates/be/inbox/platform/event-bus/event-bus.service.spec.ts.tpl +45 -0
  331. package/templates/be/inbox/platform/event-bus/event-bus.service.ts.tpl +15 -0
  332. package/templates/be/inbox/platform/event-bus/index.ts.tpl +5 -0
  333. package/templates/be/inbox/platform/event-bus/persistence/event-bus.sql.ts.tpl +5 -0
  334. package/templates/be/inbox/platform/inbox/inbox.decorators.ts.tpl +9 -0
  335. package/templates/be/inbox/platform/inbox/inbox.module-definition.ts.tpl +6 -0
  336. package/templates/be/inbox/platform/inbox/inbox.module.ts.tpl +19 -0
  337. package/templates/be/inbox/platform/inbox/inbox.options.ts.tpl +2 -0
  338. package/templates/be/inbox/platform/inbox/inbox.port.ts.tpl +10 -0
  339. package/templates/be/inbox/platform/inbox/inbox.service.spec.ts.tpl +41 -0
  340. package/templates/be/inbox/platform/inbox/inbox.service.ts.tpl +19 -0
  341. package/templates/be/inbox/platform/inbox/index.ts.tpl +3 -0
  342. package/templates/be/inbox/platform/inbox/persistence/inbox.sql.ts.tpl +7 -0
  343. package/templates/be/inbox/platform/migration.sql.tpl +48 -0
  344. package/templates/be/inbox/service.spec.ts.tpl +49 -20
  345. package/templates/be/inbox/service.ts.tpl +27 -16
  346. package/templates/be/inbox/sql.ts.tpl +2 -2
  347. package/templates/be/inbox/webhook-door.spec.ts.tpl +3 -3
  348. package/templates/be/inbox/webhook-door.ts.tpl +4 -3
  349. package/templates/be/patterns/api/feature.module-definition.ts.tpl +6 -0
  350. package/templates/be/patterns/api/feature.module.ts.tpl +2 -1
  351. package/templates/be/patterns/api/feature.options.ts.tpl +2 -0
  352. package/templates/be/patterns/api/graphql.module-definition.ts.tpl +6 -0
  353. package/templates/be/patterns/api/graphql.module.ts.tpl +3 -2
  354. package/templates/be/patterns/api/graphql.options.ts.tpl +2 -0
  355. package/templates/be/patterns/cli/group.module-definition.ts.tpl +6 -0
  356. package/templates/be/patterns/cli/group.module.ts.tpl +2 -1
  357. package/templates/be/patterns/cli/group.options.ts.tpl +2 -0
  358. package/templates/be/patterns/event-bus/platform/errors/event-bus.error.ts.tpl +0 -3
  359. package/templates/be/patterns/event-bus/platform/messages/event-bus.messages.ts.tpl +0 -2
  360. package/templates/be/patterns/jobs/job.module-definition.ts.tpl +6 -0
  361. package/templates/be/patterns/jobs/job.module.ts.tpl +2 -1
  362. package/templates/be/patterns/jobs/job.options.ts.tpl +2 -0
  363. package/templates/be/patterns/jobs/job.queue.module-definition.ts.tpl +6 -0
  364. package/templates/be/patterns/jobs/job.queue.module.ts.tpl +6 -3
  365. package/templates/be/patterns/jobs/job.queue.options.ts.tpl +2 -0
  366. package/templates/be/patterns/jobs/platform/fenced.processor.spec.ts.tpl +3 -1
  367. package/templates/be/patterns/outbox/platform/outbox-relay.policy.spec.ts.tpl +25 -9
  368. package/templates/be/patterns/queues/platform/queue.config.ts.tpl +1 -1
  369. package/templates/be/patterns/queues/platform/queue.index.ts.tpl +1 -1
  370. package/templates/be/patterns/queues/platform/queue.module-definition.ts.tpl +2 -2
  371. package/templates/be/patterns/queues/platform/queue.module.ts.tpl +11 -0
  372. package/templates/be/patterns/queues/platform/queue.options.ts.tpl +10 -0
  373. package/templates/be/patterns/queues/queue.module-definition.ts.tpl +6 -0
  374. package/templates/be/patterns/queues/queue.module.ts.tpl +2 -1
  375. package/templates/be/patterns/queues/queue.options.ts.tpl +2 -0
  376. package/templates/be/patterns/reactors/message.module-definition.ts.tpl +6 -0
  377. package/templates/be/patterns/reactors/message.module.ts.tpl +6 -3
  378. package/templates/be/patterns/reactors/message.options.ts.tpl +2 -0
  379. package/templates/be/patterns/reactors/reactor.module-definition.ts.tpl +6 -0
  380. package/templates/be/patterns/reactors/reactor.module.ts.tpl +2 -1
  381. package/templates/be/patterns/reactors/reactor.options.ts.tpl +2 -0
  382. package/templates/be/patterns/realtime/channel.gateway.spec.ts.tpl +188 -0
  383. package/templates/be/patterns/realtime/channel.gateway.ts.tpl +22 -0
  384. package/templates/be/patterns/realtime/channel.graphql.module-definition.ts.tpl +6 -0
  385. package/templates/be/patterns/realtime/channel.graphql.module.ts.tpl +2 -1
  386. package/templates/be/patterns/realtime/channel.graphql.options.ts.tpl +2 -0
  387. package/templates/be/patterns/realtime/channel.websocket.module-definition.ts.tpl +6 -0
  388. package/templates/be/patterns/realtime/channel.websocket.module.ts.tpl +110 -0
  389. package/templates/be/patterns/realtime/channel.websocket.options.ts.tpl +7 -0
  390. package/templates/be/patterns/saga/saga.message.module-definition.ts.tpl +6 -0
  391. package/templates/be/patterns/saga/saga.message.module.ts.tpl +6 -3
  392. package/templates/be/patterns/saga/saga.message.options.ts.tpl +2 -0
  393. package/templates/be/patterns/saga/saga.module-definition.ts.tpl +6 -0
  394. package/templates/be/patterns/saga/saga.module.ts.tpl +2 -1
  395. package/templates/be/patterns/saga/saga.options.ts.tpl +2 -0
  396. package/templates/be/patterns/webhooks/webhook.door.spec.ts.tpl +3 -3
  397. package/templates/be/patterns/webhooks/webhook.door.ts.tpl +3 -3
  398. package/templates/be/patterns/webhooks/webhook.http.module-definition.ts.tpl +6 -0
  399. package/templates/be/patterns/webhooks/webhook.http.module.ts.tpl +2 -1
  400. package/templates/be/patterns/webhooks/webhook.http.options.ts.tpl +2 -0
  401. package/templates/be/platform/graphql/localize-errors.mapper.spec.ts +80 -26
  402. package/templates/be/platform/graphql/localize-errors.mapper.ts +2 -5
  403. package/templates/be/skeleton/apps/__app__/src/__app__.env.ts +21 -0
  404. package/templates/be/skeleton/apps/__app__/src/__app__.options.ts +1 -1
  405. package/templates/be/skeleton/apps/__app__/src/app.module.ts +15 -45
  406. package/templates/be/skeleton/apps/__app__/src/compose/api.ts +4 -0
  407. package/templates/be/skeleton/apps/__app__/src/compose/domain.ts +11 -0
  408. package/templates/be/skeleton/apps/__app__/src/compose/platform.ts +44 -0
  409. package/templates/be/skeleton/apps/__app__/src/compose/system.ts +5 -0
  410. package/templates/be/skeleton/apps/__app__/src/compose/webhooks.ts +4 -0
  411. package/templates/be/skeleton/apps/__app__/src/main.ts +18 -10
  412. package/templates/be/skeleton/apps/cli/src/app.module.ts +3 -13
  413. package/templates/be/skeleton/apps/cli/src/cli.env.ts +13 -0
  414. package/templates/be/skeleton/apps/cli/src/cli.options.ts +7 -17
  415. package/templates/be/skeleton/apps/cli/src/compose/cli.ts +5 -0
  416. package/templates/be/skeleton/apps/cli/src/compose/platform.ts +24 -0
  417. package/templates/be/skeleton/apps/cli/src/main.ts +3 -2
  418. package/templates/be/skeleton/src/features/api/system-health/application/check-readiness.contracts.ts +2 -0
  419. package/templates/be/skeleton/src/features/api/system-health/application/check-readiness.handler.ts +22 -0
  420. package/templates/be/skeleton/src/features/api/system-health/application/check-readiness.query.ts +11 -0
  421. package/templates/be/skeleton/src/features/api/system-health/system-health.module-definition.ts +6 -0
  422. package/templates/be/skeleton/src/features/api/system-health/system-health.module.ts +5 -3
  423. package/templates/be/skeleton/src/features/api/system-health/system-health.options.ts +2 -0
  424. package/templates/be/skeleton/src/features/api/system-health/transport/http/ready.controller.ts +19 -0
  425. package/templates/be/skeleton/src/features/api/system-health/transport/http/system-health-http.module-definition.ts +6 -0
  426. package/templates/be/skeleton/src/features/api/system-health/transport/http/system-health-http.module.ts +8 -3
  427. package/templates/be/skeleton/src/features/api/system-health/transport/http/system-health-http.options.ts +2 -0
  428. package/templates/be/skeleton/src/features/cli/cli.module-definition.ts +6 -0
  429. package/templates/be/skeleton/src/features/cli/cli.module.ts +3 -2
  430. package/templates/be/skeleton/src/features/cli/cli.options.ts +2 -0
  431. package/templates/be/skeleton/src/features/cli/migrate/migrate.module-definition.ts +6 -0
  432. package/templates/be/skeleton/src/features/cli/migrate/migrate.module.ts +2 -1
  433. package/templates/be/skeleton/src/features/cli/migrate/migrate.options.ts +2 -0
  434. package/templates/be/skeleton/src/features/cli/seed/seed.module-definition.ts +6 -0
  435. package/templates/be/skeleton/src/features/cli/seed/seed.module.ts +2 -1
  436. package/templates/be/skeleton/src/features/cli/seed/seed.options.ts +2 -0
  437. package/templates/be/skeleton/src/features/cli/seed/subs/run.cli.spec.ts +5 -6
  438. package/templates/be/skeleton/src/modules/domain/identity/admission.policy.spec.ts +56 -4
  439. package/templates/be/skeleton/src/modules/domain/identity/admission.policy.ts +36 -5
  440. package/templates/be/skeleton/src/modules/domain/identity/auth.guard.spec.ts +39 -8
  441. package/templates/be/skeleton/src/modules/domain/identity/auth.guard.ts +14 -8
  442. package/templates/be/skeleton/src/modules/domain/identity/credential.contracts.ts +26 -0
  443. package/templates/be/skeleton/src/modules/domain/identity/credential.guard.spec.ts +119 -0
  444. package/templates/be/skeleton/src/modules/domain/identity/credential.guard.ts +43 -0
  445. package/templates/be/skeleton/src/modules/domain/identity/identity.contracts.ts +16 -0
  446. package/templates/be/skeleton/src/modules/domain/identity/identity.decorators.ts +18 -1
  447. package/templates/be/skeleton/src/modules/domain/identity/identity.module.ts +22 -4
  448. package/templates/be/skeleton/src/modules/domain/identity/identity.options.ts +8 -2
  449. package/templates/be/skeleton/src/modules/domain/identity/index.ts +1 -0
  450. package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +6 -6
  451. package/templates/be/skeleton/src/modules/platform/database/connection-source.client.spec.ts +11 -4
  452. package/templates/be/skeleton/src/modules/platform/database/database-probe.service.spec.ts +32 -0
  453. package/templates/be/skeleton/src/modules/platform/database/database-probe.service.ts +14 -0
  454. package/templates/be/skeleton/src/modules/platform/database/database.module.ts +7 -1
  455. package/templates/be/skeleton/src/modules/platform/database/index.ts +2 -0
  456. package/templates/be/skeleton/src/modules/platform/database/primary.decorators.ts +8 -0
  457. package/templates/be/skeleton/src/modules/platform/database/seed-connections.client.spec.ts +25 -6
  458. package/templates/be/skeleton/src/modules/platform/errors/errors.filter.spec.ts +16 -6
  459. package/templates/be/skeleton/src/modules/platform/http-security/edge-security.service.spec.ts +130 -0
  460. package/templates/be/skeleton/src/modules/platform/http-security/edge-security.service.ts +58 -0
  461. package/templates/be/skeleton/src/modules/platform/http-security/errors/http-security.error.ts +3 -0
  462. package/templates/be/skeleton/src/modules/platform/http-security/execution-request.mapper.spec.ts +16 -4
  463. package/templates/be/skeleton/src/modules/platform/http-security/http-security.config.ts +16 -10
  464. package/templates/be/skeleton/src/modules/platform/http-security/http-security.module.ts +3 -1
  465. package/templates/be/skeleton/src/modules/platform/http-security/http-security.options.ts +2 -0
  466. package/templates/be/skeleton/src/modules/platform/http-security/index.ts +5 -0
  467. package/templates/be/skeleton/src/modules/platform/http-security/messages/http-security.messages.ts +12 -5
  468. package/templates/be/skeleton/src/modules/platform/http-security/rate-limit.guard.spec.ts +13 -8
  469. package/templates/be/skeleton/src/modules/platform/http-security/readiness.contracts.ts +5 -0
  470. package/templates/be/skeleton/src/modules/platform/http-security/readiness.decorators.ts +7 -0
  471. package/templates/be/skeleton/src/modules/platform/http-security/readiness.service.spec.ts +86 -0
  472. package/templates/be/skeleton/src/modules/platform/http-security/readiness.service.ts +39 -0
  473. package/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.spec.ts +139 -131
  474. package/templates/be/skeleton/src/modules/platform/i18n/index.ts +1 -1
  475. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +91 -67
  476. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +5 -4
  477. package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +0 -2
  478. package/templates/be/skeleton/src/modules/platform/primitives/outcome.mapper.spec.ts +20 -6
  479. package/templates/be/skeleton/src/modules/platform/primitives/sequence.policy.spec.ts +16 -4
  480. package/templates/be/skeleton/src/modules/platform/retry/index.ts +3 -0
  481. package/templates/be/skeleton/src/modules/platform/retry/retry.decorators.ts +9 -0
  482. package/templates/be/skeleton/src/modules/platform/retry/retry.module-definition.ts +7 -0
  483. package/templates/be/skeleton/src/modules/platform/retry/retry.module.ts +19 -0
  484. package/templates/be/skeleton/src/modules/platform/retry/retry.options.ts +2 -0
  485. package/templates/be/skeleton/src/modules/platform/retry/retry.port.ts +11 -0
  486. package/templates/be/skeleton/src/modules/platform/retry/system-timer.service.spec.ts +36 -0
  487. package/templates/be/skeleton/src/modules/platform/retry/system-timer.service.ts +10 -0
  488. package/templates/be/skeleton/src/tests/contract/http-security/http-security.contract-spec.ts +54 -0
  489. package/templates/be/skeleton-lite/apps/api/src/api.env.ts +25 -0
  490. package/templates/be/skeleton-lite/apps/api/src/api.options.ts +1 -1
  491. package/templates/be/skeleton-lite/apps/api/src/app.module.ts +18 -58
  492. package/templates/be/skeleton-lite/apps/api/src/compose/api.ts +4 -0
  493. package/templates/be/skeleton-lite/apps/api/src/compose/domain.ts +10 -0
  494. package/templates/be/skeleton-lite/apps/api/src/compose/integrations.ts +16 -0
  495. package/templates/be/skeleton-lite/apps/api/src/compose/platform.ts +47 -0
  496. package/templates/be/skeleton-lite/apps/api/src/compose/system.ts +5 -0
  497. package/templates/be/skeleton-lite/apps/api/src/compose/webhooks.ts +4 -0
  498. package/templates/be/skeleton-lite/apps/api/src/main.ts +5 -13
  499. package/templates/be/skeleton-lite/apps/cli/src/cli.env.ts +17 -0
  500. package/templates/be/skeleton-lite/apps/cli/src/compose/platform.ts +12 -0
  501. package/templates/be/skeleton-lite/src/modules/domain/identity/admission.policy.spec.ts +71 -5
  502. package/templates/be/skeleton-lite/src/modules/domain/identity/admission.policy.ts +29 -2
  503. package/templates/be/skeleton-lite/src/modules/domain/identity/auth.guard.spec.ts +68 -15
  504. package/templates/be/skeleton-lite/src/modules/domain/identity/auth.guard.ts +14 -9
  505. package/templates/be/skeleton-lite/src/modules/domain/identity/identity.contracts.ts +9 -2
  506. package/templates/be/skeleton-lite/src/modules/domain/identity/identity.decorators.ts +16 -1
  507. package/templates/be/skeleton-lite/src/modules/domain/identity/identity.module.ts +19 -4
  508. package/templates/be/skeleton-lite/src/modules/domain/identity/identity.options.ts +5 -1
  509. package/templates/be/skeleton-lite/src/modules/domain/identity/index.ts +2 -1
  510. package/templates/be/skeleton-lite/src/modules/integrations/supabase/errors/supabase.error.ts +0 -3
  511. package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.spec.ts +17 -5
  512. package/templates/be/skeleton-lite/src/modules/platform/database/database.module.ts +24 -13
  513. package/templates/be/skeleton-lite/src/modules/platform/database/database.port.ts +5 -0
  514. package/templates/be/skeleton-lite/src/modules/platform/database/errors/database.error.ts +16 -0
  515. package/templates/be/skeleton-lite/src/modules/platform/database/index.ts +3 -0
  516. package/templates/be/skeleton-lite/src/modules/platform/http-security/http-security.module.ts +5 -2
  517. package/templates/be/skeleton-lite/src/modules/platform/http-security/index.ts +4 -1
  518. package/templates/be/skeleton-lite/src/modules/platform/i18n/index.ts +1 -1
  519. package/templates/be/skeleton-lite/src/modules/platform/logging/logging.log-events.ts +7 -0
  520. package/templates/be/skeleton-lite/src/tests/fixtures/builders/api.builder.ts +29 -0
  521. package/templates/be/skeleton-lite/src/tests/fixtures/builders/cli.builder.ts +16 -0
  522. package/templates/be/table/api/feature.module-definition.ts.tpl +6 -0
  523. package/templates/be/table/api/feature.module.ts.tpl +2 -1
  524. package/templates/be/table/api/feature.options.ts.tpl +2 -0
  525. package/templates/be/table/api/graphql.module-definition.ts.tpl +6 -0
  526. package/templates/be/table/api/graphql.module.ts.tpl +3 -2
  527. package/templates/be/table/api/graphql.options.ts.tpl +2 -0
  528. package/templates/be/table/migration.sql.tpl +1 -0
  529. package/templates/be/upgrade-full/apps/cli/src/app.module.ts +4 -6
  530. package/templates/be/upgrade-full/apps/cli/src/cli.env.ts +7 -0
  531. package/templates/be/upgrade-full/apps/cli/src/compose/cli.ts +5 -0
  532. package/templates/be/upgrade-full/apps/cli/src/compose/platform.ts +9 -0
  533. package/templates/be/upgrade-full/apps/cli/src/main.ts +3 -0
  534. package/templates/be/upgrade-full/src/features/cli/cli.module.ts +3 -2
  535. package/templates/fe/auth/supabase-client.ts.tpl +34 -0
  536. package/templates/fe/skeleton/apps/__app__/src/app/auth/callback/route.ts +11 -0
  537. package/templates/fe/skeleton/apps/__app__/src/components/blocks/SignInForm/index.tsx +6 -1
  538. package/templates/fe/skeleton/apps/__app__/src/components/leaves/Icon/index.tsx +4 -0
  539. package/templates/fe/skeleton/apps/__app__/src/features/overlays/AppGuideOverlay/component.tsx +31 -0
  540. package/templates/fe/skeleton/apps/__app__/src/features/overlays/AppGuideOverlay/index.tsx +24 -0
  541. package/templates/fe/skeleton/apps/__app__/src/hooks/auth/useSession.ts +6 -1
  542. package/templates/fe/skeleton/apps/__app__/src/hooks/auth/useSignOut.ts +3 -4
  543. package/templates/fe/skeleton/apps/__app__/src/hooks/zustand/appGuide/index.ts +1 -0
  544. package/templates/fe/skeleton/apps/__app__/src/hooks/zustand/appGuide/store.ts +15 -0
  545. package/templates/fe/skeleton/apps/__app__/src/modules/auth/pkce-client.ts +18 -0
  546. package/templates/fe/skeleton/apps/__app__/src/modules/auth/server.ts +19 -0
  547. package/templates/fe/skeleton/apps/app/src/features/pages/AppHomePage/index.tsx +7 -1
  548. package/templates/fe/skeleton/apps/app/src/modules/i18n/messages/en.json +57 -0
  549. package/templates/fe/skeleton/apps/app/src/modules/i18n/messages/vi.json +6 -0
  550. package/templates/fe/skeleton/apps/landing/src/modules/i18n/messages/en.json +31 -0
  551. package/templates/fe/skeleton/packages/__project__-i18n/src/routing.ts +1 -1
  552. package/templates/fe/skeleton/packages/__project__-ui/src/index.ts +1 -0
  553. package/templates/fe/skeleton-lite/apps/__app__/src/modules/auth/client.ts +1 -34
  554. package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/index.tsx +7 -1
  555. package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages/en.json +57 -0
  556. package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages/vi.json +30 -24
  557. package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/routing.ts +1 -1
  558. package/templates/fe/transport/graphql/clients/clients/auth.ts +1 -1
  559. package/templates/fe/transport/graphql/clients/links/locale.ts +2 -2
  560. package/upgrade/check.mjs +3 -1
  561. package/upgrade/file-state.mjs +68 -0
  562. package/upgrade/index.mjs +58 -94
  563. package/runtime/scripts/api/git/log.mjs +0 -5
  564. package/templates/app/skeleton-lite/.starciwork/shell/index.yaml +0 -55
@@ -0,0 +1,120 @@
1
+ # Illustrative development model. Replace all-zero application digests with verified published release digests before use.
2
+ version: "3.8"
3
+ services:
4
+ api:
5
+ image: "{{project}}/api:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
6
+ environment:
7
+ NODE_ENV: development
8
+ PORT: "3001"
9
+ HTTP_SECURITY_ALLOWED_ORIGINS: http://dev.{{project}}.example.invalid
10
+ PRIMARY_DB_URL_FILE: /run/secrets/primary-db-url
11
+ PRIMARY_DB_SCHEMA: public
12
+ SUPABASE_URL: https://{{project}}.supabase.co
13
+ SUPABASE_SERVICE_ROLE_KEY_FILE: /run/secrets/supabase-service-role-key
14
+ secrets:
15
+ - source: primary-db-url
16
+ target: primary-db-url
17
+ - source: supabase-service-role-key
18
+ target: supabase-service-role-key
19
+ networks: [app]
20
+ healthcheck:
21
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3001/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
22
+ interval: 30s
23
+ timeout: 5s
24
+ start_period: 20s
25
+ retries: 3
26
+ deploy:
27
+ replicas: 1
28
+ placement:
29
+ constraints: ["node.labels.{{project}} == dev"]
30
+ update_config:
31
+ parallelism: 1
32
+ order: start-first
33
+ failure_action: rollback
34
+ monitor: 30s
35
+ rollback_config:
36
+ parallelism: 1
37
+ order: stop-first
38
+ restart_policy:
39
+ condition: on-failure
40
+ delay: 5s
41
+ web:
42
+ image: "{{project}}/web:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
43
+ environment:
44
+ NODE_ENV: development
45
+ PORT: "3000"
46
+ HOSTNAME: 0.0.0.0
47
+ NEXT_PUBLIC_SITE_URL: http://dev.{{project}}.example.invalid
48
+ networks: [app]
49
+ healthcheck:
50
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
51
+ interval: 30s
52
+ timeout: 5s
53
+ start_period: 20s
54
+ retries: 3
55
+ deploy:
56
+ replicas: 1
57
+ placement:
58
+ constraints: ["node.labels.{{project}} == dev"]
59
+ update_config:
60
+ parallelism: 1
61
+ order: start-first
62
+ failure_action: rollback
63
+ monitor: 30s
64
+ rollback_config:
65
+ parallelism: 1
66
+ order: stop-first
67
+ restart_policy:
68
+ condition: on-failure
69
+ delay: 5s
70
+ ingress:
71
+ image: caddy:2.10.2@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb
72
+ configs:
73
+ - source: ingress-config
74
+ target: /etc/caddy/Caddyfile
75
+ ports:
76
+ - { target: 80, published: 80, protocol: tcp, mode: ingress }
77
+ volumes:
78
+ - ingress-data:/data
79
+ - ingress-config-data:/config
80
+ networks: [app]
81
+ healthcheck:
82
+ test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
83
+ interval: 30s
84
+ timeout: 5s
85
+ retries: 3
86
+ deploy:
87
+ replicas: 1
88
+ placement:
89
+ constraints: ["node.labels.{{project}} == dev"]
90
+ update_config:
91
+ parallelism: 1
92
+ order: stop-first
93
+ failure_action: rollback
94
+ monitor: 30s
95
+ rollback_config:
96
+ parallelism: 1
97
+ order: stop-first
98
+ restart_policy:
99
+ condition: on-failure
100
+ delay: 5s
101
+ networks:
102
+ app:
103
+ driver: overlay
104
+ secrets:
105
+ primary-db-url:
106
+ external: true
107
+ name: "{{project}}-dev-primary-db-url-v1"
108
+ supabase-service-role-key:
109
+ external: true
110
+ name: "{{project}}-dev-supabase-service-role-key-v1"
111
+ configs:
112
+ ingress-config:
113
+ file: ./Caddyfile
114
+ volumes:
115
+ ingress-data:
116
+ external: true
117
+ name: "{{project}}-dev-ingress-data"
118
+ ingress-config-data:
119
+ external: true
120
+ name: "{{project}}-dev-ingress-config-data"
@@ -0,0 +1,18 @@
1
+ # Environment key roster
2
+
3
+ This roster declares names only. Scaffolding generates the two declared encrypted members with placeholder values encrypted to this app's own age recipient. Replace their values through `starci app secret set dev` before creating external secrets. The runtime template tracks no ciphertext; its specs generate members with ephemeral identities in disposable copies. Store product credential values in sealed custody and materialize private KEY files outside the repository.
4
+
5
+ | Key | Consumer |
6
+ | --- | --- |
7
+ | `PORT` | API listener |
8
+ | `HTTP_SECURITY_ALLOWED_ORIGINS` | API origin allowlist |
9
+ | `PRIMARY_DB_URL` | API primary database connection; `.starcistacks/dev/secrets/primary-db-url.enc` maps to external `{{project}}-dev-primary-db-url-v1` and mounted `/run/secrets/primary-db-url` |
10
+ | `PRIMARY_DB_SCHEMA` | API primary database schema |
11
+ | `SUPABASE_URL` | API Auth and Storage integration |
12
+ | `SUPABASE_SERVICE_ROLE_KEY` | API Auth and Storage integration; `.starcistacks/dev/secrets/supabase-service-role-key.enc` maps to external `{{project}}-dev-supabase-service-role-key-v1` and mounted `/run/secrets/supabase-service-role-key` |
13
+ | `NEXT_PUBLIC_SITE_URL` | Front-end site URL |
14
+ | `NEXT_PUBLIC_GRAPHQL_URL` | Front-end GraphQL transport |
15
+ | `NEXT_PUBLIC_SUPABASE_URL` | Browser Auth client |
16
+ | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Browser Auth client public key |
17
+
18
+ Public front-end configuration is supplied at build time and stays outside sealed custody. Production database deployment consumes `SUPABASE_ACCESS_TOKEN`, `SUPABASE_DB_PASSWORD` and `SUPABASE_PROJECT_ID` from its environment's sealed custody; the GitHub secret store carries only the age identity.
@@ -0,0 +1,38 @@
1
+ # Production stack
2
+
3
+ The tracked model declares Docker Swarm application services and one digest-pinned Caddy ingress.
4
+ Supabase supplies PostgreSQL, Auth and pgmq. This stack runs no PostgreSQL, Redis or MongoDB service.
5
+ The model is a deployment declaration. It contains no owner credentials, real DNS receipt, completed release or restore proof. Public records under `.starcistacks/production/infra/swarm/` explicitly mark those owner-run operations as pending.
6
+ Its application image references contain illustrative all-zero digests; they identify no published image and must be replaced before deployment.
7
+
8
+ The runtime template tracks no encrypted members. Scaffolding generates the two declared members with placeholder values encrypted to this app's own recipient in `.sops.yaml`. Replace those values with `starci app secret set production` using the matching host age identity in untracked local custody. Existing generated envelopes are decryptable with that app identity and can be updated in place. Each Docker secret contains the corresponding key's real value, and the API receives it through its declared mounted file.
9
+
10
+ | Command | Operation |
11
+ | --- | --- |
12
+ | prepare | Owner provisions the Swarm, node label, database, DNS and real sealed secret members, then runs `starci app stack prepare --env production --execute` to create the missing external volumes (the one-time swarm initialization stays an owner-approved step: `--init-swarm` with `--execute`, after the owner's explicit approval). Release images are built and pushed by the managed the managed stack-deploy workflow. |
13
+ | doctor | Run `starci app stack doctor --env production` (read-only): docker, swarm, volumes, services, secrets, configs and the release pointers on the intended manager. |
14
+ | up | After preparation and review, run the manual stack-deploy workflow (Actions, deploy stack) on a release tag; it builds the images and runs `starci app stack deploy --env production --image <service>=<repository>@sha256:<digest> --source-sha <sha> --execute`. A dry run is `starci app stack render` or `deploy` without `--execute`. |
15
+ | status | Run `starci app stack doctor --env production`, or `starci app stack converge --env production --since <ISO time>` to inspect desired and running replicas plus update state. |
16
+ | logs | Run `docker service logs {{project}}-production_api` on the manager; never include secret values in a receipt. |
17
+ | down | After the owner's removal decision, run `docker stack rm {{project}}-production`; persistent external volumes remain in owner custody. |
18
+ | verification | Run `starci app stack verify --env production` (the journeys declared in `deploy.verify`); also confirm public TLS and a signed-in GraphQL request before moving the release pointer. |
19
+
20
+ ## Owner actions before the first release
21
+
22
+ Every item is pending. Swarm initialization, provider URIs, DNS changes and key rotation are owner-run steps.
23
+
24
+ | Area | Required owner action and evidence |
25
+ | --- | --- |
26
+ | Swarm and placement | Initialize the intended manager; label the intended stateful node `{{project}}=production`. Only that node owns the external ingress volumes. |
27
+ | DNS | Replace the reserved `example.invalid` hosts consistently in the manifest, Caddyfile and public configuration; publish address records for the web and API hosts and retain a provider receipt in `.starcistacks/production/infra/swarm/owner-actions.md`. |
28
+ | TLS | Caddy issues certificates after real DNS resolves. Provision `{{project}}-production-ingress-data` and `{{project}}-production-ingress-config-data` on the selected node; retain an issuance and renewal receipt in `.starcistacks/production/infra/swarm/owner-actions.md`. |
29
+ | Database | Provision Supabase and the app_be connection; provider backups remain enabled. Record the provider URI and recovery owner without copying credentials here. |
30
+ | Secret custody | Replace generated placeholder values with real values at the manifest's declared `.starcistacks/production/secrets/*.enc` paths; record their keys in `.starcistacks/production/runtime/env/KEYS.md`. The app's age identity stays only in the host's untracked `.claude/secret.env`. |
31
+ | External secrets | Materialize the sealed members in owner custody and create `{{project}}-production-primary-db-url-v1` and `{{project}}-production-supabase-service-role-key-v1`. The API reads mounted files; rotation creates new versioned names before updating the model. |
32
+ | Public build configuration | Build the front end with its declared public site and GraphQL URLs, the Supabase public URL and anonymous key. Public browser values stay outside sealed secret custody. |
33
+ | Immutable release | Replace the illustrative all-zero application digests in the manifest, model and `.starcistacks/production/infra/swarm/releases/images.lock.yaml` with digests produced by the verified release. Store each rendered release under `/srv/{{project}}/releases/<digest>`. Retain the last accepted record in `.starcistacks/production/infra/swarm/releases/previous.yaml`, then move the current pointer and update `.starcistacks/production/infra/swarm/releases/current.yaml` after verification. |
34
+ | Rollback | Retain the previous model and images, redeploy that model if convergence or health fails, and record the resulting convergence receipt. Database changes follow an expand/contract sequence. |
35
+ | Backup | Provision the manifest's seven days of database PITR and thirty daily encrypted off-host database exports and ingress-volume snapshots. Record the actual destination and encryption custody in `.starcistacks/production/infra/swarm/recovery/restore-proof.md`; the production operator owns both components. |
36
+ | Restore proof | Perform a restore into isolated infrastructure, verify the restored database and ingress state, and attach a dated receipt with artifact digests to `.starcistacks/production/infra/swarm/recovery/restore-proof.md`. Its initial record is pending; no restore has been run by scaffolding. |
37
+
38
+ No host scheduler is installed. Scheduled application work belongs to the back-end scheduler or an explicitly declared replicated job.
@@ -0,0 +1,6 @@
1
+ {
2
+ "environment": "production",
3
+ "provider": "supabase",
4
+ "project": "{{project}}",
5
+ "runtime": "docker-swarm"
6
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ admin 127.0.0.1:2019
3
+ }
4
+
5
+ {{project}}.example.invalid {
6
+ reverse_proxy web:3000
7
+ }
8
+
9
+ api.{{project}}.example.invalid {
10
+ reverse_proxy api:3001
11
+ }
@@ -0,0 +1,11 @@
1
+ # Production prerequisite record
2
+
3
+ Status: pending owner execution. This record states intended configuration and contains no completed operational receipt.
4
+
5
+ ## DNS
6
+
7
+ The production operator replaces `{{project}}.example.invalid` and `api.{{project}}.example.invalid` with owned public names, updates the manifest, Caddyfile and public configuration together, and publishes address records for the intended Swarm node. Record the provider, zone, actual hosts and dated DNS receipt here.
8
+
9
+ ## TLS
10
+
11
+ The production operator provisions the external ingress volumes on the declared node and owns Caddy certificate issuance and renewal. After real DNS resolves, record a dated issuance receipt, persistent certificate custody and HTTPS verification for both public hosts here.
@@ -0,0 +1,7 @@
1
+ # Production recovery record
2
+
3
+ Status: pending owner execution. No backup or restore has been run by scaffolding.
4
+
5
+ The production operator owns recovery of the managed Supabase database and both external ingress volumes, `{{project}}-production-ingress-data` and `{{project}}-production-ingress-config-data`. Provision seven days of provider PITR and thirty daily encrypted off-host database exports. Retain thirty daily encrypted off-host snapshots for both ingress volumes.
6
+
7
+ Before relying on the backup policy, restore the provider database backup and both volume snapshots into isolated infrastructure. Record the actual off-host destination, encryption custody, backup artifact digests, restoration time and operator. Verify database connectivity and the API readiness endpoint, then verify the restored TLS and ingress configuration. Attach the dated result here without credentials.
@@ -0,0 +1,6 @@
1
+ schema: starci/release-pointer@1
2
+ environment: production
3
+ status: pending-owner-release
4
+ release: null
5
+ verification: null
6
+ # Write a real /srv/{{project}}/releases/<digest> reference and dated health receipt only after verification.
@@ -0,0 +1,8 @@
1
+ # Illustrative inventory only. Replace application digests with verified published images.
2
+ schema: starci/images-lock@1
3
+ environment: production
4
+ status: pending-owner-release
5
+ images:
6
+ api: "{{project}}/api:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
7
+ web: "{{project}}/web:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
8
+ ingress: caddy:2.10.2@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb
@@ -0,0 +1,6 @@
1
+ schema: starci/release-pointer@1
2
+ environment: production
3
+ status: no-previous-release
4
+ release: null
5
+ verification: null
6
+ # Before moving current, retain the last accepted release here for rollback.
@@ -0,0 +1,121 @@
1
+ # Illustrative production model. Replace all-zero application digests with verified published release digests before use.
2
+ version: "3.8"
3
+ services:
4
+ api:
5
+ image: "{{project}}/api:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
6
+ environment:
7
+ NODE_ENV: production
8
+ PORT: "3001"
9
+ HTTP_SECURITY_ALLOWED_ORIGINS: https://{{project}}.example.invalid
10
+ PRIMARY_DB_URL_FILE: /run/secrets/primary-db-url
11
+ PRIMARY_DB_SCHEMA: public
12
+ SUPABASE_URL: https://{{project}}.supabase.co
13
+ SUPABASE_SERVICE_ROLE_KEY_FILE: /run/secrets/supabase-service-role-key
14
+ secrets:
15
+ - source: primary-db-url
16
+ target: primary-db-url
17
+ - source: supabase-service-role-key
18
+ target: supabase-service-role-key
19
+ networks: [app]
20
+ healthcheck:
21
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3001/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
22
+ interval: 30s
23
+ timeout: 5s
24
+ start_period: 20s
25
+ retries: 3
26
+ deploy:
27
+ replicas: 1
28
+ placement:
29
+ constraints: ["node.labels.{{project}} == production"]
30
+ update_config:
31
+ parallelism: 1
32
+ order: start-first
33
+ failure_action: rollback
34
+ monitor: 30s
35
+ rollback_config:
36
+ parallelism: 1
37
+ order: stop-first
38
+ restart_policy:
39
+ condition: on-failure
40
+ delay: 5s
41
+ web:
42
+ image: "{{project}}/web:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
43
+ environment:
44
+ NODE_ENV: production
45
+ PORT: "3000"
46
+ HOSTNAME: 0.0.0.0
47
+ NEXT_PUBLIC_SITE_URL: https://{{project}}.example.invalid
48
+ networks: [app]
49
+ healthcheck:
50
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
51
+ interval: 30s
52
+ timeout: 5s
53
+ start_period: 20s
54
+ retries: 3
55
+ deploy:
56
+ replicas: 1
57
+ placement:
58
+ constraints: ["node.labels.{{project}} == production"]
59
+ update_config:
60
+ parallelism: 1
61
+ order: start-first
62
+ failure_action: rollback
63
+ monitor: 30s
64
+ rollback_config:
65
+ parallelism: 1
66
+ order: stop-first
67
+ restart_policy:
68
+ condition: on-failure
69
+ delay: 5s
70
+ ingress:
71
+ image: caddy:2.10.2@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb
72
+ configs:
73
+ - source: ingress-config
74
+ target: /etc/caddy/Caddyfile
75
+ ports:
76
+ - { target: 80, published: 80, protocol: tcp, mode: ingress }
77
+ - { target: 443, published: 443, protocol: tcp, mode: ingress }
78
+ volumes:
79
+ - ingress-data:/data
80
+ - ingress-config-data:/config
81
+ networks: [app]
82
+ healthcheck:
83
+ test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
84
+ interval: 30s
85
+ timeout: 5s
86
+ retries: 3
87
+ deploy:
88
+ replicas: 1
89
+ placement:
90
+ constraints: ["node.labels.{{project}} == production"]
91
+ update_config:
92
+ parallelism: 1
93
+ order: stop-first
94
+ failure_action: rollback
95
+ monitor: 30s
96
+ rollback_config:
97
+ parallelism: 1
98
+ order: stop-first
99
+ restart_policy:
100
+ condition: on-failure
101
+ delay: 5s
102
+ networks:
103
+ app:
104
+ driver: overlay
105
+ secrets:
106
+ primary-db-url:
107
+ external: true
108
+ name: "{{project}}-production-primary-db-url-v1"
109
+ supabase-service-role-key:
110
+ external: true
111
+ name: "{{project}}-production-supabase-service-role-key-v1"
112
+ configs:
113
+ ingress-config:
114
+ file: ./Caddyfile
115
+ volumes:
116
+ ingress-data:
117
+ external: true
118
+ name: "{{project}}-production-ingress-data"
119
+ ingress-config-data:
120
+ external: true
121
+ name: "{{project}}-production-ingress-config-data"
@@ -0,0 +1,21 @@
1
+ # Production environment key roster
2
+
3
+ This inventory declares names, consumers and mounted file paths. Scaffolding generates the two declared encrypted members with placeholder values encrypted to this app's own age recipient. Replace their values through `starci app secret set production` after owner provisioning and before creating external secrets. The runtime template tracks no ciphertext; its specs generate members with ephemeral identities in disposable copies. Scaffolding supplies no deployment credential or successful deployment.
4
+
5
+ | Key | Consumer |
6
+ | --- | --- |
7
+ | `PORT` | API listener |
8
+ | `HTTP_SECURITY_ALLOWED_ORIGINS` | API origin allowlist |
9
+ | `PRIMARY_DB_URL` | API least-privilege database connection; reads `PRIMARY_DB_URL_FILE` at `/run/secrets/primary-db-url` |
10
+ | `PRIMARY_DB_SCHEMA` | API primary database schema |
11
+ | `SUPABASE_URL` | API Auth and Storage integration |
12
+ | `SUPABASE_SERVICE_ROLE_KEY` | API Auth and Storage integration; reads `SUPABASE_SERVICE_ROLE_KEY_FILE` at `/run/secrets/supabase-service-role-key` |
13
+ | `NEXT_PUBLIC_SITE_URL` | Front-end site URL |
14
+ | `NEXT_PUBLIC_GRAPHQL_URL` | Front-end GraphQL transport |
15
+ | `NEXT_PUBLIC_SUPABASE_URL` | Browser Auth client |
16
+ | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Browser Auth client public key |
17
+ | `SUPABASE_ACCESS_TOKEN` | Production database deployment |
18
+ | `SUPABASE_DB_PASSWORD` | Production database deployment |
19
+ | `SUPABASE_PROJECT_ID` | Production database deployment |
20
+
21
+ Public front-end configuration is supplied at build time and stays outside sealed custody. Set real values in `.starcistacks/production/secrets/primary-db-url.enc` and `.starcistacks/production/secrets/supabase-service-role-key.enc` at the declared paths. Versioned external application secrets are `{{project}}-production-primary-db-url-v1` and `{{project}}-production-supabase-service-role-key-v1`. Seal deployment-only credentials separately under `.starcistacks/production/secrets/*.enc`; they never enter an API container.
@@ -0,0 +1,12 @@
1
+ schema: work/brand@1
2
+ id: brand
3
+ kind: brand
4
+ state: todo
5
+ rev: 1
6
+ brand:
7
+ identity:
8
+ name: "{{project}}"
9
+ review:
10
+ reviewer: the {{project}} owner
11
+ authority: "The lite scaffold seeds this record so the brand tree exists; the owner settles rev 1 of the brand before the first drawn surface."
12
+ reviewedAt: "2026-10-14T00:00:00Z"
@@ -0,0 +1,9 @@
1
+ schema: work/workspace@1
2
+ id: {{project}}
3
+ project: {{project}}
4
+ description: The Work records of {{project}}, one StarCi app with its back end in be/ and its front end in fe/.
5
+ repositories:
6
+ - role: be
7
+ name: be
8
+ - role: fe
9
+ name: fe
@@ -4,7 +4,7 @@ One StarCi lite app: a Nest API in `be/`, one Next web app in `fe/`, and Supabas
4
4
 
5
5
  ## Overview
6
6
 
7
- The starter keeps one deployable API and one web app, with the same code structure as a full app: the web app calls the API over GraphQL (`src/modules/api`, SWR hooks under `src/hooks/swr`) and uses Supabase only for Auth in the browser (`src/modules/auth`); every data read and write goes through the API, which verifies the access token.
7
+ The starter keeps one deployable API and one web app, with the same code structure as a full app: the web app calls the API over GraphQL (`fe/apps/web/src/modules/api`, SWR hooks under `fe/apps/web/src/hooks/swr`) and uses Supabase only for Auth in the browser (`fe/apps/web/src/modules/auth`); every data read and write goes through the API, which verifies the access token.
8
8
 
9
9
  ## Stack
10
10
 
@@ -14,9 +14,9 @@ TypeScript everywhere, NestJS in `be/`, Next.js with next-intl in `fe/`, Supabas
14
14
 
15
15
  - `supabase/`: local configuration, forward-only SQL migrations, seed data, and generated database types.
16
16
  - `be/`: the API, shared platform capabilities, verified identity admission, and privileged Supabase integrations.
17
- - `fe/`: the web app; the only Supabase client is the Auth client of `src/modules/auth`, data goes through `src/modules/api`.
17
+ - `fe/`: the web app; the only Supabase client is the Auth client of `fe/apps/web/src/modules/auth`, data goes through `fe/apps/web/src/modules/api`.
18
18
  - `.starcistacks/`: value-free environment metadata and encrypted-secret custody.
19
- - `.starciwork/`: product workspace, brand, and shell records.
19
+ - `.starciwork/`: `.gitignore`, `.starciwork/workspace.yaml` project metadata and repo roles, and optional brand drawing records, references, and assets.
20
20
 
21
21
  ## Development
22
22
 
@@ -34,10 +34,14 @@ The API reads `PORT`, `HTTP_SECURITY_ALLOWED_ORIGINS`, `PRIMARY_DB_URL`, `PRIMAR
34
34
 
35
35
  `npm test` runs the back end's unit specs with per-file coverage. Optional integration specs run with `npm run test:integration` against the local Supabase stack (`npm run db:start`); a lite app has no e2e world.
36
36
 
37
+ The public runtime template tracks only sealed member names. Scaffolding creates this app's own age recipient and encrypts generated placeholder values into the declared `.starcistacks/<environment>/secrets/*.enc` members. Keep the matching host age identity in untracked local custody, then use `starci app secret set` to replace each placeholder with an actual value before deployment. Product apps retain sealed member custody. Runtime specs use disposable copies with ephemeral identities and remove them afterwards.
38
+
37
39
  ## Database changes
38
40
 
39
41
  Create a forward-only migration under `supabase/migrations`, keep each table's RLS policies and grants beside the table, and run `npm run contract:emit` to refresh `supabase/types/database.types.ts`. `starci app add table <name> --fe` adds the table with its GraphQL feature on the API and its operations and SWR hooks in the web app; `npm run codegen:graphql` regenerates the web app's wire types from `be/contracts/<app>/schema.graphql`.
40
42
 
41
43
  ## Work
42
44
 
43
- The product's Work records live in `.starciwork`.
45
+ Brand records live in `.starciwork/brand/`. `.starciwork/workspace.yaml` supplies the project id and repo roles so Work tools
46
+ can locate the app root and map brand records to the front end. Lite permits this metadata without brand records; the tree
47
+ is required only when brand records exist, and workspace metadata remains optional.
@@ -3,7 +3,7 @@ project_id = "{{project}}"
3
3
  [api]
4
4
  enabled = true
5
5
  port = {{supabasePortApi}}
6
- schemas = ["public", "graphql_public"]
6
+ schemas = []
7
7
  extra_search_path = ["public", "extensions"]
8
8
  max_rows = 1000
9
9
 
@@ -25,6 +25,13 @@ port = {{supabasePortInbucket}}
25
25
  [analytics]
26
26
  port = {{supabasePortAnalytics}}
27
27
 
28
+ [edge_runtime]
29
+ enabled = false
30
+
31
+ [storage]
32
+ enabled = true
33
+ file_size_limit = "50MiB"
34
+
28
35
  [auth]
29
36
  enabled = true
30
37
  site_url = "http://127.0.0.1:3000"
@@ -1,5 +1,13 @@
1
- drop role if exists app_be;
2
- create role app_be login noinherit;
1
+ do $$
2
+ begin
3
+ if not exists (select 1 from pg_catalog.pg_roles where rolname = 'app_be') then
4
+ create role app_be login noinherit nosuperuser nobypassrls nocreatedb nocreaterole;
5
+ end if;
6
+ end;
7
+ $$;
8
+
9
+ -- The attributes a Supabase migration role may change: SUPERUSER and BYPASSRLS stay as create role set them (the role migration owner is no superuser).
10
+ alter role app_be login noinherit nocreatedb nocreaterole;
3
11
 
4
12
  create schema if not exists private;
5
13
 
@@ -24,6 +32,7 @@ create table public.profiles (
24
32
  );
25
33
 
26
34
  alter table public.profiles enable row level security;
35
+ alter table public.profiles force row level security;
27
36
 
28
37
  create trigger profiles_set_updated_at
29
38
  before update on public.profiles
@@ -34,20 +43,20 @@ create policy profiles_app_be_select
34
43
  on public.profiles
35
44
  for select
36
45
  to app_be
37
- using (id is not null);
46
+ using (current_user = 'app_be');
38
47
 
39
48
  create policy profiles_app_be_insert
40
49
  on public.profiles
41
50
  for insert
42
51
  to app_be
43
- with check (id is not null);
52
+ with check (current_user = 'app_be');
44
53
 
45
54
  create policy profiles_app_be_update
46
55
  on public.profiles
47
56
  for update
48
57
  to app_be
49
- using (id is not null)
50
- with check (id is not null);
58
+ using (current_user = 'app_be')
59
+ with check (current_user = 'app_be');
51
60
 
52
61
  grant usage on schema public to app_be;
53
62
  revoke all on table public.profiles from public, anon, authenticated;
@@ -0,0 +1,6 @@
1
+ # StarCi lite .starciwork holds only workspace.yaml and brand/ (plus .gitignore).
2
+ # Runtime output lives in runtime.sqlite rows and blobs outside the repository.
3
+ /*
4
+ !/.gitignore
5
+ !/workspace.yaml
6
+ !/brand/
@@ -1,10 +1,16 @@
1
1
  # Development stack
2
2
 
3
- The full-edition development stack keeps PostgreSQL and the API in one declared Docker Compose project.
3
+ The app services may run in a local Docker Swarm; local Supabase is started separately with its CLI and supplies the database and broker. The tracked model contains no self-hosted database.
4
+ Starter release images and external secrets must be prepared before starting the container model. Replace its starter `SUPABASE_URL` with the local Supabase endpoint reachable from the Swarm node, and seal that local database connection and integration credential; a container cannot use the host's loopback address without owner-configured networking. Local source development remains available through the app scripts.
4
5
 
5
- - Prepare: provide `PRIMARY_DB_URL` to the API through the normal secret custody flow.
6
- - Up: `docker compose -f infra/compose/compose.yaml up -d`.
7
- - Status: `docker compose -f infra/compose/compose.yaml ps`.
8
- - Logs: `docker compose -f infra/compose/compose.yaml logs`.
9
- - Down: `docker compose -f infra/compose/compose.yaml down`.
10
- - Verify: call the API health endpoint and run `npm run lint`.
6
+ | Command | Operation |
7
+ | --- | --- |
8
+ | prepare | Run `npm run db:start` at the app root; obtain the local Supabase connection and Auth configuration. An owner who chooses local Swarm initializes it, labels its node `{{project}}=dev` and provisions the ingress volumes. Create the external development secrets named in the model from real sealed members. |
9
+ | doctor | From this directory, run `docker stack config -c infra/swarm/stack.yaml`. Confirm image, secret and local Supabase availability. |
10
+ | up | Run `docker stack deploy -c infra/swarm/stack.yaml {{project}}-dev` from this directory after preparation. |
11
+ | status | Run `docker stack services {{project}}-dev`. |
12
+ | logs | Run `docker service logs {{project}}-dev_api`; never print mounted credentials. |
13
+ | down | Run `docker stack rm {{project}}-dev`. |
14
+ | verification | Confirm the API `/health/live` and `/health/ready` endpoints, then run `npm run lint` from the app root. |
15
+
16
+ Keep real sealed members under `.starcistacks/dev/secrets/*.enc`, add them to the manifest after sealing and inventory their key names in the environment record. The scaffold creates no fake secret or successful proof.
@@ -32,5 +32,5 @@ RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force
32
32
  COPY --from=build /app/be/dist be/dist
33
33
 
34
34
  USER node
35
- HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 CMD pgrep -f "apps/{{app}}/src/main.js" > /dev/null || exit 1
35
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 CMD ["node", "-e", "const fs=require('node:fs');const args=fs.readFileSync('/proc/1/cmdline','utf8').split(String.fromCharCode(0));process.exit(args.includes('be/dist/apps/{{app}}/src/main.js')?0:1)"]
36
36
  CMD ["node", "be/dist/apps/{{app}}/src/main.js"]