@starci/hfs 4.3.0 → 4.4.1
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.
- package/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/db/migrate.mjs +361 -0
- package/db/post-cutover.mjs +136 -0
- package/emit/contracts.mjs +2 -2
- package/emit/db-types.mjs +12 -3
- package/lint/run.mjs +3 -3
- package/package.json +4 -1
- package/release/gate.mjs +298 -0
- package/release/index.mjs +103 -0
- package/release/push.mjs +110 -0
- package/report/sonar.mjs +1 -1
- package/runtime/config.example.yaml +7 -6
- package/runtime/engine/config.mjs +10 -18
- package/runtime/engine/removed-vocabulary.mjs +0 -2
- package/runtime/knowledge/hfs/canon-pins.yaml +11 -11
- package/runtime/knowledge/hfs/fe-stack.yaml +22 -1
- package/runtime/knowledge/hfs/rules.yaml +2855 -163
- package/runtime/knowledge/hfs/slots.yaml +333 -62
- package/runtime/knowledge/patterns/be/api.yaml +32 -5
- package/runtime/knowledge/patterns/be/cli.yaml +14 -4
- package/runtime/knowledge/patterns/be/event-bus.yaml +3 -3
- package/runtime/knowledge/patterns/be/jobs.yaml +20 -2
- package/runtime/knowledge/patterns/be/projections.yaml +4 -2
- package/runtime/knowledge/patterns/be/queues.yaml +11 -3
- package/runtime/knowledge/patterns/be/reactors.yaml +20 -1
- package/runtime/knowledge/patterns/be/realtime.yaml +25 -3
- package/runtime/knowledge/patterns/be/saga.yaml +20 -3
- package/runtime/knowledge/patterns/be/webhooks.yaml +23 -4
- package/runtime/knowledge/patterns/fe/folder.yaml +1 -0
- package/runtime/knowledge/sonar-gate.yaml +1 -1
- package/runtime/modules/kernel/failure-codes.yaml +3091 -43
- package/runtime/modules/kernel/removed-vocabulary.yaml +30 -0
- package/runtime/modules/models/runtimes.yaml +5 -7
- package/runtime/modules/schemas/application-stacks.schema.yaml +663 -0
- package/runtime/packages/cli/src/catalog.generated.mjs +13769 -0
- package/runtime/packages/cli/src/validate-args.mjs +213 -0
- package/runtime/scripts/api/git/add.mjs +5 -0
- package/runtime/scripts/api/git/init.mjs +7 -0
- package/runtime/scripts/api/git/lib.mjs +4 -1
- package/runtime/scripts/api/git/tag.mjs +5 -0
- package/runtime/scripts/api/node/lib.mjs +20 -0
- package/runtime/scripts/api/node/run-node.mjs +6 -0
- package/runtime/scripts/api/sops/lib.mjs +42 -1
- package/runtime/scripts/api/sops/selected-age-recipient.mjs +7 -0
- package/runtime/scripts/api/supabase/database-dump.mjs +5 -0
- package/runtime/scripts/api/supabase/database-query.mjs +5 -0
- package/runtime/scripts/api/supabase/lib.mjs +44 -0
- package/runtime/scripts/api/supabase/migration-repair.mjs +5 -0
- package/runtime/scripts/hfs/app-wiring.mjs +201 -0
- package/runtime/scripts/hfs/architecture/backend-app-files.mjs +1 -8
- package/runtime/scripts/hfs/architecture/backend.mjs +2 -7
- package/runtime/scripts/hfs/architecture/client-reaches-server.mjs +6 -3
- package/runtime/scripts/hfs/architecture/config.mjs +1 -1
- package/runtime/scripts/hfs/architecture/dead-exports-bindings.mjs +149 -0
- package/runtime/scripts/hfs/architecture/dead-exports.mjs +9 -41
- package/runtime/scripts/hfs/architecture/default-deny.mjs +8 -6
- package/runtime/scripts/hfs/architecture/frontend-world.mjs +1 -1
- package/runtime/scripts/hfs/architecture/function-spec-providers.mjs +153 -0
- package/runtime/scripts/hfs/architecture/hfs.mjs +3 -3
- package/runtime/scripts/hfs/architecture/index.mjs +1 -1
- package/runtime/scripts/hfs/architecture/module-per-transport.mjs +28 -13
- package/runtime/scripts/hfs/architecture/next-data-inference.mjs +176 -0
- package/runtime/scripts/hfs/architecture/next-data-symbols.mjs +26 -0
- package/runtime/scripts/hfs/architecture/next-data.mjs +31 -23
- package/runtime/scripts/hfs/architecture/reachability.mjs +14 -0
- package/runtime/scripts/hfs/architecture/register-once.mjs +2 -2
- package/runtime/scripts/hfs/architecture/source-names.mjs +48 -3
- package/runtime/scripts/hfs/architecture/supabase-ast.mjs +211 -11
- package/runtime/scripts/hfs/architecture/supabase-be.mjs +1 -1
- package/runtime/scripts/hfs/architecture/supabase.mjs +59 -21
- package/runtime/scripts/hfs/architecture/surface.mjs +2 -1
- package/runtime/scripts/hfs/architecture/tiers.mjs +4 -4
- package/runtime/scripts/hfs/architecture/unit-spec-providers.mjs +8 -2
- package/runtime/scripts/hfs/architecture.mjs +1 -1
- package/runtime/scripts/hfs/check-results.mjs +28 -0
- package/runtime/scripts/hfs/check.mjs +46 -47
- package/runtime/scripts/hfs/coverage-from.mjs +70 -0
- package/runtime/scripts/hfs/coverage-scope.mjs +1 -1
- package/runtime/scripts/hfs/db-baseline-verb.mjs +276 -0
- package/runtime/scripts/hfs/db-plan-verb.mjs +254 -0
- package/runtime/scripts/hfs/db-restamp-verb.mjs +60 -0
- package/runtime/scripts/hfs/declaration-shape.mjs +39 -3
- package/runtime/scripts/hfs/doc-commands.mjs +367 -0
- package/runtime/scripts/hfs/edition-slots.mjs +2 -2
- package/runtime/scripts/hfs/example-secrets.mjs +158 -0
- package/runtime/scripts/hfs/manifest-shape.mjs +69 -9
- package/runtime/scripts/hfs/param-names.mjs +1 -1
- package/runtime/scripts/hfs/refusal-codes.mjs +6 -0
- package/runtime/scripts/hfs/rule-catalog.mjs +158 -11
- package/runtime/scripts/hfs/rule-params-shape.mjs +22 -10
- package/runtime/scripts/hfs/rules/a15-findings.mjs +88 -0
- package/runtime/scripts/hfs/rules/app-env-required.mjs +20 -0
- package/runtime/scripts/hfs/rules/app-root.mjs +2 -2
- package/runtime/scripts/hfs/rules/assets.mjs +79 -0
- package/runtime/scripts/hfs/rules/boot-proof.mjs +16 -0
- package/runtime/scripts/hfs/rules/canon-copy-drift.mjs +59 -0
- package/runtime/scripts/hfs/rules/cli.mjs +1 -1
- package/runtime/scripts/hfs/rules/contract-compat.mjs +1 -1
- package/runtime/scripts/hfs/rules/contract.mjs +67 -6
- package/runtime/scripts/hfs/rules/coverage-below.mjs +230 -0
- package/runtime/scripts/hfs/rules/database-access.mjs +343 -0
- package/runtime/scripts/hfs/rules/database-baseline.mjs +142 -0
- package/runtime/scripts/hfs/rules/database-config.mjs +250 -2
- package/runtime/scripts/hfs/rules/database-constants.mjs +9 -0
- package/runtime/scripts/hfs/rules/database-migrations.mjs +286 -7
- package/runtime/scripts/hfs/rules/database-plpgsql.mjs +119 -9
- package/runtime/scripts/hfs/rules/database-queue-sources.mjs +176 -0
- package/runtime/scripts/hfs/rules/database-queues.mjs +361 -0
- package/runtime/scripts/hfs/rules/database-sql.mjs +91 -9
- package/runtime/scripts/hfs/rules/database.mjs +9 -0
- package/runtime/scripts/hfs/rules/deploy-scan.mjs +192 -0
- package/runtime/scripts/hfs/rules/deploy-workflow.mjs +219 -0
- package/runtime/scripts/hfs/rules/doc-fresh.mjs +286 -0
- package/runtime/scripts/hfs/rules/docker-health.mjs +249 -0
- package/runtime/scripts/hfs/rules/docker.mjs +24 -7
- package/runtime/scripts/hfs/rules/edition.mjs +9 -8
- package/runtime/scripts/hfs/rules/env-parity.mjs +373 -0
- package/runtime/scripts/hfs/rules/env-value-shape.mjs +113 -0
- package/runtime/scripts/hfs/rules/event-bus.mjs +3 -2
- package/runtime/scripts/hfs/rules/event-tables.mjs +100 -0
- package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +115 -15
- package/runtime/scripts/hfs/rules/fe-stack.mjs +57 -0
- package/runtime/scripts/hfs/rules/feature-files.mjs +28 -0
- package/runtime/scripts/hfs/rules/frontend-tree.mjs +54 -35
- package/runtime/scripts/hfs/rules/integration-specs.mjs +3 -2
- package/runtime/scripts/hfs/rules/lexicon.mjs +62 -0
- package/runtime/scripts/hfs/rules/lite-proof-lane.mjs +89 -0
- package/runtime/scripts/hfs/rules/monorepo.mjs +14 -1
- package/runtime/scripts/hfs/rules/pipeline.mjs +8 -1
- package/runtime/scripts/hfs/rules/release-provenance.mjs +211 -0
- package/runtime/scripts/hfs/rules/saga-delivery.mjs +66 -0
- package/runtime/scripts/hfs/rules/saga.mjs +8 -16
- package/runtime/scripts/hfs/rules/script-hygiene.mjs +151 -0
- package/runtime/scripts/hfs/rules/secret-custody-only.mjs +65 -0
- package/runtime/scripts/hfs/rules/secrets.mjs +13 -0
- package/runtime/scripts/hfs/rules/services.mjs +4 -4
- package/runtime/scripts/hfs/rules/stack-tooling.mjs +93 -0
- package/runtime/scripts/hfs/rules/stacks-deploy.mjs +76 -0
- package/runtime/scripts/hfs/rules/stacks-ingress.mjs +87 -0
- package/runtime/scripts/hfs/rules/stacks-lite-backing.mjs +111 -0
- package/runtime/scripts/hfs/rules/stacks-release.mjs +366 -0
- package/runtime/scripts/hfs/rules/stacks-runtime.mjs +41 -1
- package/runtime/scripts/hfs/rules/stacks-swarm.mjs +417 -0
- package/runtime/scripts/hfs/rules/supabase-secrets.mjs +2 -2
- package/runtime/scripts/hfs/rules/supply-chain.mjs +167 -0
- package/runtime/scripts/hfs/rules/unused-symbol-flow.mjs +101 -0
- package/runtime/scripts/hfs/rules/unused-symbol-ledger.mjs +77 -0
- package/runtime/scripts/hfs/rules/unused-symbol-translators.mjs +165 -0
- package/runtime/scripts/hfs/rules/unused-symbol-values.mjs +103 -0
- package/runtime/scripts/hfs/rules/unused-symbol.mjs +320 -0
- package/runtime/scripts/hfs/runtime-rules/source-ast.mjs +185 -0
- package/runtime/scripts/hfs/runtime-rules/workflow-source.mjs +19 -0
- package/runtime/scripts/hfs/sealed-members.mjs +101 -0
- package/runtime/scripts/hfs/secret-bootstrap-crypto.mjs +200 -0
- package/runtime/scripts/hfs/secret-edit.mjs +170 -0
- package/runtime/scripts/hfs/secret-init.mjs +127 -19
- package/runtime/scripts/hfs/secret-sops.mjs +38 -6
- package/runtime/scripts/hfs/secret-store.mjs +56 -54
- package/runtime/scripts/hfs/secret.mjs +34 -5
- package/runtime/scripts/hfs/slot-imports.mjs +18 -5
- package/runtime/scripts/hfs/slots.mjs +3 -2
- package/runtime/scripts/hfs/stack-config-kit.mjs +34 -0
- package/runtime/scripts/hfs/stack-deploy-config.mjs +313 -0
- package/runtime/scripts/hfs/stack-ingress-config.mjs +237 -0
- package/runtime/scripts/hfs/stacks-gate.mjs +414 -0
- package/runtime/scripts/hfs/starcistacks-runtime.mjs +61 -0
- package/runtime/scripts/hfs/typescript-programs.mjs +0 -8
- package/runtime/scripts/lib/command-tokens.mjs +126 -0
- package/runtime/scripts/lib/compose-values.mjs +11 -0
- package/runtime/scripts/lib/deployment-findings.mjs +7 -0
- package/runtime/scripts/lib/env.mjs +2 -2
- package/runtime/scripts/lib/git.mjs +1 -1
- package/runtime/scripts/lib/i18n.mjs +0 -2
- package/runtime/scripts/lib/json-clone.mjs +61 -0
- package/runtime/scripts/lib/language.mjs +1 -1
- package/runtime/scripts/lib/list.mjs +4 -0
- package/runtime/scripts/lib/roots.mjs +2 -4
- package/runtime/scripts/lib/runtime-example.mjs +13 -0
- package/runtime/scripts/lib/secret-patterns.mjs +60 -5
- package/runtime/scripts/lib/sql-ast.mjs +32 -0
- package/runtime/scripts/lib/stack-services.mjs +1 -1
- package/runtime/scripts/lib/swarm-stack.mjs +5 -18
- package/runtime/scripts/lib/trim-end.mjs +8 -0
- package/runtime/scripts/lib/ts-analysis.mjs +5 -2
- package/runtime/scripts/lib/ts-ast.mjs +27 -2
- package/runtime/scripts/lib/workflow-events.mjs +8 -0
- package/scaffold/add-app.mjs +77 -59
- package/scaffold/add-cli-lite.mjs +14 -6
- package/scaffold/add-compose.mjs +79 -0
- package/scaffold/add-database-lite.mjs +14 -0
- package/scaffold/add-fe-overlay.mjs +1 -0
- package/scaffold/add-fe-page.mjs +1 -0
- package/scaffold/add-inbox-lite.mjs +74 -42
- package/scaffold/add-table.mjs +110 -87
- package/scaffold/add.mjs +159 -44
- package/scaffold/app.mjs +124 -39
- package/scaffold/edition-gate.mjs +3 -3
- package/scaffold/lite-exports.mjs +2 -1
- package/scaffold/service.mjs +2 -2
- package/scaffold/supabase-ports.mjs +1 -1
- package/src/main.mjs +229 -116
- package/stack/age-install.mjs +37 -0
- package/stack/backup.mjs +100 -0
- package/stack/build-args.mjs +42 -0
- package/stack/build.mjs +173 -0
- package/stack/cli.mjs +130 -0
- package/stack/config.mjs +57 -0
- package/stack/context.mjs +57 -0
- package/stack/converge.mjs +107 -0
- package/stack/deploy.mjs +301 -0
- package/stack/digest.mjs +16 -0
- package/stack/docker-transport.mjs +53 -0
- package/stack/edge-alias.mjs +118 -0
- package/stack/errors.mjs +21 -0
- package/stack/image-scan.mjs +152 -0
- package/stack/ingress-create.mjs +114 -0
- package/stack/ingress-publish.mjs +273 -0
- package/stack/ingress.mjs +706 -0
- package/stack/jobs.mjs +51 -0
- package/stack/live-restore.mjs +177 -0
- package/stack/prepare.mjs +266 -0
- package/stack/private-file.mjs +22 -0
- package/stack/provision.mjs +90 -0
- package/stack/prune.mjs +46 -0
- package/stack/release-store.mjs +87 -0
- package/stack/remote.mjs +205 -0
- package/stack/render.mjs +149 -0
- package/stack/retire.mjs +47 -0
- package/stack/sealed.mjs +149 -0
- package/stack/task.mjs +42 -0
- package/stack/verify.mjs +99 -0
- package/sync/ci-commands.mjs +13 -0
- package/sync/format.mjs +1 -1
- package/sync/hygiene.mjs +1 -1
- package/sync/index.mjs +110 -54
- package/sync/stack-images.mjs +127 -0
- package/templates/app/ci-workflows/github/workflows/ci.yml +5 -1
- package/templates/app/ci-workflows/github/workflows/images.yml +15 -3
- package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +148 -0
- package/templates/app/ci-workflows-lite/github/workflows/ci.yml +7 -3
- package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +38 -6
- package/templates/app/ci-workflows-lite/github/workflows/images.yml +14 -2
- package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +148 -0
- package/templates/app/codegen-graphql.mjs.partial +13 -2
- package/templates/app/codegen-lite/scripts/codegen.mjs +6 -1
- package/templates/app/codegen-prelude.mjs.partial +8 -0
- package/templates/app/gitignore +3 -0
- package/templates/app/gitignore-lite +3 -0
- package/templates/app/package-scripts/package.json +1 -0
- package/templates/app/package-scripts/supabase.json +7 -0
- package/templates/app/package-scripts-lite/package.json +1 -7
- package/templates/app/skeleton/.editorconfig +1 -0
- package/templates/app/skeleton/.gitattributes +7 -1
- package/templates/app/skeleton/.github/dependabot.yml +17 -0
- package/templates/app/skeleton/.nvmrc +1 -1
- package/templates/app/skeleton/.starcistacks/application-stacks.yaml +134 -1
- package/templates/app/skeleton/.starcistacks/dev/README.md +16 -0
- package/templates/app/skeleton/.starcistacks/dev/environment.json +5 -0
- package/templates/app/skeleton/.starcistacks/dev/infra/compose/stack.yaml +71 -0
- package/templates/app/skeleton/.starcistacks/dev/runtime/env/KEYS.md +14 -0
- package/templates/app/skeleton/.starcistacks/production/README.md +37 -0
- package/templates/app/skeleton/.starcistacks/production/environment.json +5 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/Caddyfile +15 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/owner-actions.md +11 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/recovery/restore-proof.md +7 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/current.yaml +6 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/images.lock.yaml +9 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/previous.yaml +6 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/stack.yaml +142 -0
- package/templates/app/skeleton/.starcistacks/production/runtime/env/KEYS.md +14 -0
- package/templates/app/skeleton/README.md +6 -6
- package/templates/app/skeleton/scripts/codegen.mjs +1 -2
- package/templates/app/skeleton-lite/.editorconfig +16 -0
- package/templates/app/skeleton-lite/.gitattributes +8 -0
- package/templates/app/skeleton-lite/.github/dependabot.yml +17 -0
- package/templates/app/skeleton-lite/.nvmrc +1 -0
- package/templates/app/skeleton-lite/.sops.yaml +3 -2
- package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +178 -1
- package/templates/app/skeleton-lite/.starcistacks/dev/README.md +20 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/environment.json +2 -1
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/Caddyfile +16 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/owner-actions.md +11 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/recovery/restore-proof.md +7 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/current.yaml +6 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/images.lock.yaml +8 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/previous.yaml +6 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/stack.yaml +120 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/runtime/env/KEYS.md +18 -0
- package/templates/app/skeleton-lite/.starcistacks/production/README.md +38 -0
- package/templates/app/skeleton-lite/.starcistacks/production/environment.json +6 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/Caddyfile +11 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/owner-actions.md +11 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/recovery/restore-proof.md +7 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/releases/current.yaml +6 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/releases/images.lock.yaml +8 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/releases/previous.yaml +6 -0
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/stack.yaml +121 -0
- package/templates/app/skeleton-lite/.starcistacks/production/runtime/env/KEYS.md +21 -0
- package/templates/app/skeleton-lite/.starciwork/brand/index.yaml +12 -0
- package/templates/app/skeleton-lite/README.md +5 -3
- package/templates/app/skeleton-lite/supabase/config.toml +8 -1
- package/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql +15 -6
- package/templates/app/upgrade-full/.starcistacks/dev/README.md +13 -7
- package/templates/be/image/worker/Dockerfile +1 -1
- package/templates/be/inbox/database-client.spec.ts.tpl +17 -18
- package/templates/be/inbox/database-client.ts.tpl +12 -11
- package/templates/be/inbox/delivery-recorded.event.ts.tpl +36 -0
- package/templates/be/inbox/event-index.ts.tpl +1 -0
- package/templates/be/inbox/events.json.tpl +10 -0
- package/templates/be/inbox/migration.sql.tpl +1 -0
- package/templates/be/inbox/platform/event-bus/event-bus.contracts.ts.tpl +42 -0
- package/templates/be/inbox/platform/event-bus/event-bus.decorators.ts.tpl +9 -0
- package/templates/be/inbox/platform/event-bus/event-bus.module-definition.ts.tpl +6 -0
- package/templates/be/inbox/platform/event-bus/event-bus.module.ts.tpl +19 -0
- package/templates/be/inbox/platform/event-bus/event-bus.options.ts.tpl +2 -0
- package/templates/be/inbox/platform/event-bus/event-bus.port.ts.tpl +16 -0
- package/templates/be/inbox/platform/event-bus/event-bus.service.spec.ts.tpl +45 -0
- package/templates/be/inbox/platform/event-bus/event-bus.service.ts.tpl +15 -0
- package/templates/be/inbox/platform/event-bus/index.ts.tpl +5 -0
- package/templates/be/inbox/platform/event-bus/persistence/event-bus.sql.ts.tpl +5 -0
- package/templates/be/inbox/platform/inbox/inbox.decorators.ts.tpl +9 -0
- package/templates/be/inbox/platform/inbox/inbox.module-definition.ts.tpl +6 -0
- package/templates/be/inbox/platform/inbox/inbox.module.ts.tpl +19 -0
- package/templates/be/inbox/platform/inbox/inbox.options.ts.tpl +2 -0
- package/templates/be/inbox/platform/inbox/inbox.port.ts.tpl +10 -0
- package/templates/be/inbox/platform/inbox/inbox.service.spec.ts.tpl +41 -0
- package/templates/be/inbox/platform/inbox/inbox.service.ts.tpl +19 -0
- package/templates/be/inbox/platform/inbox/index.ts.tpl +3 -0
- package/templates/be/inbox/platform/inbox/persistence/inbox.sql.ts.tpl +7 -0
- package/templates/be/inbox/platform/migration.sql.tpl +48 -0
- package/templates/be/inbox/service.spec.ts.tpl +42 -9
- package/templates/be/inbox/service.ts.tpl +23 -8
- package/templates/be/inbox/webhook-door.spec.ts.tpl +1 -1
- package/templates/be/inbox/webhook-door.ts.tpl +2 -2
- package/templates/be/patterns/api/feature.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/api/feature.module.ts.tpl +2 -1
- package/templates/be/patterns/api/feature.options.ts.tpl +2 -0
- package/templates/be/patterns/api/graphql.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/api/graphql.module.ts.tpl +3 -2
- package/templates/be/patterns/api/graphql.options.ts.tpl +2 -0
- package/templates/be/patterns/cli/group.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/cli/group.module.ts.tpl +2 -1
- package/templates/be/patterns/cli/group.options.ts.tpl +2 -0
- package/templates/be/patterns/event-bus/platform/errors/event-bus.error.ts.tpl +0 -3
- package/templates/be/patterns/event-bus/platform/messages/event-bus.messages.ts.tpl +0 -2
- package/templates/be/patterns/jobs/job.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/jobs/job.module.ts.tpl +2 -1
- package/templates/be/patterns/jobs/job.options.ts.tpl +2 -0
- package/templates/be/patterns/jobs/job.queue.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/jobs/job.queue.module.ts.tpl +6 -3
- package/templates/be/patterns/jobs/job.queue.options.ts.tpl +2 -0
- package/templates/be/patterns/jobs/platform/fenced.processor.spec.ts.tpl +3 -1
- package/templates/be/patterns/outbox/platform/outbox-relay.policy.spec.ts.tpl +25 -9
- package/templates/be/patterns/queues/platform/queue.config.ts.tpl +1 -1
- package/templates/be/patterns/queues/platform/queue.index.ts.tpl +1 -1
- package/templates/be/patterns/queues/platform/queue.module-definition.ts.tpl +2 -2
- package/templates/be/patterns/queues/platform/queue.module.ts.tpl +11 -0
- package/templates/be/patterns/queues/platform/queue.options.ts.tpl +10 -0
- package/templates/be/patterns/queues/queue.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/queues/queue.module.ts.tpl +2 -1
- package/templates/be/patterns/queues/queue.options.ts.tpl +2 -0
- package/templates/be/patterns/reactors/message.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/reactors/message.module.ts.tpl +6 -3
- package/templates/be/patterns/reactors/message.options.ts.tpl +2 -0
- package/templates/be/patterns/reactors/reactor.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/reactors/reactor.module.ts.tpl +2 -1
- package/templates/be/patterns/reactors/reactor.options.ts.tpl +2 -0
- package/templates/be/patterns/realtime/channel.gateway.spec.ts.tpl +188 -0
- package/templates/be/patterns/realtime/channel.gateway.ts.tpl +22 -0
- package/templates/be/patterns/realtime/channel.graphql.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/realtime/channel.graphql.module.ts.tpl +2 -1
- package/templates/be/patterns/realtime/channel.graphql.options.ts.tpl +2 -0
- package/templates/be/patterns/realtime/channel.websocket.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/realtime/channel.websocket.module.ts.tpl +110 -0
- package/templates/be/patterns/realtime/channel.websocket.options.ts.tpl +7 -0
- package/templates/be/patterns/saga/saga.message.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/saga/saga.message.module.ts.tpl +6 -3
- package/templates/be/patterns/saga/saga.message.options.ts.tpl +2 -0
- package/templates/be/patterns/saga/saga.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/saga/saga.module.ts.tpl +2 -1
- package/templates/be/patterns/saga/saga.options.ts.tpl +2 -0
- package/templates/be/patterns/webhooks/webhook.http.module-definition.ts.tpl +6 -0
- package/templates/be/patterns/webhooks/webhook.http.module.ts.tpl +2 -1
- package/templates/be/patterns/webhooks/webhook.http.options.ts.tpl +2 -0
- package/templates/be/platform/graphql/localize-errors.mapper.spec.ts +80 -26
- package/templates/be/platform/graphql/localize-errors.mapper.ts +2 -5
- package/templates/be/skeleton/apps/__app__/src/app.module.ts +11 -9
- package/templates/be/skeleton/apps/__app__/src/compose/api.ts +4 -0
- package/templates/be/skeleton/apps/__app__/src/compose/domain.ts +11 -0
- package/templates/be/skeleton/apps/__app__/src/compose/platform.ts +2 -0
- package/templates/be/skeleton/apps/__app__/src/compose/system.ts +5 -0
- package/templates/be/skeleton/apps/__app__/src/compose/webhooks.ts +4 -0
- package/templates/be/skeleton/apps/__app__/src/main.ts +15 -1
- package/templates/be/skeleton/apps/cli/src/app.module.ts +3 -13
- package/templates/be/skeleton/apps/cli/src/cli.options.ts +6 -14
- package/templates/be/skeleton/apps/cli/src/compose/cli.ts +5 -0
- package/templates/be/skeleton/apps/cli/src/compose/platform.ts +24 -0
- package/templates/be/skeleton/src/features/api/system-health/application/check-readiness.contracts.ts +2 -0
- package/templates/be/skeleton/src/features/api/system-health/application/check-readiness.handler.ts +22 -0
- package/templates/be/skeleton/src/features/api/system-health/application/check-readiness.query.ts +11 -0
- package/templates/be/skeleton/src/features/api/system-health/system-health.module-definition.ts +6 -0
- package/templates/be/skeleton/src/features/api/system-health/system-health.module.ts +5 -3
- package/templates/be/skeleton/src/features/api/system-health/system-health.options.ts +2 -0
- package/templates/be/skeleton/src/features/api/system-health/transport/http/ready.controller.ts +19 -0
- package/templates/be/skeleton/src/features/api/system-health/transport/http/system-health-http.module-definition.ts +6 -0
- package/templates/be/skeleton/src/features/api/system-health/transport/http/system-health-http.module.ts +8 -3
- package/templates/be/skeleton/src/features/api/system-health/transport/http/system-health-http.options.ts +2 -0
- package/templates/be/skeleton/src/features/cli/cli.module-definition.ts +6 -0
- package/templates/be/skeleton/src/features/cli/cli.module.ts +3 -2
- package/templates/be/skeleton/src/features/cli/cli.options.ts +2 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.module-definition.ts +6 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.module.ts +2 -1
- package/templates/be/skeleton/src/features/cli/migrate/migrate.options.ts +2 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.module-definition.ts +6 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.module.ts +2 -1
- package/templates/be/skeleton/src/features/cli/seed/seed.options.ts +2 -0
- package/templates/be/skeleton/src/features/cli/seed/subs/run.cli.spec.ts +5 -6
- package/templates/be/skeleton/src/modules/domain/identity/admission.policy.spec.ts +56 -4
- package/templates/be/skeleton/src/modules/domain/identity/admission.policy.ts +36 -5
- package/templates/be/skeleton/src/modules/domain/identity/auth.guard.spec.ts +39 -8
- package/templates/be/skeleton/src/modules/domain/identity/auth.guard.ts +14 -8
- package/templates/be/skeleton/src/modules/domain/identity/credential.contracts.ts +26 -0
- package/templates/be/skeleton/src/modules/domain/identity/credential.guard.spec.ts +119 -0
- package/templates/be/skeleton/src/modules/domain/identity/credential.guard.ts +43 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.contracts.ts +16 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.decorators.ts +18 -1
- package/templates/be/skeleton/src/modules/domain/identity/identity.module.ts +22 -4
- package/templates/be/skeleton/src/modules/domain/identity/identity.options.ts +8 -2
- package/templates/be/skeleton/src/modules/domain/identity/index.ts +1 -0
- package/templates/be/skeleton/src/modules/platform/database/connection-source.client.spec.ts +11 -4
- package/templates/be/skeleton/src/modules/platform/database/database-probe.service.spec.ts +32 -0
- package/templates/be/skeleton/src/modules/platform/database/database-probe.service.ts +14 -0
- package/templates/be/skeleton/src/modules/platform/database/database.module.ts +7 -1
- package/templates/be/skeleton/src/modules/platform/database/index.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.decorators.ts +8 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-connections.client.spec.ts +25 -6
- package/templates/be/skeleton/src/modules/platform/errors/errors.filter.spec.ts +16 -6
- package/templates/be/skeleton/src/modules/platform/http-security/edge-security.service.spec.ts +130 -0
- package/templates/be/skeleton/src/modules/platform/http-security/edge-security.service.ts +58 -0
- package/templates/be/skeleton/src/modules/platform/http-security/errors/http-security.error.ts +3 -0
- package/templates/be/skeleton/src/modules/platform/http-security/execution-request.mapper.spec.ts +16 -4
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.config.ts +16 -10
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.module.ts +3 -1
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.options.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/http-security/index.ts +5 -0
- package/templates/be/skeleton/src/modules/platform/http-security/messages/http-security.messages.ts +12 -5
- package/templates/be/skeleton/src/modules/platform/http-security/rate-limit.guard.spec.ts +13 -8
- package/templates/be/skeleton/src/modules/platform/http-security/readiness.contracts.ts +5 -0
- package/templates/be/skeleton/src/modules/platform/http-security/readiness.decorators.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/http-security/readiness.service.spec.ts +86 -0
- package/templates/be/skeleton/src/modules/platform/http-security/readiness.service.ts +39 -0
- package/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.spec.ts +139 -131
- package/templates/be/skeleton/src/modules/platform/i18n/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +91 -67
- package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +5 -4
- package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +0 -2
- package/templates/be/skeleton/src/modules/platform/primitives/outcome.mapper.spec.ts +20 -6
- package/templates/be/skeleton/src/modules/platform/primitives/sequence.policy.spec.ts +16 -4
- package/templates/be/skeleton/src/modules/platform/retry/index.ts +3 -0
- package/templates/be/skeleton/src/modules/platform/retry/retry.decorators.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/retry/retry.module-definition.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/retry/retry.module.ts +19 -0
- package/templates/be/skeleton/src/modules/platform/retry/retry.options.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/retry/retry.port.ts +11 -0
- package/templates/be/skeleton/src/modules/platform/retry/system-timer.service.spec.ts +36 -0
- package/templates/be/skeleton/src/modules/platform/retry/system-timer.service.ts +10 -0
- package/templates/be/skeleton/src/tests/contract/http-security/http-security.contract-spec.ts +54 -0
- package/templates/be/skeleton-lite/apps/api/src/app.module.ts +14 -18
- package/templates/be/skeleton-lite/apps/api/src/compose/api.ts +4 -0
- package/templates/be/skeleton-lite/apps/api/src/compose/domain.ts +10 -0
- package/templates/be/skeleton-lite/apps/api/src/compose/integrations.ts +16 -0
- package/templates/be/skeleton-lite/apps/api/src/compose/platform.ts +2 -0
- package/templates/be/skeleton-lite/apps/api/src/compose/system.ts +5 -0
- package/templates/be/skeleton-lite/apps/api/src/compose/webhooks.ts +4 -0
- package/templates/be/skeleton-lite/apps/api/src/main.ts +2 -3
- package/templates/be/skeleton-lite/apps/cli/src/compose/platform.ts +12 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/admission.policy.spec.ts +71 -5
- package/templates/be/skeleton-lite/src/modules/domain/identity/admission.policy.ts +29 -2
- package/templates/be/skeleton-lite/src/modules/domain/identity/auth.guard.spec.ts +68 -15
- package/templates/be/skeleton-lite/src/modules/domain/identity/auth.guard.ts +14 -9
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.contracts.ts +9 -2
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.decorators.ts +16 -1
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.module.ts +19 -4
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.options.ts +5 -1
- package/templates/be/skeleton-lite/src/modules/domain/identity/index.ts +2 -1
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/errors/supabase.error.ts +0 -3
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.spec.ts +17 -5
- package/templates/be/skeleton-lite/src/modules/platform/database/database.module.ts +24 -13
- package/templates/be/skeleton-lite/src/modules/platform/database/database.port.ts +5 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/errors/database.error.ts +16 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/index.ts +3 -0
- package/templates/be/skeleton-lite/src/modules/platform/http-security/http-security.module.ts +5 -2
- package/templates/be/skeleton-lite/src/modules/platform/http-security/index.ts +4 -1
- package/templates/be/skeleton-lite/src/modules/platform/i18n/index.ts +1 -1
- package/templates/be/skeleton-lite/src/modules/platform/logging/logging.log-events.ts +7 -0
- package/templates/be/skeleton-lite/src/tests/fixtures/builders/api.builder.ts +29 -0
- package/templates/be/skeleton-lite/src/tests/fixtures/builders/cli.builder.ts +16 -0
- package/templates/be/table/api/feature.module-definition.ts.tpl +6 -0
- package/templates/be/table/api/feature.module.ts.tpl +2 -1
- package/templates/be/table/api/feature.options.ts.tpl +2 -0
- package/templates/be/table/api/graphql.module-definition.ts.tpl +6 -0
- package/templates/be/table/api/graphql.module.ts.tpl +3 -2
- package/templates/be/table/api/graphql.options.ts.tpl +2 -0
- package/templates/be/table/migration.sql.tpl +1 -0
- package/templates/be/upgrade-full/apps/cli/src/app.module.ts +4 -6
- package/templates/be/upgrade-full/apps/cli/src/cli.env.ts +7 -0
- package/templates/be/upgrade-full/apps/cli/src/compose/cli.ts +5 -0
- package/templates/be/upgrade-full/apps/cli/src/compose/platform.ts +9 -0
- package/templates/be/upgrade-full/apps/cli/src/main.ts +3 -0
- package/templates/be/upgrade-full/src/features/cli/cli.module.ts +3 -2
- package/templates/fe/auth/supabase-client.ts.tpl +34 -0
- package/templates/fe/skeleton/apps/__app__/src/app/auth/callback/route.ts +11 -0
- package/templates/fe/skeleton/apps/__app__/src/components/blocks/SignInForm/index.tsx +6 -1
- package/templates/fe/skeleton/apps/__app__/src/components/leaves/Icon/index.tsx +4 -0
- package/templates/fe/skeleton/apps/__app__/src/features/overlays/AppGuideOverlay/component.tsx +31 -0
- package/templates/fe/skeleton/apps/__app__/src/features/overlays/AppGuideOverlay/index.tsx +24 -0
- package/templates/fe/skeleton/apps/__app__/src/hooks/auth/useSession.ts +6 -1
- package/templates/fe/skeleton/apps/__app__/src/hooks/auth/useSignOut.ts +3 -4
- package/templates/fe/skeleton/apps/__app__/src/hooks/zustand/appGuide/index.ts +1 -0
- package/templates/fe/skeleton/apps/__app__/src/hooks/zustand/appGuide/store.ts +15 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/auth/pkce-client.ts +18 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/auth/server.ts +19 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppHomePage/index.tsx +7 -1
- package/templates/fe/skeleton/apps/app/src/modules/i18n/messages/en.json +57 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/messages/vi.json +6 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/messages/en.json +31 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/routing.ts +1 -1
- package/templates/fe/skeleton/packages/__project__-ui/src/index.ts +1 -0
- package/templates/fe/skeleton-lite/apps/__app__/src/modules/auth/client.ts +1 -34
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/index.tsx +7 -1
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages/en.json +57 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages/vi.json +30 -24
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/routing.ts +1 -1
- package/templates/fe/transport/graphql/clients/clients/auth.ts +1 -1
- package/templates/fe/transport/graphql/clients/links/locale.ts +2 -2
- package/upgrade/check.mjs +3 -1
- package/upgrade/index.mjs +54 -41
|
@@ -1,11 +1,144 @@
|
|
|
1
|
-
# The
|
|
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,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,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,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,142 @@
|
|
|
1
|
+
# Rendered production model. All-zero app digests are illustrative; publish verified images before use.
|
|
2
|
+
version: "3.8"
|
|
3
|
+
services:
|
|
4
|
+
core:
|
|
5
|
+
image: "{{project}}/core: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
|
+
secrets:
|
|
12
|
+
- source: primary-db-url
|
|
13
|
+
target: primary-db-url
|
|
14
|
+
networks: [app]
|
|
15
|
+
healthcheck:
|
|
16
|
+
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))"]
|
|
17
|
+
interval: 30s
|
|
18
|
+
timeout: 5s
|
|
19
|
+
start_period: 20s
|
|
20
|
+
retries: 3
|
|
21
|
+
deploy:
|
|
22
|
+
replicas: 1
|
|
23
|
+
placement:
|
|
24
|
+
constraints: ["node.labels.{{project}} == production"]
|
|
25
|
+
update_config:
|
|
26
|
+
parallelism: 1
|
|
27
|
+
order: start-first
|
|
28
|
+
failure_action: rollback
|
|
29
|
+
monitor: 30s
|
|
30
|
+
rollback_config:
|
|
31
|
+
parallelism: 1
|
|
32
|
+
order: stop-first
|
|
33
|
+
restart_policy:
|
|
34
|
+
condition: on-failure
|
|
35
|
+
delay: 5s
|
|
36
|
+
app:
|
|
37
|
+
image: "{{project}}/app:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
|
|
38
|
+
environment:
|
|
39
|
+
NODE_ENV: production
|
|
40
|
+
PORT: "3000"
|
|
41
|
+
HOSTNAME: 0.0.0.0
|
|
42
|
+
NEXT_PUBLIC_SITE_URL: https://{{project}}.example.invalid
|
|
43
|
+
networks: [app]
|
|
44
|
+
healthcheck:
|
|
45
|
+
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))"]
|
|
46
|
+
interval: 30s
|
|
47
|
+
timeout: 5s
|
|
48
|
+
start_period: 20s
|
|
49
|
+
retries: 3
|
|
50
|
+
deploy:
|
|
51
|
+
replicas: 1
|
|
52
|
+
placement:
|
|
53
|
+
constraints: ["node.labels.{{project}} == production"]
|
|
54
|
+
update_config:
|
|
55
|
+
parallelism: 1
|
|
56
|
+
order: start-first
|
|
57
|
+
failure_action: rollback
|
|
58
|
+
monitor: 30s
|
|
59
|
+
rollback_config:
|
|
60
|
+
parallelism: 1
|
|
61
|
+
order: stop-first
|
|
62
|
+
restart_policy:
|
|
63
|
+
condition: on-failure
|
|
64
|
+
delay: 5s
|
|
65
|
+
landing:
|
|
66
|
+
image: "{{project}}/landing:v0.0.0@sha256:0000000000000000000000000000000000000000000000000000000000000000"
|
|
67
|
+
environment:
|
|
68
|
+
NODE_ENV: production
|
|
69
|
+
PORT: "3002"
|
|
70
|
+
HOSTNAME: 0.0.0.0
|
|
71
|
+
NEXT_PUBLIC_APP_URL: https://{{project}}.example.invalid
|
|
72
|
+
networks: [app]
|
|
73
|
+
healthcheck:
|
|
74
|
+
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))"]
|
|
75
|
+
interval: 30s
|
|
76
|
+
timeout: 5s
|
|
77
|
+
start_period: 20s
|
|
78
|
+
retries: 3
|
|
79
|
+
deploy:
|
|
80
|
+
replicas: 1
|
|
81
|
+
placement:
|
|
82
|
+
constraints: ["node.labels.{{project}} == production"]
|
|
83
|
+
update_config:
|
|
84
|
+
parallelism: 1
|
|
85
|
+
order: start-first
|
|
86
|
+
failure_action: rollback
|
|
87
|
+
monitor: 30s
|
|
88
|
+
rollback_config:
|
|
89
|
+
parallelism: 1
|
|
90
|
+
order: stop-first
|
|
91
|
+
restart_policy:
|
|
92
|
+
condition: on-failure
|
|
93
|
+
delay: 5s
|
|
94
|
+
ingress:
|
|
95
|
+
image: caddy:2.10.2@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb
|
|
96
|
+
configs:
|
|
97
|
+
- source: ingress-config
|
|
98
|
+
target: /etc/caddy/Caddyfile
|
|
99
|
+
ports:
|
|
100
|
+
- { target: 80, published: 80, protocol: tcp, mode: ingress }
|
|
101
|
+
- { target: 443, published: 443, protocol: tcp, mode: ingress }
|
|
102
|
+
volumes:
|
|
103
|
+
- ingress-data:/data
|
|
104
|
+
- ingress-config-data:/config
|
|
105
|
+
networks: [app]
|
|
106
|
+
healthcheck:
|
|
107
|
+
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
|
|
108
|
+
interval: 30s
|
|
109
|
+
timeout: 5s
|
|
110
|
+
retries: 3
|
|
111
|
+
deploy:
|
|
112
|
+
replicas: 1
|
|
113
|
+
placement:
|
|
114
|
+
constraints: ["node.labels.{{project}} == production"]
|
|
115
|
+
update_config:
|
|
116
|
+
parallelism: 1
|
|
117
|
+
order: stop-first
|
|
118
|
+
failure_action: rollback
|
|
119
|
+
monitor: 30s
|
|
120
|
+
rollback_config:
|
|
121
|
+
parallelism: 1
|
|
122
|
+
order: stop-first
|
|
123
|
+
restart_policy:
|
|
124
|
+
condition: on-failure
|
|
125
|
+
delay: 5s
|
|
126
|
+
networks:
|
|
127
|
+
app:
|
|
128
|
+
driver: overlay
|
|
129
|
+
secrets:
|
|
130
|
+
primary-db-url:
|
|
131
|
+
external: true
|
|
132
|
+
name: "{{project}}-production-primary-db-url-v1"
|
|
133
|
+
configs:
|
|
134
|
+
ingress-config:
|
|
135
|
+
file: ./Caddyfile
|
|
136
|
+
volumes:
|
|
137
|
+
ingress-data:
|
|
138
|
+
external: true
|
|
139
|
+
name: "{{project}}-production-ingress-data"
|
|
140
|
+
ingress-config-data:
|
|
141
|
+
external: true
|
|
142
|
+
name: "{{project}}-production-ingress-config-data"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Production environment key roster
|
|
2
|
+
|
|
3
|
+
This inventory declares names, consumers and mounted file paths. Scaffolding seals a generated database placeholder to this app's own recipient. Replace it with the real credential before use; no successful deployment is claimed by scaffolding.
|
|
4
|
+
|
|
5
|
+
| Key | Consumer |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `PORT` | Core API listener |
|
|
8
|
+
| `HTTP_SECURITY_ALLOWED_ORIGINS` | Core API origin allowlist |
|
|
9
|
+
| `PRIMARY_DB_URL` | Core API and CLI primary database connection; the API reads `PRIMARY_DB_URL_FILE` at `/run/secrets/primary-db-url` |
|
|
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. Replace the generated private placeholder only in `.starcistacks/production/secrets/primary-db-url.enc`, already declared by the manifest. The versioned external database secret is `{{project}}-production-primary-db-url-v1`.
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# {{project}}
|
|
2
2
|
|
|
3
|
-
One StarCi app: its back end in be
|
|
3
|
+
One StarCi app: its back end in `be/`, its front end in `fe/`, one install at the root.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
The app starts with the core api app (be/apps/core) and the cli app (be/apps/cli) over one primary database, two Next apps (fe/apps/landing
|
|
7
|
+
The app starts with the core api app (`be/apps/core`) and the cli app (`be/apps/cli`) over one primary database, two Next apps (`fe/apps/landing`, the public front door, and `fe/apps/app`, the product) over the shared packages `fe/packages/{{project}}-ui` and `fe/packages/{{project}}-i18n`.
|
|
8
8
|
|
|
9
9
|
## Stack
|
|
10
10
|
|
|
11
|
-
TypeScript everywhere; NestJS in be
|
|
11
|
+
TypeScript everywhere; NestJS in `be/`, Next.js with next-intl in `fe/`; npm with one `package.json` and one lockfile at the root.
|
|
12
12
|
|
|
13
13
|
## Repository layout
|
|
14
14
|
|
|
15
|
-
- `be/`: the back end, `apps/<app>/src` composes `src/features` and `src/modules`; its tests live under `src/tests`.
|
|
16
|
-
- `fe/`: the front end, one Next app per `apps/<app>` and the shared workspace packages under `packages/` (the ui drawings and the next-intl stack both apps call).
|
|
15
|
+
- `be/`: the back end, `be/apps/<app>/src` composes `be/src/features` and `be/src/modules`; its tests live under `be/src/tests`.
|
|
16
|
+
- `fe/`: the front end, one Next app per `fe/apps/<app>` and the shared workspace packages under `fe/packages/` (the ui drawings and the next-intl stack both apps call).
|
|
17
17
|
- `scripts/`: the app's operational scripts; `hfs.json` declares both sides.
|
|
18
18
|
|
|
19
19
|
## Development
|
|
@@ -31,7 +31,7 @@ The core api app reads `PORT`, `HTTP_SECURITY_ALLOWED_ORIGINS` (comma-separated
|
|
|
31
31
|
requests) and `PRIMARY_DB_URL` at boot; every door is closed until it is marked public or sign-in is designed. The cli app reads
|
|
32
32
|
`PRIMARY_DB_URL`: `npm run migrate` applies the migrations of the primary database before the api starts, and
|
|
33
33
|
`npm run cli -- seed run` runs the dev seeds of `.starcistacks/dev/seeds` (run both from the app root). The product app reads
|
|
34
|
-
`NEXT_PUBLIC_SITE_URL` and `NEXT_PUBLIC_GRAPHQL_URL` (the back end it calls through `src/modules/api`, read once the first GraphQL operation exists), the landing `NEXT_PUBLIC_APP_URL` (the product app it hands the reader over to). A missing key stops the process with an error that names it.
|
|
34
|
+
`NEXT_PUBLIC_SITE_URL` and `NEXT_PUBLIC_GRAPHQL_URL` (the back end it calls through `fe/apps/app/src/modules/api`, read once the first GraphQL operation exists), the landing `NEXT_PUBLIC_APP_URL` (the product app it hands the reader over to). A missing key stops the process with an error that names it.
|
|
35
35
|
|
|
36
36
|
## Work
|
|
37
37
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// codegen.mjs - the app's generated code, the one step behind `npm run codegen` (lint, typecheck, dev and build run it first).
|
|
2
2
|
// The front end reads the back end's committed contracts in place (be/contracts/, hfs.json sides.fe.reads) and generates its
|
|
3
3
|
// client from them into a gitignored __generated__/ folder. A new app has no contract yet, so there is nothing to generate.
|
|
4
|
-
|
|
5
|
-
import path from "node:path"
|
|
4
|
+
// {{> app/codegen-prelude.mjs.partial}}
|
|
6
5
|
|
|
7
6
|
// {{> app/codegen-graphql.mjs.partial}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{{header}}
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
charset = utf-8
|
|
6
|
+
end_of_line = lf
|
|
7
|
+
indent_style = space
|
|
8
|
+
indent_size = 4
|
|
9
|
+
insert_final_newline = true
|
|
10
|
+
trim_trailing_whitespace = true
|
|
11
|
+
|
|
12
|
+
[*.{json,yml,yaml}]
|
|
13
|
+
indent_size = 2
|
|
14
|
+
|
|
15
|
+
[*.md]
|
|
16
|
+
trim_trailing_whitespace = false
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{nodeMajor}}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
1
|
+
# The runtime template tracks no sealed members or shared recipient.
|
|
2
|
+
# Scaffolding configures this app's own age recipient and generates sealed placeholders.
|
|
3
|
+
# The private identity lives only in untracked .claude/secret.env as SOPS_AGE_KEY.
|
|
3
4
|
creation_rules: []
|