diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cf5d719..a108d818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ Releases up to 2.63.0 are listed in check-harness rules ([#2082]) - The git template drops its submodule, numbered-document and base64 rules and the .vscode allowlist ([#2093]) +- The backend-quality template is retired; its general rules move to the HTTP + template ([#2102]) ### Added @@ -206,6 +208,7 @@ Releases up to 2.63.0 are listed in [#2099]: https://github.com/solid-ai-dev/solid-ai-templates/pull/2099 [#2100]: https://github.com/solid-ai-dev/solid-ai-templates/pull/2100 [#2101]: https://github.com/solid-ai-dev/solid-ai-templates/pull/2101 +[#2102]: https://github.com/solid-ai-dev/solid-ai-templates/pull/2102 ## [2.90.0] - 2026-09-12 diff --git a/docs/architecture/05-building-block-view.md b/docs/architecture/05-building-block-view.md index 8a1d0553..47097af0 100644 --- a/docs/architecture/05-building-block-view.md +++ b/docs/architecture/05-building-block-view.md @@ -62,13 +62,13 @@ The core tier, as the manifest states it today: - `templates/core/review.md` - `templates/core/oop.md` -Measured: 11 `[DEPENDS ON]` tokens across 7 templates name one of these -files, and 7 manifest entries name a core id in `depends_on`. Declaring one +Measured: 9 `[DEPENDS ON]` tokens across 6 templates name one of these +files, and 6 manifest entries name a core id in `depends_on`. Declaring one is redundant rather than forbidden — the seeding reaches the file either way, and the directive documents a dependency a reader would otherwise -infer. Reached by the seeding alone: `base-review`. A chain assembled by -walking the directives does not reach that set and reports nothing about it, -because nothing declares what is absent. +infer. Reached by the seeding alone: `base-review`, `base-oop`. A chain +assembled by walking the directives does not reach that set and reports +nothing about it, because nothing declares what is absent. Every top-level list of entries except `core` and `fork_core` is a section diff --git a/docs/migrating-to-v3.md b/docs/migrating-to-v3.md index 0d140300..62181381 100644 --- a/docs/migrating-to-v3.md +++ b/docs/migrating-to-v3.md @@ -62,6 +62,9 @@ receives nothing (ADR-051). | Kubernetes: namespaces, two replicas per service, probes, PodDisruptionBudget, ConfigMap secrets | `base-containers` | removed; resources as code and the readiness gate remain, orchestrator-neutral | | Exact names: plural snake_case tables, `is_` booleans, `_id` keys, alphabetical junctions, `ix_` and `ux_` indexes | `base-data-modeling` | one convention per store, recorded in the context file; relational rules say so | | Per-target product choices: managed CAs, `step-ca`, F5 and MetalLB, Route 53 and Consul, Harbor and Athens, Vault topologies | `base-deployment` | removed; each section keeps its ID and the rules that hold on any target | +| `backend-quality`: the handler, service and repository layering and its pattern catalogue | `backend-quality` | removed with the template; declare a stack's own architecture in a fork | +| `backend-quality`: process lifecycle, admin processes, outbound timeouts, auth before logic, rate limits | `backend-quality` | `backend-http` | +| `backend-quality`: N+1, async I/O, API deprecation, circuit breaker, outbox | `backend-quality` | already in `backend-database`, `backend-concurrency`, `backend-api`, `backend-errors`, `backend-messaging` | | The numbered-document check after concurrent merges, the first-CI-run rule for a check on its own change | `base-git` | this repository's playbook; the `check-heading-numbers` hook still ships | | The submodule update after a pin bump, the base64 bundle mask, the `.vscode` allowlist | `base-git` | removed; a neutral editor-settings rule remains | | Factory classmethods; `*-overlay.png` naming | `base-oop`, `base-measurement` | neutral rules remain | diff --git a/templates/backend/http.md b/templates/backend/http.md index 7810ea0c..b9735177 100644 --- a/templates/backend/http.md +++ b/templates/backend/http.md @@ -9,10 +9,29 @@ - Use a well-known default in development, and the port the platform assigns in production +## Process lifecycle +- Start fast — keep initialisation short (MUST) +- Shut down gracefully on `SIGTERM`: finish in-flight work, release + resources, then exit (MUST) +- Force-exit when a graceful shutdown passes its deadline +- Recover cleanly when a process is killed without warning (`SIGKILL`, + power loss) (MUST) +- Keep no state in the process; use external stores, so any instance can + be replaced + +## Admin processes +- Run one-off tasks (migrations, data fixes, REPL sessions) with the + application's code, config and dependencies (MUST) +- Commit admin scripts to the repository; never run them as ad-hoc shell + commands (MUST) +- Prefer idempotent scripts — safe to re-run +- Never run an admin task against production without a tested rollback plan + ## Handler design - Handlers are thin: decode request → call service → encode response - No business logic in handlers — delegate to a service layer - Validate all incoming request data before processing +- Set a timeout on every outbound call (HTTP clients, database queries) ## URI design - Path segments MUST be lowercase with hyphens as word separators — @@ -105,3 +124,5 @@ authorisation - Internal API endpoints SHOULD require authentication at minimum - Write endpoints MUST NOT be accessible without a valid authenticated identity +- Apply authentication and authorisation before any business logic runs +- Rate-limit public endpoints — never expose an unbounded write operation diff --git a/templates/backend/quality.md b/templates/backend/quality.md deleted file mode 100644 index b9901f96..00000000 --- a/templates/backend/quality.md +++ /dev/null @@ -1,77 +0,0 @@ -# Backend — Quality Attributes -[ID: backend-quality] -[DEPENDS ON: templates/core/quality.md, templates/core/oop.md] -[DEPENDS ON: templates/security/security.md, templates/infra/containers.md] - -## Layered architecture -- Enforce a strict handler → service → repository separation -- No database access in handlers — always go through the service layer -- No HTTP concerns in the service layer — services are framework-agnostic -- Domain logic lives in the service layer, not in models or schemas - -## Design patterns - -Prefer these patterns for backend concerns: - -- **Repository** — abstract all data access behind a repository interface; - the service layer never constructs queries directly -- **Service layer** — encapsulate business logic in service objects that - hold their injected collaborators and no request state; one service per - domain aggregate -- **Unit of Work** — coordinate multiple repository operations in a single - transaction; commit or roll back as one atomic unit -- **Factory / Factory Method** — centralise object construction, especially - for domain objects with complex invariants -- **Strategy** — swap algorithms or business rules (pricing, validation, - export format) at runtime without modifying the caller -- **Observer / Event** — decouple producers from consumers for domain events - (user registered, order placed); use an internal event bus or message queue -- **Circuit Breaker** — wrap all outbound calls to external services; - fail fast and recover gracefully rather than cascading timeouts -- **Outbox** — when publishing an event must be atomic with a DB write, - write to an outbox table in the same transaction and relay asynchronously -- **CQRS** — separate read models from write models when query and command - requirements diverge significantly; do not apply by default - -## Disposability - -- Processes MUST start fast — minimize initialization time -- Processes MUST shut down gracefully on `SIGTERM` — finish - in-flight work, release resources, then exit -- Set a shutdown timeout — if graceful shutdown exceeds the - deadline, force-exit -- Design for crash safety — the system MUST recover cleanly if - a process is killed without warning (`SIGKILL`, power loss) -- Do not store state in-process — use external stores (database, - cache, queue) so processes are disposable and replaceable - -## Admin processes - -- One-off tasks (migrations, data fixes, REPL sessions) MUST run - in the same environment as the application — same code, same - config, same dependencies -- Admin scripts MUST be committed to the repository — not run - from ad-hoc shell commands -- Prefer idempotent scripts — safe to re-run without side effects -- Never run admin tasks directly against production without a - tested rollback plan - -## Security -[EXTEND: security-input] - -- Rate-limit public endpoints — never expose unbounded write operations -- Apply authentication and authorisation before any business logic - executes - -## Performance -- Prefer async I/O for network-bound operations -- Cache only when there is a measured need — document cache invalidation - strategy -- Avoid N+1 queries — use eager loading or batch fetching -- Set timeouts on all outbound calls (HTTP clients, DB queries) - -## API stability -- Never remove or rename a field in a response without a deprecation period -- Increment the API version (`/v2/`) for breaking changes — keep the old version - alive -- Document deprecated endpoints; set a removal date before retiring them diff --git a/templates/manifest.yaml b/templates/manifest.yaml index 6691cdd4..70c022f9 100644 --- a/templates/manifest.yaml +++ b/templates/manifest.yaml @@ -170,10 +170,6 @@ backend: file: templates/backend/monitoring.md description: Key metrics, thresholds, alerts, dashboards, incidents depends_on: [backend-observability] - - id: backend-quality - file: templates/backend/quality.md - description: Layered architecture, security, performance, API stability - depends_on: [base-quality, base-oop, base-security, base-containers] stacks: - id: stack-fixture file: templates/fixture/stack.md diff --git a/tests/baselines/template-quality.txt b/tests/baselines/template-quality.txt index 6679eeec..3acae237 100644 --- a/tests/baselines/template-quality.txt +++ b/tests/baselines/template-quality.txt @@ -11,13 +11,12 @@ templates/backend/edge.md 89.7 templates/backend/errors.md 91.7 templates/backend/features.md 92.2 templates/backend/grpc.md 96.1 -templates/backend/http.md 96.4 +templates/backend/http.md 97.8 templates/backend/jobs.md 97.2 templates/backend/messaging.md 96.8 templates/backend/microservices.md 93.5 templates/backend/monitoring.md 98.5 templates/backend/observability.md 96.6 -templates/backend/quality.md 98.3 templates/backend/webhooks.md 86.9 templates/core/agents.md 100.0 templates/core/config.md 99.3