@starci/hfs 4.0.8 → 4.0.10
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 +9 -0
- package/LICENSE +21 -0
- package/README.md +81 -39
- package/emit/contracts.mjs +56 -9
- package/emit/db-types.mjs +169 -0
- package/emit/events.mjs +41 -0
- package/emit/operations-worker.mjs +1 -1
- package/emit/operations.mjs +2 -2
- package/emit/schema-worker.mjs +1 -1
- package/lint/bound-sys.cjs +50 -0
- package/lint/run.mjs +131 -24
- package/package.json +16 -10
- package/report/sonar.mjs +8 -8
- package/runtime/engine/admission.mjs +308 -0
- package/runtime/engine/canonical-json.mjs +10 -0
- package/runtime/engine/config.mjs +486 -0
- package/runtime/engine/db/blob.mjs +315 -0
- package/runtime/engine/db/ledger-paths.mjs +83 -0
- package/runtime/engine/db/ledger.mjs +1118 -0
- package/runtime/engine/db/machine-connection.mjs +135 -0
- package/runtime/engine/db/machine-schema.mjs +84 -0
- package/runtime/engine/db/machine.mjs +1367 -0
- package/runtime/engine/db/migrations/machine/0001-init.sql +924 -0
- package/runtime/engine/db/migrations/runtime/0001-init.sql +1108 -0
- package/runtime/engine/db/provider-reservations.mjs +101 -0
- package/runtime/engine/digest.mjs +16 -0
- package/runtime/engine/invalid-config.mjs +15 -0
- package/runtime/engine/orca-config.mjs +27 -0
- package/runtime/engine/refuse.mjs +11 -0
- package/runtime/engine/secrets.mjs +130 -0
- package/runtime/knowledge/hfs/canon-pins.yaml +162 -31
- package/runtime/knowledge/hfs/peer-integrations.yaml +2 -2
- package/runtime/knowledge/hfs/rules.yaml +2059 -0
- package/runtime/knowledge/hfs/slots.yaml +912 -120
- package/runtime/knowledge/patterns/be/api.yaml +369 -0
- package/runtime/knowledge/patterns/be/cli.yaml +297 -0
- package/runtime/knowledge/patterns/be/domain.yaml +113 -0
- package/runtime/knowledge/patterns/be/event-bus.yaml +285 -0
- package/runtime/knowledge/patterns/be/jobs.yaml +261 -0
- package/runtime/knowledge/patterns/be/projections.yaml +178 -0
- package/runtime/knowledge/patterns/be/queues.yaml +236 -0
- package/runtime/knowledge/patterns/be/reactors.yaml +140 -0
- package/runtime/knowledge/patterns/be/realtime.yaml +222 -0
- package/runtime/knowledge/patterns/be/saga.yaml +248 -0
- package/runtime/knowledge/patterns/be/webhooks.yaml +221 -0
- package/runtime/knowledge/patterns/fe/folder.yaml +131 -25
- package/runtime/knowledge/sonar-gate.yaml +52 -18
- package/runtime/modules/kernel/failure-codes.yaml +611 -51
- package/runtime/modules/models/registry.yaml +553 -0
- package/runtime/modules/models/runtimes.yaml +695 -0
- package/runtime/modules/ops/_labels.yaml +53 -0
- package/runtime/scripts/api/fs/forbidden-root.mjs +51 -0
- package/runtime/scripts/api/fs/is-link-like.mjs +25 -0
- package/runtime/scripts/api/fs/lib.mjs +16 -2
- package/runtime/scripts/api/fs/safe-remove.mjs +12 -132
- package/runtime/scripts/api/git/config-get.mjs +10 -0
- package/runtime/scripts/api/git/diff.mjs +5 -0
- package/runtime/scripts/api/git/lib.mjs +18 -26
- package/runtime/scripts/api/git/log.mjs +5 -0
- package/runtime/scripts/api/git/ls-files.mjs +6 -0
- package/runtime/scripts/api/git/ls-tree.mjs +5 -0
- package/runtime/scripts/api/git/merge-base.mjs +9 -0
- package/runtime/scripts/api/git/remote.mjs +5 -0
- package/runtime/scripts/api/git/rev-parse-query.mjs +5 -0
- package/runtime/scripts/api/git/show.mjs +6 -0
- package/runtime/scripts/api/node/lib.mjs +14 -0
- package/runtime/scripts/api/node/spawn-node.mjs +6 -0
- package/runtime/scripts/api/process/lib.mjs +111 -0
- package/runtime/scripts/api/process/owned-process.mjs +78 -0
- package/runtime/scripts/api/process/resolve-real-tool.mjs +46 -0
- package/runtime/scripts/api/process/run-program.mjs +7 -0
- package/runtime/scripts/api/process/stop-owned-process.mjs +9 -0
- package/runtime/scripts/api/sops/decrypt.mjs +9 -12
- package/runtime/scripts/api/sops/lib.mjs +255 -0
- package/runtime/scripts/api/sops/seal.mjs +22 -0
- package/runtime/scripts/connectors/lib.mjs +488 -0
- package/runtime/scripts/hfs/architecture/ast-walks.mjs +220 -0
- package/runtime/scripts/hfs/architecture/backend.mjs +16 -23
- package/runtime/scripts/hfs/architecture/background-unowned.mjs +16 -34
- package/runtime/scripts/hfs/architecture/client-reaches-server.mjs +3 -1
- package/runtime/scripts/hfs/architecture/clones.mjs +4 -4
- package/runtime/scripts/hfs/architecture/config.mjs +9 -6
- package/runtime/scripts/hfs/architecture/connection-map.mjs +20 -8
- package/runtime/scripts/hfs/architecture/context-coupling.mjs +88 -0
- package/runtime/scripts/hfs/architecture/context-map.mjs +237 -0
- package/runtime/scripts/hfs/architecture/context-owner.mjs +82 -0
- package/runtime/scripts/hfs/architecture/context-platform-tables.mjs +47 -0
- package/runtime/scripts/hfs/architecture/context-transaction.mjs +60 -0
- package/runtime/scripts/hfs/architecture/contract-fixture-guard.mjs +4 -10
- package/runtime/scripts/hfs/architecture/contracts.mjs +33 -162
- package/runtime/scripts/hfs/architecture/dead-exports.mjs +58 -29
- package/runtime/scripts/hfs/architecture/doc-language.mjs +1 -1
- package/runtime/scripts/hfs/architecture/entrypoint.mjs +2 -1
- package/runtime/scripts/hfs/architecture/fe-slot-allows.mjs +2 -2
- package/runtime/scripts/hfs/architecture/feature-shape.mjs +5 -2
- package/runtime/scripts/hfs/architecture/framework-pinned.mjs +1 -1
- package/runtime/scripts/hfs/architecture/frontend.mjs +17 -43
- package/runtime/scripts/hfs/architecture/hfs.mjs +24 -39
- package/runtime/scripts/hfs/architecture/i18n-keys.mjs +1 -1
- package/runtime/scripts/hfs/architecture/index.mjs +17 -4
- package/runtime/scripts/hfs/architecture/machine-ast.mjs +44 -11
- package/runtime/scripts/hfs/architecture/managed-scripts.mjs +27 -0
- package/runtime/scripts/hfs/architecture/module-per-transport.mjs +30 -6
- package/runtime/scripts/hfs/architecture/next-data.mjs +22 -63
- package/runtime/scripts/hfs/architecture/owners.mjs +35 -15
- package/runtime/scripts/hfs/architecture/register-once.mjs +2 -1
- package/runtime/scripts/hfs/architecture/registration.mjs +23 -81
- package/runtime/scripts/hfs/architecture/required-files.mjs +20 -12
- package/runtime/scripts/hfs/architecture/schema-owner.mjs +17 -114
- package/runtime/scripts/hfs/architecture/server-action.mjs +24 -0
- package/runtime/scripts/hfs/architecture/side-boundary.mjs +16 -0
- package/runtime/scripts/hfs/architecture/source-names.mjs +27 -147
- package/runtime/scripts/hfs/architecture/sql-owner.mjs +59 -18
- package/runtime/scripts/hfs/architecture/sql-returning.mjs +64 -0
- package/runtime/scripts/hfs/architecture/supabase-ast.mjs +111 -0
- package/runtime/scripts/hfs/architecture/supabase-be.mjs +131 -0
- package/runtime/scripts/hfs/architecture/supabase-tables.mjs +42 -0
- package/runtime/scripts/hfs/architecture/supabase.mjs +434 -0
- package/runtime/scripts/hfs/architecture/surface.mjs +9 -3
- package/runtime/scripts/hfs/architecture/test-world-files.mjs +9 -19
- package/runtime/scripts/hfs/architecture/tiers.mjs +47 -5
- package/runtime/scripts/hfs/architecture/transport-owner.mjs +3 -3
- package/runtime/scripts/hfs/architecture/typescript.mjs +12 -26
- package/runtime/scripts/hfs/architecture.mjs +4 -4
- package/runtime/scripts/hfs/check.mjs +75 -72
- package/runtime/scripts/hfs/coverage-scope.mjs +162 -0
- package/runtime/scripts/hfs/declaration-shape.mjs +62 -0
- package/runtime/scripts/hfs/declaration-slots.mjs +75 -0
- package/runtime/scripts/hfs/edition-slots.mjs +66 -0
- package/runtime/scripts/hfs/manifest-shape.mjs +109 -32
- package/runtime/scripts/hfs/param-names.mjs +18 -0
- package/runtime/scripts/hfs/path-findings.mjs +1 -1
- package/runtime/scripts/hfs/repo-identity.mjs +9 -6
- package/runtime/scripts/hfs/rule-params-shape.mjs +50 -0
- package/runtime/scripts/hfs/rules/app-root.mjs +51 -0
- package/runtime/scripts/hfs/rules/cli.mjs +37 -0
- package/runtime/scripts/hfs/rules/contract-compat.mjs +71 -0
- package/runtime/scripts/hfs/rules/contract.mjs +10 -9
- package/runtime/scripts/hfs/rules/database-config.mjs +102 -0
- package/runtime/scripts/hfs/rules/database-constants.mjs +13 -0
- package/runtime/scripts/hfs/rules/database-migrations.mjs +111 -0
- package/runtime/scripts/hfs/rules/database-plpgsql.mjs +233 -0
- package/runtime/scripts/hfs/rules/database-sql.mjs +336 -0
- package/runtime/scripts/hfs/rules/database.mjs +68 -0
- package/runtime/scripts/hfs/rules/deps.mjs +1 -1
- package/runtime/scripts/hfs/rules/docker.mjs +259 -0
- package/runtime/scripts/hfs/rules/edition.mjs +111 -0
- package/runtime/scripts/hfs/rules/event-bus.mjs +153 -0
- package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +1 -1
- package/runtime/scripts/hfs/rules/fe-no-tests.mjs +6 -5
- package/runtime/scripts/hfs/rules/frontend-tree.mjs +9 -9
- package/runtime/scripts/hfs/rules/integration-specs.mjs +3 -6
- package/runtime/scripts/hfs/rules/kinds.mjs +84 -0
- package/runtime/scripts/hfs/rules/lint-suppression.mjs +1 -1
- package/runtime/scripts/hfs/rules/monorepo.mjs +179 -0
- package/runtime/scripts/hfs/rules/peer-integrations.mjs +3 -3
- package/runtime/scripts/hfs/rules/pipeline.mjs +11 -21
- package/runtime/scripts/hfs/rules/proof-commands.mjs +2 -2
- package/runtime/scripts/hfs/rules/read.mjs +1 -1
- package/runtime/scripts/hfs/rules/repo-local-checks.mjs +2 -2
- package/runtime/scripts/hfs/rules/saga.mjs +170 -0
- package/runtime/scripts/hfs/rules/secrets.mjs +3 -3
- package/runtime/scripts/hfs/rules/services.mjs +220 -0
- package/runtime/scripts/hfs/rules/spec-placement.mjs +1 -1
- package/runtime/scripts/hfs/rules/stacks.mjs +3 -3
- package/runtime/scripts/hfs/rules/supabase-secrets.mjs +89 -0
- package/runtime/scripts/hfs/rules/test-topology.mjs +2 -2
- package/runtime/scripts/hfs/secret.mjs +209 -0
- package/runtime/scripts/hfs/slots.mjs +78 -108
- package/runtime/scripts/hfs/sql/pg-parse.mjs +46 -0
- package/runtime/scripts/hfs/test-world-slot.mjs +6 -0
- package/runtime/scripts/hfs/tree.mjs +5 -4
- package/runtime/scripts/hfs/typescript-programs.mjs +0 -5
- package/runtime/scripts/hfs/view.mjs +3 -2
- package/runtime/scripts/lib/clip.mjs +19 -0
- package/runtime/scripts/lib/display-names.mjs +259 -0
- package/runtime/scripts/lib/dockerfile.mjs +124 -0
- package/runtime/scripts/lib/env.mjs +10 -0
- package/runtime/scripts/lib/event-contract.mjs +103 -0
- package/runtime/scripts/lib/example-refs.mjs +158 -0
- package/runtime/scripts/lib/fs-kind.mjs +14 -4
- package/runtime/scripts/lib/git.mjs +36 -0
- package/runtime/scripts/lib/graphql-contract.mjs +1 -1
- package/runtime/scripts/lib/i18n.mjs +86 -0
- package/runtime/scripts/lib/json-schema.mjs +52 -0
- package/runtime/scripts/lib/json.mjs +13 -3
- package/runtime/scripts/lib/language.mjs +24 -5
- package/runtime/scripts/lib/list.mjs +20 -0
- package/runtime/scripts/lib/mutation-fence.mjs +15 -0
- package/runtime/scripts/lib/package-at.mjs +37 -0
- package/runtime/scripts/lib/path-key.mjs +57 -2
- package/runtime/scripts/lib/process-identity.mjs +6 -0
- package/runtime/scripts/lib/read-text.mjs +34 -0
- package/runtime/scripts/lib/read-yaml.mjs +18 -0
- package/runtime/scripts/lib/redact.mjs +161 -0
- package/runtime/scripts/lib/regex.mjs +4 -0
- package/runtime/scripts/lib/same-text.mjs +5 -0
- package/runtime/scripts/lib/secret-patterns.mjs +4 -3
- package/runtime/scripts/lib/sleep-sync.mjs +2 -1
- package/runtime/scripts/lib/sleep.mjs +7 -0
- package/runtime/scripts/lib/sops-envelope.mjs +112 -0
- package/runtime/scripts/lib/source-phrases.mjs +34 -0
- package/runtime/scripts/lib/sqlite.mjs +21 -0
- package/runtime/scripts/lib/stack-services.mjs +7 -31
- package/runtime/scripts/lib/ts-ast.mjs +35 -0
- package/runtime/scripts/lib/walk.mjs +4 -3
- package/scaffold/add-app.mjs +174 -0
- package/scaffold/add-cli-lite.mjs +257 -0
- package/scaffold/add-inbox-lite.mjs +314 -0
- package/scaffold/add-table.mjs +344 -0
- package/scaffold/add.mjs +299 -0
- package/scaffold/app.mjs +358 -69
- package/scaffold/edition-gate.mjs +25 -0
- package/scaffold/image.mjs +19 -0
- package/scaffold/lite-exports.mjs +186 -0
- package/scaffold/service.mjs +32 -26
- package/scaffold/supabase-ports.mjs +26 -0
- package/src/main.mjs +327 -0
- package/sync/cli.mjs +6 -9
- package/sync/format.mjs +1 -1
- package/sync/hygiene.mjs +10 -10
- package/sync/index.mjs +167 -104
- package/sync/managed.mjs +19 -11
- package/sync/sonar-key.mjs +5 -0
- package/templates/app/ci-workflows/github/workflows/ci.yml +14 -14
- package/templates/app/ci-workflows/github/workflows/images.yml +37 -0
- package/templates/app/ci-workflows/sonar-steps.yml +9 -0
- package/templates/app/ci-workflows-lite/github/workflows/ci.yml +66 -0
- package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +31 -0
- package/templates/app/ci-workflows-lite/github/workflows/images.yml +37 -0
- package/templates/app/codegen-lite/scripts/codegen.mjs +32 -0
- package/templates/app/docker-ignore/dockerignore +50 -0
- package/templates/app/gitignore-lite +35 -0
- package/templates/app/hooks/husky/pre-commit +3 -8
- package/templates/app/hooks/husky/pre-push +45 -6
- package/templates/app/package-scripts/core.json +8 -0
- package/templates/app/package-scripts/package.json +3 -10
- package/templates/app/package-scripts-lite/package.json +15 -0
- package/templates/app/quality-config/codecov.yml +15 -3
- package/templates/app/quality-config/sonar-base.properties +4 -0
- package/templates/app/quality-config/sonar-project.properties +1 -4
- package/templates/app/quality-config-lite/sonar-project.properties +5 -0
- package/templates/app/skeleton/.starcistacks/dev/seeds/primary-notes.sql +5 -0
- package/templates/app/skeleton/.starciwork/features/system-health/index.yaml +4 -0
- package/templates/app/skeleton/.starciwork/{features/index.yaml → index.yaml} +2 -2
- package/templates/app/skeleton/README.md +7 -5
- package/templates/app/skeleton-lite/.sops.yaml +3 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/environment.json +5 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/secrets/.gitkeep +1 -0
- package/templates/app/skeleton-lite/.starciwork/shell/index.yaml +55 -0
- package/templates/app/skeleton-lite/README.md +40 -0
- package/templates/app/skeleton-lite/supabase/config.toml +41 -0
- package/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql +56 -0
- package/templates/app/skeleton-lite/supabase/seed.sql +0 -0
- package/templates/app/task-graph/turbo.json +23 -0
- package/templates/app/tool-config-lite/prettierignore +2 -0
- package/templates/app/tool-config-lite/prettierrc +1 -0
- package/templates/app/upgrade-full/.starcistacks/application-stacks.yaml +38 -0
- package/templates/app/upgrade-full/.starcistacks/dev/README.md +10 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/api.yaml +13 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/compose.yaml +3 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/postgres.yaml +12 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/metadata.json +7 -0
- package/templates/be/common/main-listen.ts.partial +14 -0
- package/templates/be/common/sql-ident.ts.partial +7 -0
- package/templates/be/common/sql-tag.ts.partial +5 -0
- package/templates/be/image/api/Dockerfile +38 -0
- package/templates/be/image/cli/Dockerfile +38 -0
- package/templates/be/image/worker/Dockerfile +36 -0
- package/templates/be/inbox/database-client.ts.tpl +50 -0
- package/templates/be/inbox/index.ts.tpl +2 -0
- package/templates/be/inbox/migration.sql.tpl +29 -0
- package/templates/be/inbox/module-definition.ts.tpl +6 -0
- package/templates/be/inbox/module.ts.tpl +14 -0
- package/templates/be/inbox/options.ts.tpl +2 -0
- package/templates/be/inbox/service.ts.tpl +33 -0
- package/templates/be/inbox/sql.ts.tpl +16 -0
- package/templates/be/inbox/webhook-door.ts.tpl +36 -0
- package/templates/be/patterns/api/application.command.http.ts.tpl +10 -0
- package/templates/be/patterns/api/application.command.ts.tpl +10 -0
- package/templates/be/patterns/api/application.contracts.ts.tpl +11 -0
- package/templates/be/patterns/api/application.handler.http.ts.tpl +22 -0
- package/templates/be/patterns/api/application.handler.ts.tpl +22 -0
- package/templates/be/patterns/api/feature.index.http.ts.tpl +1 -0
- package/templates/be/patterns/api/feature.index.ts.tpl +1 -0
- package/templates/be/patterns/api/feature.module.ts.tpl +6 -0
- package/templates/be/patterns/api/graphql.input.ts.tpl +13 -0
- package/templates/be/patterns/api/graphql.mapper.ts.tpl +9 -0
- package/templates/be/patterns/api/graphql.module.ts.tpl +7 -0
- package/templates/be/patterns/api/graphql.resolver.ts.tpl +27 -0
- package/templates/be/patterns/api/graphql.type.ts.tpl +9 -0
- package/templates/be/patterns/api/http.controller.ts.tpl +27 -0
- package/templates/be/patterns/api/http.mapper.ts.tpl +9 -0
- package/templates/be/patterns/api/http.module.ts.tpl +7 -0
- package/templates/be/patterns/api/http.request.ts.tpl +10 -0
- package/templates/be/patterns/api/http.response.ts.tpl +5 -0
- package/templates/be/patterns/cli/group.cli.spec.ts.tpl +15 -0
- package/templates/be/patterns/cli/group.cli.ts.tpl +11 -0
- package/templates/be/patterns/cli/group.module.ts.tpl +7 -0
- package/templates/be/patterns/cli/sub.run.cli.spec.ts.tpl +17 -0
- package/templates/be/patterns/cli/sub.run.cli.ts.tpl +15 -0
- package/templates/be/patterns/event-bus/platform/errors/event-bus.error.ts.tpl +22 -0
- package/templates/be/patterns/event-bus/platform/event-bus.config.ts.tpl +19 -0
- package/templates/be/patterns/event-bus/platform/event-bus.contracts.ts.tpl +58 -0
- package/templates/be/patterns/event-bus/platform/event-bus.decorators.ts.tpl +46 -0
- package/templates/be/patterns/event-bus/platform/event-bus.log-events.ts.tpl +12 -0
- package/templates/be/patterns/event-bus/platform/event-bus.module-definition.ts.tpl +10 -0
- package/templates/be/patterns/event-bus/platform/event-bus.module.ts.tpl +52 -0
- package/templates/be/patterns/event-bus/platform/event-bus.options.ts.tpl +19 -0
- package/templates/be/patterns/event-bus/platform/event-bus.port.ts.tpl +28 -0
- package/templates/be/patterns/event-bus/platform/event-bus.service.spec.ts.tpl +165 -0
- package/templates/be/patterns/event-bus/platform/event-bus.service.ts.tpl +93 -0
- package/templates/be/patterns/event-bus/platform/event-envelope.policy.spec.ts.tpl +90 -0
- package/templates/be/patterns/event-bus/platform/event-envelope.policy.ts.tpl +58 -0
- package/templates/be/patterns/event-bus/platform/event-relay.service.spec.ts.tpl +136 -0
- package/templates/be/patterns/event-bus/platform/event-relay.service.ts.tpl +56 -0
- package/templates/be/patterns/event-bus/platform/event-runner.service.spec.ts.tpl +272 -0
- package/templates/be/patterns/event-bus/platform/event-runner.service.ts.tpl +128 -0
- package/templates/be/patterns/event-bus/platform/event-transport.port.ts.tpl +180 -0
- package/templates/be/patterns/event-bus/platform/event.policy.spec.ts.tpl +67 -0
- package/templates/be/patterns/event-bus/platform/event.policy.ts.tpl +38 -0
- package/templates/be/patterns/event-bus/platform/index.ts.tpl +11 -0
- package/templates/be/patterns/event-bus/platform/kafka-event-transport.client.spec.ts.tpl +348 -0
- package/templates/be/patterns/event-bus/platform/kafka-event-transport.client.ts.tpl +241 -0
- package/templates/be/patterns/event-bus/platform/messages/event-bus.messages.ts.tpl +15 -0
- package/templates/be/patterns/event-bus/platform/persistence/connection.ts.tpl +8 -0
- package/templates/be/patterns/event-bus/platform/persistence/entities/event-outbox.entity.ts.tpl +37 -0
- package/templates/be/patterns/event-bus/platform/persistence/event-bus.rows.ts.tpl +11 -0
- package/templates/be/patterns/event-bus/platform/persistence/event-bus.sql.ts.tpl +12 -0
- package/templates/be/patterns/event-bus/platform/persistence/migrations/1789800009000-create-event-outbox.ts.tpl +26 -0
- package/templates/be/patterns/jobs/job.index.ts.tpl +1 -0
- package/templates/be/patterns/jobs/job.module.ts.tpl +6 -0
- package/templates/be/patterns/jobs/job.processor.ts.tpl +20 -0
- package/templates/be/patterns/jobs/job.queue.module.ts.tpl +20 -0
- package/templates/be/patterns/jobs/job.step.ts.tpl +19 -0
- package/templates/be/patterns/jobs/platform/fenced.processor.spec.ts.tpl +31 -0
- package/templates/be/patterns/jobs/platform/fenced.processor.ts.tpl +13 -0
- package/templates/be/patterns/jobs/platform/job-claim.service.spec.ts.tpl +150 -0
- package/templates/be/patterns/jobs/platform/job-claim.service.ts.tpl +100 -0
- package/templates/be/patterns/jobs/platform/job-runner.service.spec.ts.tpl +138 -0
- package/templates/be/patterns/jobs/platform/job-runner.service.ts.tpl +69 -0
- package/templates/be/patterns/jobs/platform/jobs.config.ts.tpl +11 -0
- package/templates/be/patterns/jobs/platform/jobs.contracts.ts.tpl +62 -0
- package/templates/be/patterns/jobs/platform/jobs.decorators.ts.tpl +31 -0
- package/templates/be/patterns/jobs/platform/jobs.error.ts.tpl +22 -0
- package/templates/be/patterns/jobs/platform/jobs.index.ts.tpl +11 -0
- package/templates/be/patterns/jobs/platform/jobs.log-events.ts.tpl +9 -0
- package/templates/be/patterns/jobs/platform/jobs.messages.ts.tpl +15 -0
- package/templates/be/patterns/jobs/platform/jobs.module-definition.ts.tpl +10 -0
- package/templates/be/patterns/jobs/platform/jobs.module.ts.tpl +32 -0
- package/templates/be/patterns/jobs/platform/jobs.options.ts.tpl +11 -0
- package/templates/be/patterns/jobs/platform/jobs.port.ts.tpl +36 -0
- package/templates/be/patterns/jobs/platform/persistence.connection.ts.tpl +8 -0
- package/templates/be/patterns/jobs/platform/persistence.job.entity.ts.tpl +53 -0
- package/templates/be/patterns/jobs/platform/persistence.jobs.rows.ts.tpl +13 -0
- package/templates/be/patterns/jobs/platform/persistence.jobs.sql.ts.tpl +33 -0
- package/templates/be/patterns/jobs/platform/persistence.migration.ts.tpl +29 -0
- package/templates/be/patterns/outbox/platform/index.ts.tpl +2 -0
- package/templates/be/patterns/outbox/platform/outbox-relay.policy.spec.ts.tpl +96 -0
- package/templates/be/patterns/outbox/platform/outbox-relay.policy.ts.tpl +78 -0
- package/templates/be/patterns/outbox/platform/outbox.log-events.ts.tpl +5 -0
- package/templates/be/patterns/projections/migration.ts.tpl +18 -0
- package/templates/be/patterns/projections/persistence.connection.ts.tpl +8 -0
- package/templates/be/patterns/projections/projection.entity.ts.tpl +9 -0
- package/templates/be/patterns/projections/projection.index.ts.tpl +3 -0
- package/templates/be/patterns/projections/projection.module-definition.ts.tpl +7 -0
- package/templates/be/patterns/projections/projection.module.ts.tpl +18 -0
- package/templates/be/patterns/projections/projection.options.ts.tpl +2 -0
- package/templates/be/patterns/projections/projection.projection.spec.ts.tpl +55 -0
- package/templates/be/patterns/projections/projection.projection.ts.tpl +21 -0
- package/templates/be/patterns/queues/platform/bullmq-queue-transport.client.spec.ts.tpl +142 -0
- package/templates/be/patterns/queues/platform/bullmq-queue-transport.client.ts.tpl +81 -0
- package/templates/be/patterns/queues/platform/persistence.connection.ts.tpl +8 -0
- package/templates/be/patterns/queues/platform/persistence.migration.ts.tpl +25 -0
- package/templates/be/patterns/queues/platform/persistence.queue-outbox.entity.ts.tpl +25 -0
- package/templates/be/patterns/queues/platform/persistence.queue.rows.ts.tpl +9 -0
- package/templates/be/patterns/queues/platform/persistence.queue.sql.ts.tpl +12 -0
- package/templates/be/patterns/queues/platform/queue-outbox.service.spec.ts.tpl +48 -0
- package/templates/be/patterns/queues/platform/queue-outbox.service.ts.tpl +17 -0
- package/templates/be/patterns/queues/platform/queue-relay.service.spec.ts.tpl +128 -0
- package/templates/be/patterns/queues/platform/queue-relay.service.ts.tpl +48 -0
- package/templates/be/patterns/queues/platform/queue-transport.port.ts.tpl +115 -0
- package/templates/be/patterns/queues/platform/queue-worker.service.spec.ts.tpl +91 -0
- package/templates/be/patterns/queues/platform/queue-worker.service.ts.tpl +45 -0
- package/templates/be/patterns/queues/platform/queue.config.ts.tpl +15 -0
- package/templates/be/patterns/queues/platform/queue.contracts.ts.tpl +31 -0
- package/templates/be/patterns/queues/platform/queue.decorators.ts.tpl +45 -0
- package/templates/be/patterns/queues/platform/queue.index.ts.tpl +7 -0
- package/templates/be/patterns/queues/platform/queue.log-events.ts.tpl +5 -0
- package/templates/be/patterns/queues/platform/queue.module-definition.ts.tpl +10 -0
- package/templates/be/patterns/queues/platform/queue.module.ts.tpl +62 -0
- package/templates/be/patterns/queues/platform/queue.options.ts.tpl +22 -0
- package/templates/be/patterns/queues/platform/queue.policy.spec.ts.tpl +19 -0
- package/templates/be/patterns/queues/platform/queue.policy.ts.tpl +11 -0
- package/templates/be/patterns/queues/platform/queue.port.ts.tpl +14 -0
- package/templates/be/patterns/queues/queue.index.ts.tpl +3 -0
- package/templates/be/patterns/queues/queue.module.ts.tpl +6 -0
- package/templates/be/patterns/queues/queue.queue.ts.tpl +23 -0
- package/templates/be/patterns/reactors/application.command.ts.tpl +10 -0
- package/templates/be/patterns/reactors/application.contracts.ts.tpl +12 -0
- package/templates/be/patterns/reactors/application.handler.ts.tpl +22 -0
- package/templates/be/patterns/reactors/consumer.ts.tpl +19 -0
- package/templates/be/patterns/reactors/message.module.ts.tpl +20 -0
- package/templates/be/patterns/reactors/reactor.index.ts.tpl +1 -0
- package/templates/be/patterns/reactors/reactor.module.ts.tpl +6 -0
- package/templates/be/patterns/realtime/channel.graphql.module.ts.tpl +6 -0
- package/templates/be/patterns/realtime/channel.index.ts.tpl +1 -0
- package/templates/be/patterns/realtime/channel.input.ts.tpl +12 -0
- package/templates/be/patterns/realtime/channel.subscription.spec.ts.tpl +51 -0
- package/templates/be/patterns/realtime/channel.subscription.ts.tpl +32 -0
- package/templates/be/patterns/realtime/channel.type.ts.tpl +9 -0
- package/templates/be/patterns/saga/saga.compensate.command.ts.tpl +11 -0
- package/templates/be/patterns/saga/saga.compensate.contracts.ts.tpl +7 -0
- package/templates/be/patterns/saga/saga.compensate.handler.ts.tpl +22 -0
- package/templates/be/patterns/saga/saga.compensation.ts.tpl +21 -0
- package/templates/be/patterns/saga/saga.complete.command.ts.tpl +11 -0
- package/templates/be/patterns/saga/saga.complete.contracts.ts.tpl +7 -0
- package/templates/be/patterns/saga/saga.complete.handler.ts.tpl +22 -0
- package/templates/be/patterns/saga/saga.done.consumer.ts.tpl +21 -0
- package/templates/be/patterns/saga/saga.failed.consumer.ts.tpl +21 -0
- package/templates/be/patterns/saga/saga.index.ts.tpl +1 -0
- package/templates/be/patterns/saga/saga.message.module.ts.tpl +23 -0
- package/templates/be/patterns/saga/saga.module.ts.tpl +20 -0
- package/templates/be/patterns/saga/saga.service.spec.ts.tpl +70 -0
- package/templates/be/patterns/saga/saga.service.ts.tpl +44 -0
- package/templates/be/patterns/saga/saga.state.ts.tpl +14 -0
- package/templates/be/patterns/saga/saga.step.ts.tpl +11 -0
- package/templates/be/patterns/saga/saga.undo.command.ts.tpl +10 -0
- package/templates/be/patterns/saga/saga.undo.contracts.ts.tpl +5 -0
- package/templates/be/patterns/saga/saga.undo.handler.ts.tpl +21 -0
- package/templates/be/patterns/webhooks/webhook.door.spec.ts.tpl +72 -0
- package/templates/be/patterns/webhooks/webhook.door.ts.tpl +36 -0
- package/templates/be/patterns/webhooks/webhook.http.module.ts.tpl +6 -0
- package/templates/be/patterns/webhooks/webhook.index.ts.tpl +1 -0
- package/templates/be/patterns/webhooks/webhook.request.ts.tpl +9 -0
- package/templates/be/skeleton/apps/__app__/src/__app__.options.ts +3 -0
- package/templates/be/skeleton/apps/__app__/src/app.module.ts +15 -2
- package/templates/be/skeleton/apps/__app__/src/main.ts +7 -15
- package/templates/be/skeleton/apps/cli/src/app.module.ts +30 -0
- package/templates/be/skeleton/apps/cli/src/cli.options.ts +22 -0
- package/templates/be/skeleton/apps/cli/src/main.ts +24 -0
- package/templates/be/skeleton/src/features/cli/cli.module.ts +7 -0
- package/templates/be/skeleton/src/features/cli/index.ts +1 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.cli.spec.ts +17 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.cli.ts +15 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.module.ts +7 -0
- package/templates/be/skeleton/src/features/cli/migrate/subs/run.cli.spec.ts +17 -0
- package/templates/be/skeleton/src/features/cli/migrate/subs/run.cli.ts +18 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.cli.spec.ts +17 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.cli.ts +15 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.module.ts +7 -0
- package/templates/be/skeleton/src/features/cli/seed/subs/run.cli.spec.ts +33 -0
- package/templates/be/skeleton/src/features/cli/seed/subs/run.cli.ts +34 -0
- package/templates/be/skeleton/src/modules/domain/identity/admission.policy.spec.ts +13 -0
- package/templates/be/skeleton/src/modules/domain/identity/auth.guard.spec.ts +40 -0
- package/templates/be/skeleton/src/modules/domain/identity/messages/identity.messages.ts +1 -1
- package/templates/be/skeleton/src/modules/domain/note/errors/note.error.ts +16 -0
- package/templates/be/skeleton/src/modules/domain/note/index.ts +3 -0
- package/templates/be/skeleton/src/modules/domain/note/note.contracts.ts +19 -0
- package/templates/be/skeleton/src/modules/domain/note/note.decorators.ts +9 -0
- package/templates/be/skeleton/src/modules/domain/note/note.module-definition.ts +7 -0
- package/templates/be/skeleton/src/modules/domain/note/note.module.ts +19 -0
- package/templates/be/skeleton/src/modules/domain/note/note.options.ts +2 -0
- package/templates/be/skeleton/src/modules/domain/note/note.service.spec.ts +76 -0
- package/templates/be/skeleton/src/modules/domain/note/note.service.ts +37 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/connection.ts +8 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/entities/note.entity.ts +17 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/migrations/1790000000000-init-note.ts +22 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/note.rows.ts +17 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/note.sql.ts +4 -0
- package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +20 -0
- package/templates/be/skeleton/src/modules/platform/config/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/cqrs/cqrs.contracts.ts +18 -0
- package/templates/be/skeleton/src/modules/platform/database/connection-source.client.spec.ts +41 -0
- package/templates/be/skeleton/src/modules/platform/database/connection-source.client.ts +17 -0
- package/templates/be/skeleton/src/modules/platform/database/database.module-definition.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/database/database.module.ts +77 -0
- package/templates/be/skeleton/src/modules/platform/database/database.options.ts +30 -0
- package/templates/be/skeleton/src/modules/platform/database/database.port.ts +65 -0
- package/templates/be/skeleton/src/modules/platform/database/database.sql.ts +47 -0
- package/templates/be/skeleton/src/modules/platform/database/errors/database.error.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/database/index.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/database/migrate-connections.client.ts +30 -0
- package/templates/be/skeleton/src/modules/platform/database/migration-runner.service.spec.ts +84 -0
- package/templates/be/skeleton/src/modules/platform/database/migration-runner.service.ts +23 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.config.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.connection.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.decorators.ts +10 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-connections.client.spec.ts +108 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-connections.client.ts +75 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-runner.service.spec.ts +88 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-runner.service.ts +29 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.filter.spec.ts +48 -0
- package/templates/be/skeleton/src/modules/platform/errors/messages/errors.messages.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/http-security/errors/http-security.error.ts +12 -0
- package/templates/be/skeleton/src/modules/platform/http-security/execution-request.mapper.spec.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.config.ts +8 -1
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.decorators.ts +8 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.module.ts +14 -1
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.options.ts +12 -0
- package/templates/be/skeleton/src/modules/platform/http-security/messages/http-security.messages.ts +10 -2
- package/templates/be/skeleton/src/modules/platform/http-security/origin.guard.spec.ts +63 -0
- package/templates/be/skeleton/src/modules/platform/http-security/rate-limit.guard.spec.ts +108 -0
- package/templates/be/skeleton/src/modules/platform/http-security/request-validation.service.spec.ts +39 -0
- package/templates/be/skeleton/src/modules/platform/http-security/request-validation.service.ts +25 -0
- package/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.spec.ts +172 -0
- package/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.ts +66 -0
- package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +3 -1
- package/templates/be/skeleton/src/modules/platform/primitives/outcome.mapper.spec.ts +52 -0
- package/templates/be/skeleton-lite/apps/api/Dockerfile +37 -0
- package/templates/be/skeleton-lite/apps/api/src/api.options.ts +16 -0
- package/templates/be/skeleton-lite/apps/api/src/app.module.ts +81 -0
- package/templates/be/skeleton-lite/apps/api/src/main.ts +34 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/admission.policy.ts +14 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/auth.guard.ts +50 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.contracts.ts +26 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.decorators.ts +19 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.module.ts +26 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.options.ts +7 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/index.ts +6 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/errors/supabase.error.ts +19 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/index.ts +10 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.ts +24 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.config.ts +8 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.decorators.ts +17 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts +32 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.options.ts +24 -0
- package/templates/be/skeleton-lite/src/modules/platform/cqrs/index.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.module.ts +54 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.options.ts +23 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.port.ts +10 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.sql.ts +49 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/index.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/migration-runner.service.ts +21 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/primary.config.ts +11 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/seed-runner.service.ts +28 -0
- package/templates/be/skeleton-lite/src/modules/platform/http-security/http-security.module.ts +25 -0
- package/templates/be/skeleton-lite/src/modules/platform/http-security/index.ts +9 -0
- package/templates/be/skeleton-lite/src/modules/platform/i18n/index.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/logging/index.ts +5 -0
- package/templates/be/table/error.ts.tpl +16 -0
- package/templates/be/table/index.ts.tpl +2 -0
- package/templates/be/table/migration.sql.tpl +51 -0
- package/templates/be/table/module-definition.ts.tpl +7 -0
- package/templates/be/table/module.ts.tpl +14 -0
- package/templates/be/table/options.ts.tpl +2 -0
- package/templates/be/table/rows.ts.tpl +4 -0
- package/templates/be/table/service.ts.tpl +23 -0
- package/templates/be/table/sql.ts.tpl +4 -0
- package/templates/be/tool-config/jest.config.js +3 -1
- package/templates/be/upgrade-full/apps/cli/src/app.module.ts +14 -0
- package/templates/be/upgrade-full/apps/cli/src/main.ts +26 -0
- package/templates/be/upgrade-full/src/features/cli/cli.module.ts +6 -0
- package/templates/be/upgrade-full/src/features/cli/migrate/subs/run.cli.ts +23 -0
- package/templates/common/gitignore.base +1 -2
- package/templates/fe/app/package.json.tpl +1 -0
- package/templates/fe/app/tsconfig.json +12 -0
- package/templates/fe/common/app-layout.tsx.partial +8 -0
- package/templates/fe/common/site-shell.tsx.partial +9 -0
- package/templates/fe/image/next/Dockerfile +42 -0
- package/templates/fe/skeleton/apps/app/next.config.ts +23 -0
- package/templates/fe/skeleton/apps/app/postcss.config.mjs +7 -0
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/[locale]/error.tsx +2 -2
- package/templates/fe/skeleton/apps/app/src/app/[locale]/layout.tsx +22 -0
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/[locale]/loading.tsx +2 -2
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/[locale]/not-found.tsx +2 -2
- package/templates/fe/skeleton/apps/app/src/app/[locale]/page.tsx +9 -0
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/global-error.tsx +2 -2
- package/templates/fe/skeleton/apps/app/src/app/globals.css +10 -0
- package/templates/fe/skeleton/apps/app/src/features/layouts/AppLayout/index.tsx +18 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppErrorPage/component.tsx +19 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppErrorPage/index.tsx +11 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppGlobalErrorPage/index.tsx +16 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppHomePage/component.tsx +10 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppHomePage/index.tsx +15 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppLoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppNotFoundPage/index.tsx +9 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/index.ts +4 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/messages/vi.json +28 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/request.ts +4 -0
- package/templates/fe/skeleton/apps/app/src/modules/routes/index.ts +4 -0
- package/templates/fe/skeleton/apps/app/src/proxy.ts +1 -0
- package/templates/fe/skeleton/apps/{__app__ → landing}/next.config.ts +4 -2
- package/templates/fe/skeleton/apps/landing/postcss.config.mjs +7 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/error.tsx +10 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/layout.tsx +22 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/loading.tsx +6 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/not-found.tsx +6 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/page.tsx +9 -0
- package/templates/fe/skeleton/apps/landing/src/app/global-error.tsx +10 -0
- package/templates/fe/skeleton/apps/landing/src/app/globals.css +10 -0
- package/templates/fe/skeleton/apps/landing/src/features/layouts/LandingLayout/index.tsx +24 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingErrorPage/component.tsx +18 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingErrorPage/index.tsx +11 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingGlobalErrorPage/index.tsx +16 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingLoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingNotFoundPage/index.tsx +9 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingPage/component.tsx +24 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingPage/index.tsx +16 -0
- package/templates/fe/skeleton/apps/landing/src/modules/config/index.ts +12 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/index.ts +7 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/messages/vi.json +31 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/request.ts +4 -0
- package/templates/fe/skeleton/apps/landing/src/modules/routes/index.ts +4 -0
- package/templates/fe/skeleton/apps/landing/src/proxy.ts +1 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/index.ts +49 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/proxy.ts +24 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/routing.ts +20 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/branches/Providers/index.tsx +23 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/ErrorNotice/index.tsx +14 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/GlobalErrorNotice/index.tsx +25 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/LoadingNotice/index.tsx +9 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/LocaleShell/index.tsx +21 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/NotFoundNotice/index.tsx +19 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/SiteShell/classNames.ts +4 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/SiteShell/index.tsx +19 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/index.ts +6 -0
- package/templates/fe/skeleton-lite/apps/web/next.config.ts +22 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/error.tsx +10 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/layout.tsx +37 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/loading.tsx +6 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/not-found.tsx +6 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/page.tsx +9 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/providers.tsx +26 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/auth/callback/route.ts +24 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/global-error.tsx +10 -0
- package/templates/fe/{skeleton/apps/__app__ → skeleton-lite/apps/web}/src/app/globals.css +1 -1
- package/templates/fe/skeleton-lite/apps/web/src/app/health/live/route.ts +5 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignInForm/component.tsx +29 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignInForm/index.tsx +41 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignOutButton/component.tsx +17 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignOutButton/index.tsx +38 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/ErrorNotice/index.tsx +13 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/GlobalErrorNotice/index.tsx +24 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/LoadingNotice/index.tsx +7 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/NotFoundNotice/index.tsx +18 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/SiteShell/classNames.ts +4 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/SiteShell/index.tsx +13 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/layouts/AppLayout/index.tsx +31 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppErrorPage/component.tsx +12 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppErrorPage/index.tsx +10 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppGlobalErrorPage/index.tsx +15 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/component.tsx +14 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/index.tsx +30 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppLoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppNotFoundPage/index.tsx +9 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/brand/brand.css +20 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/brand/index.ts +2 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/config/index.ts +20 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/auth/read-session.ts +25 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/auth/write-sign-in.ts +25 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/auth/write-sign-out.ts +17 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/browser.ts +14 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/index.ts +3 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/outcome.ts +59 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/principal.ts +29 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/server.ts +70 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/validation/validation.mapper.ts +50 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/index.ts +8 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages/vi.json +48 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/request.ts +16 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/routing.ts +14 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/routes/index.ts +7 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/routes/safe-next-path.ts +26 -0
- package/templates/fe/skeleton-lite/apps/web/src/proxy.ts +43 -0
- package/templates/fe/table/read.ts.tpl +16 -0
- package/templates/fe/table/write.ts.tpl +16 -0
- package/upgrade/check.mjs +137 -0
- package/upgrade/index.mjs +524 -0
- package/bin/hfs.mjs +0 -233
- package/runtime/scripts/api/fs/rmdir-link.mjs +0 -12
- package/runtime/scripts/lib/test-secrets.mjs +0 -116
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/layout.tsx +0 -20
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/page.tsx +0 -9
- package/templates/fe/skeleton/apps/__app__/src/components/composites/FailureScreen/index.tsx +0 -28
- package/templates/fe/skeleton/apps/__app__/src/features/layouts/LocaleShell/index.tsx +0 -35
- package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/component.tsx +0 -19
- package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/index.tsx +0 -11
- package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/component.tsx +0 -24
- package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/index.tsx +0 -14
- package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/component.tsx +0 -21
- package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/index.tsx +0 -15
- package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/component.tsx +0 -23
- package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/index.tsx +0 -8
- package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/component.tsx +0 -28
- package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/index.tsx +0 -8
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/config.ts +0 -8
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/index.ts +0 -2
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/messages/vi.json +0 -25
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/request.ts +0 -19
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/routing.ts +0 -9
- package/templates/fe/skeleton/apps/__app__/src/modules/routes/index.ts +0 -4
- package/templates/fe/skeleton/apps/__app__/src/proxy.ts +0 -10
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/application/check-liveness.contracts.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/application/check-liveness.handler.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/application/check-liveness.query.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/index.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/system-health.module.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/transport/http/live.controller.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/transport/http/system-health-http.module.ts +0 -0
- /package/templates/fe/skeleton/apps/{__app__ → app}/src/app/health/live/route.ts +0 -0
- /package/templates/fe/skeleton/apps/{__app__ → app}/src/modules/config/index.ts +0 -0
- /package/templates/fe/{skeleton/apps/__app__ → skeleton-lite/apps/web}/postcss.config.mjs +0 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
schema: starci/knowledge-source@1
|
|
2
|
+
id: be.feature.webhooks
|
|
3
|
+
title: Provider webhooks
|
|
4
|
+
purpose: |-
|
|
5
|
+
Given a delivery a payment, identity or shipping provider POSTs to us, how is it received? A webhook is a feature KIND:
|
|
6
|
+
`be/src/features/webhooks/<provider>/` holds one signed door that proves the delivery came from the provider (signature and
|
|
7
|
+
replay window), then hands it to exactly ONE domain intake method. That method records the delivery (deduplicated through the
|
|
8
|
+
inbox) and publishes the domain event with `eventBus.publish(event, tx)` inside its own transaction, because publishing is
|
|
9
|
+
allowed only from `modules/domain`. The door writes nothing and decides nothing; everything after the proof is an event.
|
|
10
|
+
appliesTo:
|
|
11
|
+
- backend
|
|
12
|
+
family: be
|
|
13
|
+
provenance:
|
|
14
|
+
reviewedAt: 2026-10-02
|
|
15
|
+
sources:
|
|
16
|
+
- knowledge/hfs/README.md
|
|
17
|
+
- knowledge/hfs/slots.yaml
|
|
18
|
+
- knowledge/hfs/rules.yaml
|
|
19
|
+
- knowledge/patterns/be/api-auth.yaml
|
|
20
|
+
- knowledge/patterns/be/idempotency.yaml
|
|
21
|
+
- owner decision 2026-10-02 (feature kinds: webhooks, realtime, reactors, saga, jobs, cli; no kind imports another)
|
|
22
|
+
limitations: |-
|
|
23
|
+
Static checks prove the door's shape, that the proof is its first statement and that the only thing it can call after it is
|
|
24
|
+
one domain service method. They do not prove the HMAC scheme matches the provider's documentation, that the replay window
|
|
25
|
+
is the right length or that the intake is idempotent; the provider fake of the test world and the three
|
|
26
|
+
`webhooks/*` scenarios prove those against the real stack.
|
|
27
|
+
rules:
|
|
28
|
+
- id: BE-WEBHOOK-1
|
|
29
|
+
title: A webhook is a kind folder with one door, its module and its own spec
|
|
30
|
+
kind: mandatory
|
|
31
|
+
hfsRules: [R01, R02, R47]
|
|
32
|
+
requirement: |-
|
|
33
|
+
A provider webhook lives in `be/src/features/webhooks/<provider>/` (slot `be.feature.webhooks`), enabled by declaring the pattern
|
|
34
|
+
`webhooks` in `hfs.json` `sides.be.patterns`. The folder holds `index.ts` (the module class an app composes), `transport/http/<provider>-http.module.ts`, `transport/http/<provider>.webhook.ts` (the
|
|
35
|
+
door), `<provider>.webhook.spec.ts` (its spec — the kind's door has no service of its own, so the door carries it) and an optional `transport/http/dto/` of typed
|
|
36
|
+
payload classes (`<event>.request.ts`). Nothing else exists there: no application layer, no handler, no consumer. The kind
|
|
37
|
+
imports only `modules/*`, never another kind, and only an api-kind app composes `<provider>-http.module.ts`.
|
|
38
|
+
rationale: |-
|
|
39
|
+
A webhook is an external caller we do not control, so its door is kept apart from the api features a client uses. One place
|
|
40
|
+
and one shape let a reader find every public signed door and its proof in one folder.
|
|
41
|
+
cases:
|
|
42
|
+
- id: case-1
|
|
43
|
+
when: A new provider (a payment gateway)
|
|
44
|
+
write: 'features/webhooks/payment-gateway/ with index.ts, transport/http/payment-gateway-http.module.ts, transport/http/payment-gateway.webhook.ts, transport/http/payment-gateway.webhook.spec.ts and transport/http/dto/payment-notification.request.ts.'
|
|
45
|
+
verification:
|
|
46
|
+
automated:
|
|
47
|
+
- HFS_SLOT_UNDECLARED
|
|
48
|
+
- HFS_SLOT_AMBIGUOUS
|
|
49
|
+
- HFS_SLOT_NOT_ENABLED
|
|
50
|
+
- HFS_FORBIDDEN_PRESENT
|
|
51
|
+
- HFS_TRACKED_MUST_BE_IGNORED
|
|
52
|
+
- HFS_ROOT_ENTRY_FORBIDDEN
|
|
53
|
+
- HFS_ROOT_MARKDOWN_FORBIDDEN
|
|
54
|
+
- HFS_ROOT_SRC_FORBIDDEN_FE
|
|
55
|
+
- HFS_SRC_LAYOUT_INVALID
|
|
56
|
+
- HFS_MODULE_TIER_INVALID
|
|
57
|
+
- HFS_WORK_IN_FE
|
|
58
|
+
- HFS_STACKS_IN_SIDE
|
|
59
|
+
- HFS_SLOT_REQUIRED_MISSING
|
|
60
|
+
- HFS_MIN_INSTANCES
|
|
61
|
+
- HFS_REQUIRED_FILE_MISSING
|
|
62
|
+
- HFS_ROOT_ENTRY_MISSING
|
|
63
|
+
- HFS_APPS_REQUIRED
|
|
64
|
+
- HFS_APP_LAYOUT_INVALID
|
|
65
|
+
- HFS_README_TITLE_INVALID
|
|
66
|
+
- HFS_README_DESCRIPTION_INVALID
|
|
67
|
+
- HFS_README_SECTION_MISSING
|
|
68
|
+
- HFS_README_SECTION_ORDER
|
|
69
|
+
- HFS_README_DEVELOPMENT_INCOMPLETE
|
|
70
|
+
- HFS_README_WORK_POINTER_MISSING
|
|
71
|
+
- HFS_README_PRIVATE_URL
|
|
72
|
+
- HFS_README_BADGE_NOT_LIVE
|
|
73
|
+
- BE_TEST_TOPOLOGY
|
|
74
|
+
- BE_CONTRACT_UNGUARDED
|
|
75
|
+
manual:
|
|
76
|
+
- Confirm the provider endpoint is one door and that a second endpoint of the same provider is a second door only when it has a different proof.
|
|
77
|
+
relatedExamples: [webhooks]
|
|
78
|
+
- id: BE-WEBHOOK-2
|
|
79
|
+
title: The door verifies first, then makes one domain call
|
|
80
|
+
kind: mandatory
|
|
81
|
+
hfsRules: [R182, R183, R41, R42, R203]
|
|
82
|
+
requirement: |-
|
|
83
|
+
`<provider>.webhook.ts` is one `@Controller` with one `@Post` handler declared
|
|
84
|
+
`@Public({ reason: PublicReason.SignedWebhook })`, thin (R203 `BE_FEATURE_THIN`). The handler's FIRST statement is the unconditional
|
|
85
|
+
`this.<signature>.verify({ provider, rawBody, signature, timestamp })` of the `WebhookSignatureService` of `platform/http-security`
|
|
86
|
+
(HMAC-SHA256 over `<timestamp>.<raw body>` with the provider's secret, a constant-time comparison and a replay window on the signed timestamp; it throws before anything else runs). The provider key and its secret and tolerance are options of `platform/http-security` (`options.webhooks[provider]`). The
|
|
87
|
+
second and last call is one method of a domain service, the intake. The door injects only that service and the signature
|
|
88
|
+
service (injected with `@InjectWebhookSignature()`), holds no branch, loop or `try`, calls nothing else (no parsing, mapping or publishing) and returns nothing: the
|
|
89
|
+
provider gets its status code and an empty body. `@RateLimit(RateTier.Strict)` is required by the signed-webhook reason.
|
|
90
|
+
rationale: |-
|
|
91
|
+
The signature is the authentication of a public door. Making the proof the first statement removes every path to the intake
|
|
92
|
+
that skips it, and a door with one call and no decision has nothing left to test except the proof and the hand-over.
|
|
93
|
+
cases:
|
|
94
|
+
- id: case-1
|
|
95
|
+
when: The door of a payment gateway
|
|
96
|
+
write: |-
|
|
97
|
+
@Controller("webhooks/payment-gateway")
|
|
98
|
+
export class PaymentGatewayWebhook {
|
|
99
|
+
constructor(
|
|
100
|
+
@InjectWebhookSignature() private readonly signature: WebhookSignatureService,
|
|
101
|
+
private readonly payments: PaymentService,
|
|
102
|
+
) {}
|
|
103
|
+
|
|
104
|
+
@Post()
|
|
105
|
+
@HttpCode(HttpStatus.NO_CONTENT)
|
|
106
|
+
@Public({ reason: PublicReason.SignedWebhook })
|
|
107
|
+
@RateLimit(RateTier.Strict)
|
|
108
|
+
async receive(@Req() request: RawBodyRequest<Request>, @Headers("x-signature") signature: string | undefined, @Headers("x-timestamp") timestamp: string | undefined, @Body() body: PaymentNotificationRequest): Promise<void> {
|
|
109
|
+
this.signature.verify({ provider: "payment-gateway", rawBody: request.rawBody, signature, timestamp })
|
|
110
|
+
await this.payments.acceptNotification(body)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
- id: case-2
|
|
114
|
+
when: A delivery whose raw body must be hashed
|
|
115
|
+
write: 'enable the raw body for the app (`NestFactory.create(..., { rawBody: true })` in the api app) and read `request.rawBody`; never hash a re-serialized `body`.'
|
|
116
|
+
verification:
|
|
117
|
+
automated:
|
|
118
|
+
- BE_WEBHOOK_SHAPE
|
|
119
|
+
- BE_WEBHOOK_UNVERIFIED
|
|
120
|
+
- BE_DEFAULT_DENY
|
|
121
|
+
- BE_INPUT_BOUNDED
|
|
122
|
+
- BE_FEATURE_THIN
|
|
123
|
+
manual:
|
|
124
|
+
- Review that the raw body, not a re-serialized one, is verified, and that the replay window matches the provider's tolerance.
|
|
125
|
+
relatedExamples: [webhooks]
|
|
126
|
+
- id: BE-WEBHOOK-3
|
|
127
|
+
title: The intake publishes the event inside its own transaction
|
|
128
|
+
kind: mandatory
|
|
129
|
+
hfsRules: [R80, R152, R151]
|
|
130
|
+
requirement: |-
|
|
131
|
+
The domain intake method (`PaymentService.acceptNotification`) is the delivery method of R80: its first awaited expression
|
|
132
|
+
claims `(source, eventId)` in the `Inbox` and it returns when the claim answers false, so a redelivery is a no-op. It then
|
|
133
|
+
records the delivery and calls `this.eventBus.publish(PaymentConfirmedEvent.create({...}), manager)` inside the same
|
|
134
|
+
transaction (`entityManager.transaction`). The events are typed classes in `modules/events/<service>/<event>.event.ts` that
|
|
135
|
+
equal their `be/contracts/<service>/events.json` entry (`payment.confirmed`, `payment.failed`). The webhook door never
|
|
136
|
+
imports `modules/events` or the event bus.
|
|
137
|
+
rationale: |-
|
|
138
|
+
Recording the delivery and writing the outbox row in one transaction means a crash cannot lose or duplicate the event, and
|
|
139
|
+
keeping the publish in `modules/domain` keeps one place that owns the transaction boundary.
|
|
140
|
+
cases:
|
|
141
|
+
- id: case-1
|
|
142
|
+
when: A confirmed payment arrives
|
|
143
|
+
write: 'acceptNotification claims the inbox row, updates the payment row and publishes PaymentConfirmedEvent in one transaction; a second delivery of the same eventId changes nothing.'
|
|
144
|
+
verification:
|
|
145
|
+
automated:
|
|
146
|
+
- BE_INBOX_DEDUPE_MISSING
|
|
147
|
+
- BE_OUTBOX_WRITE_TX
|
|
148
|
+
- BE_EVENT_CLASS_CONTRACT
|
|
149
|
+
manual:
|
|
150
|
+
- Confirm each provider event kind maps to exactly one published event and that an unknown kind is acknowledged and ignored, not published.
|
|
151
|
+
relatedExamples: [webhooks]
|
|
152
|
+
- id: BE-WEBHOOK-4
|
|
153
|
+
title: Three behaviours are proven on the test world
|
|
154
|
+
kind: mandatory
|
|
155
|
+
hfsRules: [R155]
|
|
156
|
+
requirement: |-
|
|
157
|
+
Declaring the pattern `webhooks` requires e2e or integration tests titled `webhooks/<scenario>: ...` for each scenario
|
|
158
|
+
`bad-signature-is-refused` (a tampered body is refused and nothing is published), `replay-is-refused` (a stale timestamp is
|
|
159
|
+
refused and nothing is published) and `accepted-delivery-publishes-once` (a valid delivery publishes the event once and a
|
|
160
|
+
redelivery publishes nothing more). The provider is the network-edge fake of the test world (`world.fake.<provider>`), which
|
|
161
|
+
signs with the test secret; a real provider is never called. The unit spec `<provider>.webhook.spec.ts` covers the door
|
|
162
|
+
itself with the Nest testing module, a real `WebhookSignatureService` configured with a test secret and a double of the
|
|
163
|
+
domain service.
|
|
164
|
+
rationale: |-
|
|
165
|
+
The door has no logic of its own, so the risk is in the wiring: the raw body, the headers, the real signature scheme and the
|
|
166
|
+
transaction behind the intake. Only a signed request through the real app proves it.
|
|
167
|
+
cases:
|
|
168
|
+
- id: case-1
|
|
169
|
+
when: The e2e of the payment gateway
|
|
170
|
+
write: 'e2e/payment/payment-gateway-webhook.e2e-spec.ts has `it("webhooks/bad-signature-is-refused: ...")`, `it("webhooks/replay-is-refused: ...")` and `it("webhooks/accepted-delivery-publishes-once: ...")`.'
|
|
171
|
+
verification:
|
|
172
|
+
automated:
|
|
173
|
+
- BE_PATTERN_SPEC_MISSING
|
|
174
|
+
manual:
|
|
175
|
+
- Confirm the fake signs exactly as the provider documents and that a contract spec guards its payload fixtures.
|
|
176
|
+
relatedExamples: [webhooks]
|
|
177
|
+
files:
|
|
178
|
+
- path: src/features/webhooks/<provider>/index.ts
|
|
179
|
+
slot: be.feature.webhooks
|
|
180
|
+
template: webhooks/webhook.index.ts.tpl
|
|
181
|
+
role: The public surface of the kind folder, the module class an api-kind app composes.
|
|
182
|
+
- path: src/features/webhooks/<provider>/transport/http/<provider>-http.module.ts
|
|
183
|
+
slot: be.feature.webhooks.http
|
|
184
|
+
template: webhooks/webhook.http.module.ts.tpl
|
|
185
|
+
role: Nest module of the door, composed only by an api-kind app.
|
|
186
|
+
- path: src/features/webhooks/<provider>/transport/http/<provider>.webhook.ts
|
|
187
|
+
slot: be.feature.webhooks.http
|
|
188
|
+
template: webhooks/webhook.door.ts.tpl
|
|
189
|
+
role: The signed door, one controller with one POST handler.
|
|
190
|
+
rules: [BE_WEBHOOK_SHAPE, BE_WEBHOOK_UNVERIFIED, BE_DEFAULT_DENY, BE_INPUT_BOUNDED]
|
|
191
|
+
spec: src/features/webhooks/<provider>/transport/http/<provider>.webhook.spec.ts
|
|
192
|
+
- path: src/features/webhooks/<provider>/transport/http/<provider>.webhook.spec.ts
|
|
193
|
+
slot: be.feature.webhooks.http
|
|
194
|
+
template: webhooks/webhook.door.spec.ts.tpl
|
|
195
|
+
role: Unit spec of the door beside it.
|
|
196
|
+
- path: src/features/webhooks/<provider>/transport/http/dto/<event>.request.ts
|
|
197
|
+
slot: be.feature.webhooks.dto
|
|
198
|
+
role: The typed, bounded provider payload.
|
|
199
|
+
rules: [BE_INPUT_BOUNDED]
|
|
200
|
+
template: webhooks/webhook.request.ts.tpl
|
|
201
|
+
- path: src/modules/platform/http-security/webhook-signature.service.ts
|
|
202
|
+
slot: be.platform
|
|
203
|
+
role: WebhookSignatureService, the one owner of the signature and replay proof.
|
|
204
|
+
spec: src/modules/platform/http-security/webhook-signature.service.spec.ts
|
|
205
|
+
optional: true
|
|
206
|
+
- path: src/modules/domain/<capability>/<capability>.service.ts
|
|
207
|
+
slot: be.domain
|
|
208
|
+
role: The intake method, which claims the inbox and publishes the event in its transaction.
|
|
209
|
+
rules: [BE_INBOX_DEDUPE_MISSING, BE_OUTBOX_WRITE_TX]
|
|
210
|
+
optional: true
|
|
211
|
+
- path: src/modules/events/<service>/<event>.event.ts
|
|
212
|
+
slot: be.events
|
|
213
|
+
role: The typed event the intake publishes.
|
|
214
|
+
rules: [BE_EVENT_CLASS_CONTRACT]
|
|
215
|
+
optional: true
|
|
216
|
+
- path: src/tests/e2e/<area>/<provider>-webhook.e2e-spec.ts
|
|
217
|
+
slot: be.tests.e2e
|
|
218
|
+
role: "Titles webhooks/<scenario>: ... prove the pattern against the provider fake."
|
|
219
|
+
spec: webhooks/bad-signature-is-refused, webhooks/replay-is-refused, webhooks/accepted-delivery-publishes-once
|
|
220
|
+
rules: [BE_PATTERN_SPEC_MISSING]
|
|
221
|
+
optional: true
|
|
@@ -23,14 +23,16 @@ rules:
|
|
|
23
23
|
- id: FE-FOLDER-1
|
|
24
24
|
title: Responsibility directories
|
|
25
25
|
kind: mandatory
|
|
26
|
-
hfsRules: [R01, R02, R59, R64]
|
|
26
|
+
hfsRules: [R01, R02, R59, R64, R26, R54, R56, R91, R94]
|
|
27
27
|
requirement: |
|
|
28
|
-
The front end of every app (`fe/`) is an fe/apps/<app>/ monorepo even with one app
|
|
29
|
-
|
|
28
|
+
The front end of every app (`fe/`) is an fe/apps/<app>/ monorepo even with one app — each app declared in
|
|
29
|
+
`hfs.json` `sides.fe.apps` with kind `next` (slot `fe.app.next`; the scaffold writes `landing` and `app`) — and all
|
|
30
|
+
product source lives under fe/apps/<app>/src. An fe/src/ does not exist. Each Next source root
|
|
30
31
|
(fe/apps/<app>/src) uses app/ for framework adapters; features/{pages,layouts,overlays} for route-facing product
|
|
31
32
|
composition; components/{blocks,composites,branches,leaves} for product visuals; hooks/<domain> for React hooks;
|
|
32
|
-
and modules/<capability> for cohesive reusable technical and domain capabilities. Every app
|
|
33
|
-
|
|
33
|
+
and modules/<capability> for cohesive reusable technical and domain capabilities. Every app carries the required
|
|
34
|
+
module instances of slot `fe.modules` and one brand.css under modules/brand when it sets brand tokens
|
|
35
|
+
(`fe.modules.brand`). No other empty role
|
|
34
36
|
folder is required. Grammar remains a separate product-agnostic package. The only files that may sit directly in the
|
|
35
37
|
source root (the directory holding app/) are the framework-pinned root files listed in frameworkPinnedRootFiles
|
|
36
38
|
below: Next.js loads them from that exact place. Each is a thin framework adapter whose internal imports enter
|
|
@@ -46,9 +48,8 @@ rules:
|
|
|
46
48
|
# keep is decided by the slot fe.source-root-pinned and FE_NEXT_CONVENTIONS, not by this list.
|
|
47
49
|
# Machine list read by scripts/hfs/architecture/framework-pinned.mjs (FE_SOURCE_LAYOUT_INVALID
|
|
48
50
|
# accepts exactly these basenames directly in a Next source root;
|
|
49
|
-
# their imports follow the FE_TIER_DIRECTION matrix). Exact names, case-sensitive, no globs. Supervisor rulings
|
|
50
|
-
#
|
|
51
|
-
# middleware, listed so the list survives the upgrade).
|
|
51
|
+
# their imports follow the FE_TIER_DIRECTION matrix). Exact names, case-sensitive, no globs. Supervisor rulings
|
|
52
|
+
# (proxy is the Next 16 name of middleware, listed so the list survives the upgrade).
|
|
52
53
|
- middleware.ts
|
|
53
54
|
- middleware.js
|
|
54
55
|
- middleware.mjs
|
|
@@ -82,7 +83,7 @@ rules:
|
|
|
82
83
|
fe/apps/<app>/src/modules/api/ or fe/apps/<app>/src/modules/session/ with one explicit public index.ts entry
|
|
83
84
|
- id: case-3
|
|
84
85
|
when: "A reusable product visual without scenario ownership"
|
|
85
|
-
write: "fe/apps/<app>/src/components/
|
|
86
|
+
write: "an owner folder of slot `fe.components` under the layer it belongs to — for example fe/apps/<app>/src/components/leaves/<Name>/index.tsx"
|
|
86
87
|
- id: case-4
|
|
87
88
|
when: "A React hook"
|
|
88
89
|
write: "fe/apps/<app>/src/hooks/<domain>/useAutoScroll.ts; built-in React hook calls may remain in visuals"
|
|
@@ -94,7 +95,7 @@ rules:
|
|
|
94
95
|
fe/apps/<app>/src/modules/i18n/ and the adapter imports it; the names the framework mandates there
|
|
95
96
|
(frameworkPinnedRootExports, for example export const config = { matcher }) keep their framework spelling
|
|
96
97
|
- id: case-6
|
|
97
|
-
when: "Any other file or folder directly under the source root (
|
|
98
|
+
when: "Any other file or folder directly under the source root (an `i18n/request.ts` or a `config.ts` there), and an fe/src/"
|
|
98
99
|
write: >
|
|
99
100
|
Move it to its owner, for example fe/apps/<app>/src/modules/i18n/request.ts, and point framework configuration
|
|
100
101
|
(fe/apps/<app>/next.config.ts) at the new path
|
|
@@ -106,13 +107,53 @@ rules:
|
|
|
106
107
|
verification:
|
|
107
108
|
automated:
|
|
108
109
|
- HFS_SLOT_UNDECLARED
|
|
110
|
+
- HFS_SLOT_AMBIGUOUS
|
|
111
|
+
- HFS_SLOT_NOT_ENABLED
|
|
112
|
+
- HFS_FORBIDDEN_PRESENT
|
|
113
|
+
- HFS_TRACKED_MUST_BE_IGNORED
|
|
114
|
+
- HFS_ROOT_ENTRY_FORBIDDEN
|
|
115
|
+
- HFS_ROOT_MARKDOWN_FORBIDDEN
|
|
116
|
+
- HFS_ROOT_SRC_FORBIDDEN_FE
|
|
117
|
+
- HFS_SRC_LAYOUT_INVALID
|
|
118
|
+
- HFS_MODULE_TIER_INVALID
|
|
119
|
+
- HFS_WORK_IN_FE
|
|
120
|
+
- HFS_STACKS_IN_SIDE
|
|
109
121
|
- HFS_SLOT_REQUIRED_MISSING
|
|
110
|
-
-
|
|
111
|
-
-
|
|
122
|
+
- HFS_MIN_INSTANCES
|
|
123
|
+
- HFS_REQUIRED_FILE_MISSING
|
|
124
|
+
- HFS_ROOT_ENTRY_MISSING
|
|
125
|
+
- HFS_APPS_REQUIRED
|
|
126
|
+
- HFS_APP_LAYOUT_INVALID
|
|
127
|
+
- HFS_README_TITLE_INVALID
|
|
128
|
+
- HFS_README_DESCRIPTION_INVALID
|
|
129
|
+
- HFS_README_SECTION_MISSING
|
|
130
|
+
- HFS_README_SECTION_ORDER
|
|
131
|
+
- HFS_README_DEVELOPMENT_INCOMPLETE
|
|
132
|
+
- HFS_README_WORK_POINTER_MISSING
|
|
133
|
+
- HFS_README_PRIVATE_URL
|
|
134
|
+
- HFS_README_BADGE_NOT_LIVE
|
|
135
|
+
- FE_I18N_PLACEMENT
|
|
136
|
+
- FE_I18N_NAVIGATION
|
|
137
|
+
- FE_I18N_FORMATTER
|
|
138
|
+
- FE_APP_ISOLATION
|
|
139
|
+
- BE_TIER_DIRECTION
|
|
112
140
|
- FE_TIER_DIRECTION
|
|
141
|
+
- ARCH_PACKAGE_IMPORTS_APP
|
|
142
|
+
- FE_ROUTE_FILES_THIN
|
|
143
|
+
- FE_NEXT_CONVENTIONS
|
|
144
|
+
- FE_PAGE_METADATA_MISSING
|
|
145
|
+
- FE_ROUTE_ONE_PAGE
|
|
146
|
+
- FE_ROUTE_DRAWING_DECISION
|
|
147
|
+
- FE_ROUTE_CLIENT_BOUNDARY
|
|
148
|
+
- FE_ROUTE_CLIENT_HOOK
|
|
149
|
+
- FE_ROUTE_DEFAULT_EXPORT
|
|
150
|
+
- FE_HOOKS_ARE_HOOKS
|
|
113
151
|
- FE_CUSTOM_HOOK_LOCATION
|
|
114
|
-
-
|
|
115
|
-
-
|
|
152
|
+
- FE_BLOCK_PRODUCT_HOOK_DEFINITION
|
|
153
|
+
- FE_COMPONENT_DEEP_HOOK_IMPORT
|
|
154
|
+
- FE_SOURCE_FORM
|
|
155
|
+
- FE_SOURCE_LAYOUT_INVALID
|
|
156
|
+
- FE_SLOT_FILE_ROLE
|
|
116
157
|
manual:
|
|
117
158
|
- Confirm the unit's responsibility and public entry, rather than assigning it by consumer count.
|
|
118
159
|
relatedExamples:
|
|
@@ -121,7 +162,7 @@ rules:
|
|
|
121
162
|
- id: FE-FOLDER-2
|
|
122
163
|
title: Discoverable files for one unit
|
|
123
164
|
kind: mandatory
|
|
124
|
-
hfsRules: [R02, R55, R65]
|
|
165
|
+
hfsRules: [R02, R55, R65, R20, R92]
|
|
125
166
|
requirement: |
|
|
126
167
|
A split unit (a connected block, and a feature page, layout or overlay) uses index.tsx for the connected X and
|
|
127
168
|
sibling component.tsx for the pure XBase, its XBaseProps and xDefaultState, plus XState when the shape is its own union
|
|
@@ -149,12 +190,40 @@ rules:
|
|
|
149
190
|
write: "hooks/<domain>/useX.ts or modules/<capability>/...; do not create visual twins"
|
|
150
191
|
verification:
|
|
151
192
|
automated:
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
193
|
+
- HFS_SLOT_REQUIRED_MISSING
|
|
194
|
+
- HFS_MIN_INSTANCES
|
|
195
|
+
- HFS_REQUIRED_FILE_MISSING
|
|
196
|
+
- HFS_ROOT_ENTRY_MISSING
|
|
197
|
+
- HFS_APPS_REQUIRED
|
|
198
|
+
- HFS_APP_LAYOUT_INVALID
|
|
199
|
+
- HFS_README_TITLE_INVALID
|
|
200
|
+
- HFS_README_DESCRIPTION_INVALID
|
|
201
|
+
- HFS_README_SECTION_MISSING
|
|
202
|
+
- HFS_README_SECTION_ORDER
|
|
203
|
+
- HFS_README_DEVELOPMENT_INCOMPLETE
|
|
204
|
+
- HFS_README_WORK_POINTER_MISSING
|
|
205
|
+
- HFS_README_PRIVATE_URL
|
|
206
|
+
- HFS_README_BADGE_NOT_LIVE
|
|
207
|
+
- FE_CLIENT_BOUNDARY
|
|
208
|
+
- FE_CLIENT_SERVER_IMPORT
|
|
209
|
+
- FE_CLIENT_REACHES_SERVER
|
|
210
|
+
- FE_SERVER_ONLY_MARK
|
|
211
|
+
- FE_STORAGE_OUTSIDE_MODULES
|
|
212
|
+
- FE_DANGEROUS_HTML
|
|
155
213
|
- FE_SIZE_AND_STATE_BUDGET
|
|
214
|
+
- FE_LIST_KEY
|
|
215
|
+
- FE_EFFECT_CLEANUP
|
|
216
|
+
- FE_SWALLOWED_ERROR
|
|
217
|
+
- FE_CONSOLE_CALL
|
|
156
218
|
- HFS_SIZE_GROWTH
|
|
157
|
-
-
|
|
219
|
+
- HFS_SIZE_SOFT_BACKLOG
|
|
220
|
+
- FE_COMPONENT_API
|
|
221
|
+
- FE_COMPONENT_WORLD_OWNERSHIP
|
|
222
|
+
- FE_WORLD_OWNER_RENDER_BOUNDARY
|
|
223
|
+
- FE_CONNECTED_BLOCK_RENDER_PAIR
|
|
224
|
+
- FE_PURE_REACHES_DATA
|
|
225
|
+
- FE_PURE_WORLD_HOOK
|
|
226
|
+
- FE_PURE_WORLD_IMPORT
|
|
158
227
|
manual:
|
|
159
228
|
- Confirm each file owns a real responsibility; do not add a component.tsx twin by habit.
|
|
160
229
|
relatedExamples:
|
|
@@ -163,7 +232,7 @@ rules:
|
|
|
163
232
|
- id: FE-FOLDER-3
|
|
164
233
|
title: Route files adapt to one visual owner and every app has its boundaries
|
|
165
234
|
kind: mandatory
|
|
166
|
-
hfsRules: [R53, R54, R55, R57]
|
|
235
|
+
hfsRules: [R53, R54, R55, R57, R26]
|
|
167
236
|
requirement: |
|
|
168
237
|
Route files under app/[locale]/ (page, layout, template, loading, not-found) are server components. A route may
|
|
169
238
|
resolve framework server inputs (params, searchParams, headers, cookies), then mounts one page-level visual owner.
|
|
@@ -192,10 +261,27 @@ rules:
|
|
|
192
261
|
verification:
|
|
193
262
|
automated:
|
|
194
263
|
- FE_ERROR_BOUNDARY_MISSING
|
|
264
|
+
- FE_SUSPENSE_NULL_FALLBACK
|
|
195
265
|
- FE_ROUTE_FILES_THIN
|
|
266
|
+
- FE_NEXT_CONVENTIONS
|
|
267
|
+
- FE_PAGE_METADATA_MISSING
|
|
268
|
+
- FE_ROUTE_ONE_PAGE
|
|
269
|
+
- FE_ROUTE_DRAWING_DECISION
|
|
270
|
+
- FE_ROUTE_CLIENT_BOUNDARY
|
|
271
|
+
- FE_ROUTE_CLIENT_HOOK
|
|
272
|
+
- FE_ROUTE_DEFAULT_EXPORT
|
|
196
273
|
- FE_CLIENT_BOUNDARY
|
|
274
|
+
- FE_CLIENT_SERVER_IMPORT
|
|
275
|
+
- FE_CLIENT_REACHES_SERVER
|
|
276
|
+
- FE_SERVER_ONLY_MARK
|
|
277
|
+
- FE_STORAGE_OUTSIDE_MODULES
|
|
278
|
+
- FE_DANGEROUS_HTML
|
|
197
279
|
- FE_OWNER_REACHABLE
|
|
280
|
+
- FE_ROUTE_HARDCODED
|
|
281
|
+
- FE_HREF_RESOLVES
|
|
282
|
+
- BE_TIER_DIRECTION
|
|
198
283
|
- FE_TIER_DIRECTION
|
|
284
|
+
- ARCH_PACKAGE_IMPORTS_APP
|
|
199
285
|
manual:
|
|
200
286
|
- Confirm visual routes have one page owner and redirect-only routes have no visual tree.
|
|
201
287
|
relatedExamples: []
|
|
@@ -203,7 +289,7 @@ rules:
|
|
|
203
289
|
- id: FE-FOLDER-4
|
|
204
290
|
title: Hooks are hooks; readers and transport live in modules
|
|
205
291
|
kind: mandatory
|
|
206
|
-
hfsRules: [R56, R50, R49]
|
|
292
|
+
hfsRules: [R56, R50, R49, R21, R26]
|
|
207
293
|
requirement: |
|
|
208
294
|
hooks/<domain>/ holds React hooks (use*.ts, one hook per file) and exactly one <domain>.shared.ts for shared
|
|
209
295
|
non-hook helpers of that domain (key builders, token readers). A file in hooks/ that is not a hook and is not the shared
|
|
@@ -235,8 +321,19 @@ rules:
|
|
|
235
321
|
automated:
|
|
236
322
|
- FE_HOOKS_ARE_HOOKS
|
|
237
323
|
- FE_CUSTOM_HOOK_LOCATION
|
|
324
|
+
- FE_BLOCK_PRODUCT_HOOK_DEFINITION
|
|
325
|
+
- FE_COMPONENT_DEEP_HOOK_IMPORT
|
|
326
|
+
- FE_TRANSPORT_OWNER
|
|
327
|
+
- FE_EFFECT_FETCH
|
|
328
|
+
- FE_SWR_KEY_IDENTITY
|
|
329
|
+
- FE_SWR_MUTATION_RESOURCE_IDENTITY
|
|
330
|
+
- FE_ENV_OWNER
|
|
238
331
|
- HFS_DUPLICATE_CODE
|
|
332
|
+
- HFS_DUPLICATE_SYMBOL
|
|
333
|
+
- FE_CROSS_APP_DUPLICATE
|
|
334
|
+
- BE_TIER_DIRECTION
|
|
239
335
|
- FE_TIER_DIRECTION
|
|
336
|
+
- ARCH_PACKAGE_IMPORTS_APP
|
|
240
337
|
manual:
|
|
241
338
|
- Confirm each lifecycle has one feature owner and transport mechanics have one module owner.
|
|
242
339
|
relatedExamples:
|
|
@@ -274,7 +371,7 @@ rules:
|
|
|
274
371
|
- id: FE-FOLDER-6
|
|
275
372
|
title: Keep units cohesive
|
|
276
373
|
kind: mandatory
|
|
277
|
-
hfsRules: [R49, R21]
|
|
374
|
+
hfsRules: [R49, R21, R91, R92]
|
|
278
375
|
requirement: |
|
|
279
376
|
A unit folder contains files that change for the same responsibility. Do not create generic helpers/ or utils/
|
|
280
377
|
buckets inside components, read deployment configuration in presentation, or split files solely to meet a count.
|
|
@@ -301,9 +398,18 @@ rules:
|
|
|
301
398
|
verification:
|
|
302
399
|
automated:
|
|
303
400
|
- FE_ENV_OWNER
|
|
304
|
-
-
|
|
305
|
-
-
|
|
306
|
-
-
|
|
401
|
+
- HFS_DUPLICATE_CODE
|
|
402
|
+
- HFS_DUPLICATE_SYMBOL
|
|
403
|
+
- FE_CROSS_APP_DUPLICATE
|
|
404
|
+
- FE_SOURCE_FORM
|
|
405
|
+
- FE_SOURCE_LAYOUT_INVALID
|
|
406
|
+
- FE_COMPONENT_API
|
|
407
|
+
- FE_COMPONENT_WORLD_OWNERSHIP
|
|
408
|
+
- FE_WORLD_OWNER_RENDER_BOUNDARY
|
|
409
|
+
- FE_CONNECTED_BLOCK_RENDER_PAIR
|
|
410
|
+
- FE_PURE_REACHES_DATA
|
|
411
|
+
- FE_PURE_WORLD_HOOK
|
|
412
|
+
- FE_PURE_WORLD_IMPORT
|
|
307
413
|
manual:
|
|
308
414
|
- Confirm extraction is justified by ownership or lifecycle rather than file length or count.
|
|
309
415
|
relatedExamples: []
|
|
@@ -13,16 +13,16 @@ purpose: |
|
|
|
13
13
|
vulnerability, every hotspot reviewed, no duplicated-lines excess, no cognitive-complexity issue). The one Sonar
|
|
14
14
|
mechanism of the HFS canon is packages/hfs/README.md section "Sonar".
|
|
15
15
|
gate:
|
|
16
|
-
name: starci-
|
|
17
|
-
# A project with no new-code baseline judges the whole project as new code
|
|
16
|
+
name: starci-quality
|
|
17
|
+
# A project with no new-code baseline judges the whole project as new code; a fixed
|
|
18
18
|
# window keeps "new code" the recent work on main, so the server gate is passable on a healthy main.
|
|
19
19
|
newCodePeriod: {type: NUMBER_OF_DAYS, value: 30}
|
|
20
20
|
newCode:
|
|
21
|
-
# Coverage of the
|
|
21
|
+
# Coverage of the measured logic files only (the `ruleParams.be.logicRoles` roles of the `coverage: required` slots). The be unit run writes coverage/lcov.info (@starci/jest-preset coverageReporters lcov) and the
|
|
22
22
|
# managed sonar-project.properties imports it (sonar.javascript.lcov.reportPaths=be/coverage/lcov.info) with
|
|
23
|
-
# sonar.coverage.exclusions = the complement of
|
|
24
|
-
#
|
|
25
|
-
# fe/
|
|
23
|
+
# sonar.coverage.exclusions = the complement of the measured files (SonarQube has no coverage inclusions), rendered by starci app sync from the one derivation scripts/hfs/coverage-scope.mjs (be/jest.config.js and codecov.yml
|
|
24
|
+
# are rendered from it too; a hand edit of any of them is R204 HFS_COVERAGE_SCOPE_DRIFT). The feature tier, declaration files, tests and
|
|
25
|
+
# fe/ are never coverage targets, so coverage on these conditions is the coverage of the modules' logic alone.
|
|
26
26
|
coverage:
|
|
27
27
|
metric: new_coverage
|
|
28
28
|
minPercent: 100
|
|
@@ -40,11 +40,11 @@ newCode:
|
|
|
40
40
|
metric: new_security_hotspots_reviewed
|
|
41
41
|
minReviewedPercent: 100
|
|
42
42
|
unreviewedMax: 0
|
|
43
|
-
# The whole code, not only the new code. Every finding of the HFS canon reaches Sonar through ONE entry, `
|
|
43
|
+
# The whole code, not only the new code. Every finding of the HFS canon reaches Sonar through ONE entry, `starci app lint`
|
|
44
44
|
# (packages/hfs, contract changes hfs-sonar-import and hfs-lint-entry), which writes ONE file, reports/lint.sonar.json
|
|
45
|
-
# (`
|
|
45
|
+
# (`starci app lint --sonar reports/lint.sonar.json`), named by sonar.externalIssuesReportPaths; the gate holds the open-issue count of
|
|
46
46
|
# the whole project at zero. The file carries three engines:
|
|
47
|
-
# starci-hfs the repository findings of `
|
|
47
|
+
# starci-hfs the repository findings of `starci app check` (managed files, tree, pins, CI, contracts; the rule id is the finding code)
|
|
48
48
|
# eslint ESLint's json over the repository (the BE and FE canon plugins alike, per-file and project-graph rules)
|
|
49
49
|
# stylelint stylelint's json over the style glob (front ends)
|
|
50
50
|
# The engines share ONE placement rule (a finding on a file Sonar does not index is filed on the first source file); Sonar's own
|
|
@@ -63,9 +63,9 @@ overall:
|
|
|
63
63
|
hotspots:
|
|
64
64
|
metric: security_hotspots_reviewed
|
|
65
65
|
minReviewedPercent: 100
|
|
66
|
-
# The
|
|
67
|
-
# own measure, so one
|
|
68
|
-
# (sonar-local dashboard) although the project average may round to 100. A file outside the
|
|
66
|
+
# The measured files' coverage (see newCode.coverage), overall and per file: with the exclusions in place each measured file is its
|
|
67
|
+
# own measure, so one measured file below 100 fails the slice verdict (sonar-local evaluateSlice) and the dashboard verdict
|
|
68
|
+
# (sonar-local dashboard) although the project average may round to 100. A file outside the scope is never read.
|
|
69
69
|
coverage:
|
|
70
70
|
metric: coverage
|
|
71
71
|
minPercent: 100
|
|
@@ -81,6 +81,40 @@ overall:
|
|
|
81
81
|
cognitiveComplexity:
|
|
82
82
|
rule: typescript:S3776
|
|
83
83
|
via: overall.issues
|
|
84
|
+
# Lite is the same quality policy without a test or coverage world. Readers select this block from hfs.json edition;
|
|
85
|
+
# keeping both gates in this document makes every threshold data, never a branch-local restatement.
|
|
86
|
+
lite:
|
|
87
|
+
gate:
|
|
88
|
+
name: starci-quality-lite
|
|
89
|
+
newCodePeriod: {type: NUMBER_OF_DAYS, value: 30}
|
|
90
|
+
newCode:
|
|
91
|
+
ignoreBelowChangedLines: 20
|
|
92
|
+
duplication:
|
|
93
|
+
metric: new_duplicated_lines_density
|
|
94
|
+
maxPercent: 3
|
|
95
|
+
issues:
|
|
96
|
+
blockingSeverities: [BLOCKER, CRITICAL]
|
|
97
|
+
metrics: {BLOCKER: new_blocker_violations, CRITICAL: new_critical_violations}
|
|
98
|
+
max: 0
|
|
99
|
+
hotspots:
|
|
100
|
+
metric: new_security_hotspots_reviewed
|
|
101
|
+
minReviewedPercent: 100
|
|
102
|
+
unreviewedMax: 0
|
|
103
|
+
overall:
|
|
104
|
+
issues:
|
|
105
|
+
metric: violations
|
|
106
|
+
max: 0
|
|
107
|
+
engines: [starci-hfs, eslint, stylelint]
|
|
108
|
+
types: {bugs: BUG, code_smells: CODE_SMELL, vulnerabilities: VULNERABILITY}
|
|
109
|
+
hotspots:
|
|
110
|
+
metric: security_hotspots_reviewed
|
|
111
|
+
minReviewedPercent: 100
|
|
112
|
+
duplication:
|
|
113
|
+
metric: duplicated_lines_density
|
|
114
|
+
maxPercent: 3
|
|
115
|
+
cognitiveComplexity:
|
|
116
|
+
rule: typescript:S3776
|
|
117
|
+
via: overall.issues
|
|
84
118
|
# The Sonar enforcers of the rule catalog (knowledge/hfs/rules.yaml): the failure code each condition above is the gate of.
|
|
85
119
|
enforces:
|
|
86
120
|
- {rule: R20, code: HFS_SIZE_GROWTH, enforcer: cognitive-complexity, condition: cognitiveComplexity}
|
|
@@ -91,19 +125,19 @@ enforcedOps: [backend.implement, interface.implement, code.refactor]
|
|
|
91
125
|
reasoning: |
|
|
92
126
|
Chosen against the four projects the local server holds on 2026-09-29 (whole-project duplicated lines
|
|
93
127
|
1.6 / 2.1 / 1.7 / 0.0 percent), so new code that meets them is at or below what main already carries.
|
|
94
|
-
coverage 100 on
|
|
95
|
-
100 threshold on
|
|
96
|
-
verdict and the server gate show the number the runner enforces, file by file. Only
|
|
97
|
-
lives there, the thin
|
|
128
|
+
coverage 100 on the measured logic files, overall and new code (owner 2026-10-01): the unit project already fails below its per-file
|
|
129
|
+
100 threshold on the `ruleParams.be.logicRoles` files of the `coverage: required` slots; Sonar imports the same run's lcov with the same scope, so the dashboard, the slice
|
|
130
|
+
verdict and the server gate show the number the runner enforces, file by file. Only the modules' logic counts: business logic
|
|
131
|
+
lives there, the feature tier is thin (R203) and proven by integration and e2e, and the front end has no unit tests.
|
|
98
132
|
duplication 3: the Sonar way value; the worst project today is 2.1, so 3 rejects a real copy-paste block and
|
|
99
133
|
passes ordinary work.
|
|
100
134
|
blocker/critical 0: the two severities that are defects, not style. main carries old debt of both kinds
|
|
101
|
-
(
|
|
135
|
+
(one product repository carries 3 blocker and 137 critical), so the SLICE verdict reads only changed lines and never main's backlog;
|
|
102
136
|
major and lower are reported on the summary and never fail a slice.
|
|
103
137
|
overall issues 0 and overall duplication 3: the server gate is also the owner's definition of done for the HFS canon:
|
|
104
138
|
a repository that carries any open ESLint, stylelint or HFS finding is not green, whatever the age of the line. The
|
|
105
139
|
op slice keeps judging changed lines (an op cannot fix a repository's whole backlog); the dashboard and CI show the
|
|
106
|
-
whole-project condition. Adopting a repository therefore means clearing its imported findings, which `
|
|
140
|
+
whole-project condition. Adopting a repository therefore means clearing its imported findings, which `starci app check`,
|
|
107
141
|
eslint and stylelint already demand at land.
|
|
108
142
|
hotspots 0 unreviewed: a hotspot is a question the author must answer; on changed lines it is answered in the
|
|
109
143
|
same slice.
|