@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
@@ -7,6 +7,11 @@ import { createHash } from "node:crypto"
7
7
  import fs from "node:fs"
8
8
  import path from "node:path"
9
9
 
10
+ const byCodeUnit = (left, right) => {
11
+ if (left === right) return 0
12
+ return left < right ? -1 : 1
13
+ }
14
+
10
15
  const MIGRATIONS = path.join("supabase", "migrations")
11
16
  const TYPES = path.join("supabase", "types", "database.types.ts")
12
17
  const STAMP = /^\/\/ migrations-sha256: ([0-9a-f]{64})$/
@@ -20,7 +25,7 @@ if (!process.argv.includes("--graphql")) {
20
25
  const hash = createHash("sha256")
21
26
  for (const name of (fs.existsSync(MIGRATIONS) ? fs.readdirSync(MIGRATIONS) : [])
22
27
  .filter((file) => file.endsWith(".sql"))
23
- .sort()) {
28
+ .sort(byCodeUnit)) {
24
29
  hash.update(`${name}\0${fs.readFileSync(path.join(MIGRATIONS, name), "utf8").replace(/\r\n/g, "\n")}\0`)
25
30
  }
26
31
  const digest = hash.digest("hex")
@@ -0,0 +1,8 @@
1
+ import fs from "node:fs"
2
+ import path from "node:path"
3
+ import { createHash } from "node:crypto"
4
+
5
+ const byCodeUnit = (left, right) => {
6
+ if (left === right) return 0
7
+ return left < right ? -1 : 1
8
+ }
@@ -18,6 +18,7 @@ next-env.d.ts
18
18
  !.starcistacks/*/infra/compose/**
19
19
  !.starcistacks/*/infra/k8s/**
20
20
  !.starcistacks/*/infra/terraform/**
21
+ !.starcistacks/*/infra/swarm/**
21
22
  .starcistacks/*/infra/**/.env
22
23
  .starcistacks/*/infra/**/.env.*
23
24
  .starcistacks/*/infra/**/*.env
@@ -30,3 +31,6 @@ next-env.d.ts
30
31
  .starcistacks/*/infra/terraform/files/
31
32
  .starcistacks/*/infra/terraform/*.tar.gz
32
33
  !.starcistacks/**/*.enc
34
+
35
+ # Host-local agent credentials and app age identity never enter Git.
36
+ .claude/
@@ -21,6 +21,7 @@ next-env.d.ts
21
21
  !.starcistacks/*/infra/compose/**
22
22
  !.starcistacks/*/infra/k8s/**
23
23
  !.starcistacks/*/infra/terraform/**
24
+ !.starcistacks/*/infra/swarm/**
24
25
  .starcistacks/*/infra/**/.env
25
26
  .starcistacks/*/infra/**/.env.*
26
27
  .starcistacks/*/infra/**/*.env
@@ -33,3 +34,6 @@ next-env.d.ts
33
34
  .starcistacks/*/infra/terraform/files/
34
35
  .starcistacks/*/infra/terraform/*.tar.gz
35
36
  !.starcistacks/**/*.enc
37
+
38
+ # Host-local agent credentials and app age identity never enter Git.
39
+ .claude/
@@ -2,19 +2,14 @@
2
2
  # Commit gate (L0 only): work hygiene and the secrets guard of the staged files, eslint of the staged files of each side,
3
3
  # stylelint over the staged CSS of fe, a prettier check of the staged files. Types and the targeted specs belong to the op gate.
4
4
  npx starci app hygiene
5
- be=$(git diff --cached --name-only --diff-filter=ACMR --relative=be -- '*.ts' '*.mts' '*.cts' '*.js' '*.mjs' '*.cjs' || true)
6
- if [ -n "$be" ]; then
7
- (cd be && npx eslint $be)
8
- fi
9
- fe=$(git diff --cached --name-only --diff-filter=ACMR --relative=fe -- '*.ts' '*.tsx' '*.mts' '*.cts' '*.js' '*.jsx' '*.mjs' '*.cjs' || true)
10
- if [ -n "$fe" ]; then
11
- (cd fe && npx eslint --max-warnings=0 --no-warn-ignored $fe)
12
- fi
5
+ # NUL-delimited paths keep filenames intact; bounded batches fit the Windows command line.
6
+ git diff --cached --name-only --diff-filter=ACMR -z --relative=be -- '*.ts' '*.mts' '*.cts' '*.js' '*.mjs' '*.cjs' |
7
+ xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then cd be && npx eslint -- "$@"; fi' sh || exit $?
8
+ git diff --cached --name-only --diff-filter=ACMR -z --relative=fe -- '*.ts' '*.tsx' '*.mts' '*.cts' '*.js' '*.jsx' '*.mjs' '*.cjs' |
9
+ xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then cd fe && npx eslint --max-warnings=0 --no-warn-ignored -- "$@"; fi' sh || exit $?
13
10
  styles=$(git diff --cached --name-only --diff-filter=ACMR --relative=fe -- '*.css' || true)
14
11
  if [ -n "$styles" ]; then
15
12
  (cd fe && npx stylelint $styles)
16
13
  fi
17
- formatted=$(git diff --cached --name-only --diff-filter=ACMR || true)
18
- if [ -n "$formatted" ]; then
19
- npx prettier --check --ignore-unknown $formatted
20
- fi
14
+ git diff --cached --name-only --diff-filter=ACMR -z |
15
+ xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then npx prettier --check --ignore-unknown -- "$@"; fi' sh || exit $?
@@ -10,6 +10,7 @@
10
10
  "test:e2e": "npm run typecheck:tests && cd be && jest --selectProjects e2e",
11
11
  "test:contract": "npm run typecheck:tests && cd be && jest --selectProjects contract",
12
12
  "test:stack": "starci app stack",
13
+ {{supabaseScripts}}
13
14
  "contract:emit": "starci app emit"
14
15
  }
15
16
  }
@@ -0,0 +1,7 @@
1
+ "db:start": "supabase start",
2
+ "db:stop": "supabase stop",
3
+ "db:reset": "supabase db reset",
4
+ "db:new": "supabase migration new",
5
+ "db:push": "supabase db push",
6
+ "db:types": "npm run contract:emit",
7
+ "db:lint": "{{appBinary}} check --fast",
@@ -7,13 +7,7 @@
7
7
  "test": "cd be && jest --selectProjects unit --coverage",
8
8
  "test:affected": "cd be && jest --selectProjects unit --passWithNoTests",
9
9
  "test:integration": "npm run typecheck:tests && cd be && jest --selectProjects integration",
10
- "db:start": "supabase start",
11
- "db:stop": "supabase stop",
12
- "db:reset": "supabase db reset",
13
- "db:new": "supabase migration new",
14
- "db:push": "supabase db push",
15
- "db:types": "npm run contract:emit",
16
- "db:lint": "{{appBinary}} check --fast",
10
+ {{> app/package-scripts/supabase.json}}
17
11
  "contract:emit": "{{appBinary}} emit"
18
12
  }
19
13
  }
@@ -1,3 +1,4 @@
1
+ {{header}}
1
2
  root = true
2
3
 
3
4
  [*]
@@ -1,2 +1,8 @@
1
- * text=auto
1
+ {{header}}
2
+ * text=auto eol=lf
2
3
  *.enc binary
4
+ # Scripts and the deploy data are mounted into Linux containers: CRLF there fails (set: Illegal option -).
5
+ *.sh text eol=lf
6
+ *.mjs text eol=lf
7
+ .starcistacks/** text eol=lf
8
+ .starcistacks/**/*.enc binary
@@ -0,0 +1,17 @@
1
+ {{header}}
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: npm
5
+ directory: /
6
+ schedule:
7
+ interval: weekly
8
+ - package-ecosystem: github-actions
9
+ directory: /
10
+ schedule:
11
+ interval: weekly
12
+ - package-ecosystem: docker
13
+ directories:
14
+ - /be/apps/*
15
+ - /fe/apps/*
16
+ schedule:
17
+ interval: weekly
@@ -1 +1 @@
1
- 22
1
+ {{nodeMajor}}
@@ -1,2 +1,2 @@
1
- # Set a project-owned age recipient before encrypting the first secret.
1
+ # Run `starci app secret init` to set a project-owned age recipient before encrypting the first secret.
2
2
  creation_rules: []
@@ -1,11 +1,144 @@
1
- # The stack declaration of the app, at the app root beside be/, fe/ and .starciwork (never under a side).
1
+ # The app declares its topology before any owner provisions a deployment.
2
+ # All-zero application digests are illustrative and must be replaced by verified release digests.
2
3
  schema: starci/application-stacks@1
4
+ sources:
5
+ - repository: "{{project}}"
6
+ backing:
7
+ primary:
8
+ provider: external-postgres
9
+ managed: true
10
+ components:
11
+ core:
12
+ role: service
13
+ image: "{{project}}/core:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
14
+ app:
15
+ role: service
16
+ image: "{{project}}/app:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
17
+ landing:
18
+ role: service
19
+ image: "{{project}}/landing:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
20
+ ingress:
21
+ role: ingress
22
+ stateful: true
23
+ volumes: [ingress-data, ingress-config-data]
24
+ image: caddy:2.10.2@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb
25
+ purpose: The single public entry point; TLS state stays on its declared persistent volume.
26
+ postgres:
27
+ role: stateful
28
+ image: postgres:16@sha256:1a6ab3f5345eb6dbe04a1349529caabdb0ab09293a09590fad07b2246bfa4b54
29
+ purpose: The full development database; production uses an owner-provisioned external PostgreSQL connection.
30
+ environments:
31
+ dev:
32
+ status: supported
33
+ runtime: docker-compose
34
+ composeFiles: [infra/compose/stack.yaml]
35
+ components:
36
+ core: { port: 3001 }
37
+ app: { port: 3000 }
38
+ landing: { port: 3002 }
39
+ postgres: { port: 5432 }
40
+ runbook: README.md
41
+ # Custody starts empty; add real sealed members after owner provisioning.
42
+ secrets: []
43
+ production:
44
+ status: supported
45
+ runtime: docker-swarm
46
+ composeFiles: [infra/swarm/stack.yaml]
47
+ components:
48
+ core: { port: 3001 }
49
+ app: { port: 3000 }
50
+ landing: { port: 3002 }
51
+ ingress: { httpPort: 80, httpsPort: 443 }
52
+ runbook: README.md
53
+ ingress:
54
+ component: ingress
55
+ hosts: ["{{project}}.example.invalid", "api.{{project}}.example.invalid", "www.{{project}}.example.invalid"]
56
+ dns:
57
+ - host: "{{project}}.example.invalid"
58
+ owner: Production operator
59
+ receipt: .starcistacks/production/infra/swarm/owner-actions.md#dns
60
+ - host: "api.{{project}}.example.invalid"
61
+ owner: Production operator
62
+ receipt: .starcistacks/production/infra/swarm/owner-actions.md#dns
63
+ - host: "www.{{project}}.example.invalid"
64
+ owner: Production operator
65
+ receipt: .starcistacks/production/infra/swarm/owner-actions.md#dns
66
+ tls:
67
+ owner: Production operator
68
+ receipt: .starcistacks/production/infra/swarm/owner-actions.md#tls
69
+ release:
70
+ imagesLock: .starcistacks/production/infra/swarm/releases/images.lock.yaml
71
+ pointer: .starcistacks/production/infra/swarm/releases/current.yaml
72
+ previous: .starcistacks/production/infra/swarm/releases/previous.yaml
73
+ healthAssertions: [API /health/live, API /health/ready, App /health/live, Landing /health/live, Signed-in GraphQL request over TLS]
74
+ backup:
75
+ - component: ingress
76
+ target: Owner-provisioned encrypted off-host storage for both ingress volumes
77
+ retention: Thirty daily snapshots
78
+ owner: Production operator
79
+ restoreProof: .starcistacks/production/infra/swarm/recovery/restore-proof.md
80
+ - component: primary
81
+ target: Provider recovery plus owner-provisioned encrypted off-host database exports
82
+ retention: Thirty daily exports
83
+ owner: Production operator
84
+ restoreProof: .starcistacks/production/infra/swarm/recovery/restore-proof.md
85
+ # Scaffolding seals generated placeholders to this app's own recipient; set real values before use.
86
+ secrets:
87
+ - name: primary-db-url
88
+ runtimeName: "{{project}}-production-primary-db-url-v1"
89
+ version: 1
90
+ where: secrets/primary-db-url
91
+ recipientPolicy: This app's own age recipient configured in .sops.yaml
92
+ keyCustody: SOPS_AGE_KEY in the host's untracked .claude/secret.env
93
+ # What `starci app stack` deploys (verbs: prepare, doctor, deploy, verify, rollback); names and shapes only, never a value.
94
+ # Add secrets.grants once the real sealed members exist under .starcistacks/production/secrets, and a backup block for stateful volumes.
95
+ deploy:
96
+ stack: {{project}}-production
97
+ # The image registry. The canon scaffold writes `public` (the owner's default: images cost nothing there); the value belongs to the app from now on
98
+ # and `starci app sync` never rewrites it. While it is public, `starci app stack build --push` scans every image for secret material first.
99
+ registry:
100
+ host: ghcr.io
101
+ visibility: {{registryVisibility}}
102
+ images:
103
+ core:
104
+ app: core
105
+ app:
106
+ app: app
107
+ landing:
108
+ app: landing
109
+ volumes:
110
+ - {{project}}-production-ingress-data
111
+ - {{project}}-production-ingress-config-data
112
+ verify:
113
+ http:
114
+ - name: core liveness
115
+ url: "https://api.{{project}}.example.invalid/health/live"
116
+ status: 200
117
+ retry: true
118
+ - name: app liveness
119
+ url: "https://{{project}}.example.invalid/health/live"
120
+ status: 200
121
+ retry: true
122
+ - name: landing liveness
123
+ url: "https://www.{{project}}.example.invalid/health/live"
124
+ status: 200
125
+ retry: true
126
+ k8s:
127
+ status: deferred
128
+ reason: This starter declares Docker Swarm production; no Kubernetes environment is provisioned.
3
129
  services:
4
130
  sonar:
5
131
  provider: sonarqube
6
132
  mode: local
7
133
  qualityGate: {{sonarGate}}
134
+ host: { local: http://127.0.0.1:9000 }
8
135
  stack:
9
136
  owner: host
10
137
  root: .claude/ext/sonar
11
138
  environment: dev
139
+ compose: compose.yaml
140
+ auth: token
141
+ ci: { wiring: optional-follow-up }
142
+ ownerAction:
143
+ needed: Provision the shared host Sonar project and its analysis credential through sealed custody.
144
+ reason: A fresh app declares its quality service without fabricating credentials or a successful analysis.
@@ -0,0 +1,16 @@
1
+ # Development stack
2
+
3
+ The development Docker Compose model contains the core API, the product and landing front ends, and a pinned local PostgreSQL database. Trust authentication is confined to this local, unpublished database.
4
+ Starter release images and external secrets must be prepared before starting the container model. Local source development remains available through the app scripts.
5
+
6
+ | Command | Operation |
7
+ | --- | --- |
8
+ | prepare | Build the app images and provide the local database connection through sealed custody. Materialize its real sealed member to the owner-controlled file `/run/starci-secrets/{{project}}/dev/primary-db-url`; Docker Compose mounts that file into the API. |
9
+ | doctor | From this directory, run `docker compose config -f infra/compose/stack.yaml`. Confirm image, secret and database availability. |
10
+ | up | Run `docker compose -f infra/compose/stack.yaml up -d` from this directory after preparation. |
11
+ | status | Run `docker compose -f infra/compose/stack.yaml ps`. |
12
+ | logs | Run `docker compose -f infra/compose/stack.yaml logs core`; never print mounted credentials. |
13
+ | down | Run `docker compose -f infra/compose/stack.yaml down`. |
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.
@@ -0,0 +1,5 @@
1
+ {
2
+ "environment": "dev",
3
+ "provider": "docker-compose",
4
+ "project": "{{project}}"
5
+ }
@@ -0,0 +1,71 @@
1
+ # Rendered development model. App images and owner infrastructure must be provisioned before use.
2
+ version: "3.8"
3
+ services:
4
+ core:
5
+ image: "{{project}}/core:v0.0.0"
6
+ environment:
7
+ NODE_ENV: development
8
+ PORT: "3001"
9
+ HTTP_SECURITY_ALLOWED_ORIGINS: http://127.0.0.1:3000
10
+ PRIMARY_DB_URL_FILE: /run/secrets/primary-db-url
11
+ secrets:
12
+ - source: primary-db-url
13
+ target: primary-db-url
14
+ ports: ["3001:3001"]
15
+ networks: [app]
16
+ healthcheck:
17
+ 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))"]
18
+ interval: 30s
19
+ timeout: 5s
20
+ start_period: 20s
21
+ retries: 3
22
+ app:
23
+ image: "{{project}}/app:v0.0.0"
24
+ environment:
25
+ NODE_ENV: development
26
+ PORT: "3000"
27
+ HOSTNAME: 0.0.0.0
28
+ NEXT_PUBLIC_SITE_URL: http://127.0.0.1:3000
29
+ ports: ["3000:3000"]
30
+ networks: [app]
31
+ healthcheck:
32
+ 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))"]
33
+ interval: 30s
34
+ timeout: 5s
35
+ start_period: 20s
36
+ retries: 3
37
+ landing:
38
+ image: "{{project}}/landing:v0.0.0"
39
+ environment:
40
+ NODE_ENV: development
41
+ PORT: "3002"
42
+ HOSTNAME: 0.0.0.0
43
+ NEXT_PUBLIC_APP_URL: http://127.0.0.1:3000
44
+ ports: ["3002:3002"]
45
+ networks: [app]
46
+ healthcheck:
47
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3002/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
48
+ interval: 30s
49
+ timeout: 5s
50
+ start_period: 20s
51
+ retries: 3
52
+ postgres:
53
+ image: postgres:16@sha256:1a6ab3f5345eb6dbe04a1349529caabdb0ab09293a09590fad07b2246bfa4b54
54
+ environment:
55
+ POSTGRES_DB: "{{project}}"
56
+ POSTGRES_HOST_AUTH_METHOD: trust
57
+ volumes: [postgres-data:/var/lib/postgresql/data]
58
+ networks: [app]
59
+ healthcheck:
60
+ test: ["CMD-SHELL", "pg_isready -U postgres -d {{project}}"]
61
+ interval: 10s
62
+ timeout: 5s
63
+ retries: 5
64
+ networks:
65
+ app:
66
+ driver: bridge
67
+ secrets:
68
+ primary-db-url:
69
+ file: /run/starci-secrets/{{project}}/dev/primary-db-url
70
+ volumes:
71
+ postgres-data:
@@ -0,0 +1,14 @@
1
+ # Environment key roster
2
+
3
+ This roster declares names only. Store 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 and CLI primary database connection |
10
+ | `NEXT_PUBLIC_SITE_URL` | Product front-end site URL |
11
+ | `NEXT_PUBLIC_GRAPHQL_URL` | Product front-end GraphQL transport |
12
+ | `NEXT_PUBLIC_APP_URL` | Landing front-end product link |
13
+
14
+ Public front-end configuration is supplied at build time and stays outside sealed custody.
@@ -0,0 +1,37 @@
1
+ # Production stack
2
+
3
+ The tracked model declares Docker Swarm application services and one digest-pinned Caddy ingress.
4
+ The production database is external PostgreSQL; the owner supplies its least-privilege connection through sealed custody.
5
+ The model is a deployment declaration. It contains no owner credentials, real DNS receipt, completed release or restore proof. The public records under `.starcistacks/production/infra/swarm/` mark those owner-run operations as pending. Its all-zero application image digests are illustrative and must be replaced before deployment.
6
+
7
+ The runtime template tracks no encrypted members. Scaffolding generates the declared database member with a placeholder value encrypted to this app's own recipient in `.sops.yaml`. Replace it with `starci app secret set production` using the matching host age identity in untracked local custody. Each Docker secret contains its corresponding key's real value; the API receives it through the declared mounted file.
8
+
9
+ | Command | Operation |
10
+ | --- | --- |
11
+ | 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. |
12
+ | doctor | Run `starci app stack doctor --env production` (read-only): docker, swarm, volumes, services, secrets, configs and the release pointers on the intended manager. |
13
+ | 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`. |
14
+ | 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. |
15
+ | logs | Run `docker service logs {{project}}-production_core` on the manager; never include secret values in a receipt. |
16
+ | down | After the owner's removal decision, run `docker stack rm {{project}}-production`; persistent external volumes remain in owner custody. |
17
+ | 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. |
18
+
19
+ ## Owner actions before the first release
20
+
21
+ Every item is pending. Swarm initialization, provider URIs, DNS changes and key rotation are owner-run steps.
22
+
23
+ | Area | Required owner action and evidence |
24
+ | --- | --- |
25
+ | Swarm and placement | Initialize the intended manager; label the intended stateful node `{{project}}=production`. Only that node owns the external ingress volumes. |
26
+ | DNS | Replace the reserved `example.invalid` hosts consistently in the manifest, Caddyfile and public configuration; publish address records for the product, API and landing hosts and retain a provider receipt in `.starcistacks/production/infra/swarm/owner-actions.md`. |
27
+ | 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`. |
28
+ | Database | Provision external PostgreSQL and its least-privilege application role. Record the provider URI and recovery owner without copying credentials here. |
29
+ | Secret custody | Replace the generated placeholder with the real value in the manifest's declared `.starcistacks/production/secrets/primary-db-url.enc`; record its key in `.starcistacks/production/runtime/env/KEYS.md`. The age identity stays only in the host's untracked `.claude/secret.env`. |
30
+ | External secrets | Materialize the sealed members in owner custody and create `{{project}}-production-primary-db-url-v1`. The API reads mounted files; rotation creates new versioned names before updating the model. |
31
+ | Public build configuration | Build the front end with its declared public site and GraphQL URLs. Public browser values stay outside sealed secret custody. |
32
+ | Immutable release | Replace the illustrative all-zero application digests in the manifest, model and `.starcistacks/production/infra/swarm/releases/images.lock.yaml` with the verified release digests. 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 pointer and update `.starcistacks/production/infra/swarm/releases/current.yaml` after verification. |
33
+ | 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. |
34
+ | Backup | Provision the manifest's 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. |
35
+ | 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. |
36
+
37
+ No host scheduler is installed. Scheduled application work belongs to the back-end scheduler or an explicitly declared replicated job.
@@ -0,0 +1,5 @@
1
+ {
2
+ "environment": "production",
3
+ "provider": "external-postgres",
4
+ "project": "{{project}}"
5
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ admin 127.0.0.1:2019
3
+ }
4
+
5
+ {{project}}.example.invalid {
6
+ reverse_proxy app:3000
7
+ }
8
+
9
+ api.{{project}}.example.invalid {
10
+ reverse_proxy core:3001
11
+ }
12
+
13
+ www.{{project}}.example.invalid {
14
+ reverse_proxy landing:3002
15
+ }
@@ -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`, `api.{{project}}.example.invalid` and `www.{{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 both 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 all three 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 external PostgreSQL database and both external ingress volumes, `{{project}}-production-ingress-data` and `{{project}}-production-ingress-config-data`. Provision provider recovery 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 a database backup and both volume snapshots into isolated infrastructure. Record the actual off-host destination, retention, 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,9 @@
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
+ core: "{{project}}/core:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
7
+ app: "{{project}}/app:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
8
+ landing: "{{project}}/landing:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
9
+ 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.