Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

LearnStack Engineering Standards

This directory contains the engineering rules that apply across the LearnStack codebase. Architecture docs (docs/architecture/) explain what we are building; standards explain how we build it.

How to Use This Directory

  • Author-side: before opening a PR, skim the standards that touch your change.
  • Reviewer-side: reference standards in review comments rather than re-litigating preferences.
  • Newcomer-side: read 00-principles.md first; the rest is reference material.
  • Disagreement: propose a change via PR against the standard itself. Standards are versioned documents, not folklore.

Index

# Document Scope
00 Principles The handful of beliefs every other standard descends from.
01 Architecture Standards Module boundaries, dependency direction, ports & adapters, aggregate ownership.
02 Backend Coding Standards C# / .NET style, async, nullability, records, MediatR, EF Core.
03 Frontend Coding Standards TypeScript / React / Next.js style, components, hooks, data fetching.
04 API Design Standards REST, Problem Details, pagination, idempotency, versioning.
05 Database Standards Schema conventions, migrations, indexing, tenant-aware patterns.
06 Testing Standards Unit / integration / architecture / E2E / contract tests; pyramid; coverage targets.
07 Frontend Architecture Standards App Router layout, server vs client components, tenant context, SDK shape.
08 Localization Standards i18n rules for strings, content, URLs, SEO, formatting.
09 Error Handling Standards Exception hierarchy, Problem Details, frontend error boundaries, user-facing copy.
10 Observability Standards Logging, tracing, metrics, correlation, redaction.
11 Security Standards Auth, tenant isolation enforcement, OWASP, secrets, file uploads, headers.
12 Infrastructure Standards Docker, CI/CD, environments, configuration, deployment.
13 Documentation Standards ADRs, code comments, diagrams, doc style.
14 Git Workflow Standards Branching, commits, PRs, reviews.
15 Performance Standards Budgets, caching, query shape, frontend perf.
16 Accessibility Standards WCAG targets, semantic HTML, keyboard, screen readers.
17 Code Review Standards What to look for, what not to block on, etiquette. Zero-tolerance blockers and author self-review gate.
18 Audit Coverage Standards Which operations must be audited; payload contract; retention; per-module classification matrix.
19 Permissions Standards {module}.{resource}.{action} naming, closed action set, registry pattern, matrix template, built-in roles.
20 Infrastructure Stack Standards Demand-gated building blocks, the foundation ports (IEventBus, ICacheService, ISecretProvider), APISIX gateway, Hub contract surface + its two invariants, entitlement projection, outbox/inbox usage.
21 Architecture Tests + Analyzers Catalogue Single source of truth for the identifier, assertion, status, and source ADR / standard of every non-skippable architecture test or Roslyn analyzer. Cross-link target so renames touch one place.

Status of Each Standard

Standards have one of three states:

  • Active. Currently enforced; PRs must comply. There is code, tooling, or a live process that the standard governs today.
  • Adopted. Agreed and binding on the code that will implement it — but that code does not exist yet, so nothing enforces it beyond review.
  • Draft. Proposed; open for discussion.

The rule that makes the model mean something

A standard with no implementing code is Adopted, not Active.

Each document declares its state at the top, and until 2026-08-08 all twenty-two declared Active — including standards governing endpoints, migrations, permissions and audit rows that do not exist. A three-state model whose every member sits in one state is decorative: it tells a reader nothing, and it quietly overstates how much of the corpus is load-bearing.

"Adopted" is not a weaker commitment. It is the honest one. It says: this is the rule the implementing PR must satisfy, and there is nothing standing between a violation and main except a reviewer who remembers. That is exactly the situation in which a reviewer most needs to know.

Promotion Adopted → Active happens in the PR that lands the enforcement — the migration, the endpoint, the analyzer, the architecture test — not in a separate bookkeeping pass.

Honest status today

The table below is the current, accurate state as of 2026-08-28, at HEAD with Phase 02a Packets 0–3, 3b, 4, 5 and 6 shipped.

The individual documents still declare Active in their own headers. Reconciling the twenty-two status lines with this table is a Phase 02a Packet 10 deliverable, landed together with the architecture-test reconciliation so the two views of "what is actually enforced" change in one commit. Until that lands, this table wins.

# Standard Status What does or does not enforce it today
00 Principles Active Governs every PR and every ADR; principles 1, 16 and 17 are already deciding live scope questions.
01 Architecture Standards Active Module layout shipped; ModuleDomain_DoesNotDependOn_* and the planted-violation meta-test are green.
02 Backend Coding Active MediatR pipeline, Result<T>, IClock, the LS0001 analyzer and the pipeline-order test all ship. Packet 6 brought the first DbContext, the first aggregates and the ambient unit of work, so its EF Core and domain-modelling clauses are live too — for one module.
03 Frontend Coding Adopted ESLint and TypeScript strict mode are configured, and Packet 3b stood up the Vitest harness (jsdom + Testing Library) with one render test — so the required frontend check now asserts something. apps/web is otherwise still a scaffold with no components. First real code: Phase 02d.
04 API Design Active Packet 4 shipped the versioned route convention and its startup guards, one Problem Details shape on every error including the framework-minted ones, cursor pagination, the sort grammar, idempotency keys, ETag concurrency, correlation ids, the request-body limit and the tenancy edge — each with tests in the required backend check. No business endpoint exists yet; the conventions they will land into do.
05 Database Active Packet 6 applied it: two migration chains, ten tables, the four-role model, and the canonical RLS template this document owns — ENABLE and FORCE, one AND-ed policy per table, an explicit WITH CHECK — asserted against a real PostgreSQL as learnstack_app. Its § Concurrency, § Table classes, § Indexes and § GRANT matrix each have a test that fails without them. Partitioning and the retention job are still ahead.
06 Testing Active Unit, architecture, contract and integration suites all run in the required backend job — Packet 4 removed the filter that used to exclude the integration assembly, which by then held the only tests that could catch an unversioned route. The Docker-bound backend-integration job activated in Packet 6 with the four-role provisioning suite; the split is by [Trait("Requires","Docker")] and the two jobs' filters are exact complements.
07 Frontend Architecture Adopted Route groups exist as empty layouts; server/client split, tenant context and SDK shape are exercised first in Phase 02d.
08 Localization Adopted Packet 6 shipped tenant_locales and the slug schema; the i18n runtime lands in Phase 04. Nothing enforces "exactly one default locale per tenant" yet — recorded as an open question in the Tenancy module spec, Packet 7's call.
09 Error Handling Active L1 IExceptionHandler, the exception hierarchy, ProblemDetailsFactory and HttpStatusMap shipped in Packet 3.
10 Observability Active Serilog → OTLP, OpenTelemetry SDK, TenantContextSpanProcessor and the redaction enrichers shipped in Packet 3.
11 Security Adopted No auth yet; RLS is live. Packet 6 shipped the policies, the four roles and the isolation suite that runs as learnstack_app, and Packet 4 shipped the header-facing half — the tenancy edge, the trusted-hop predicate, host normalization and the anonymous rate limiter. Tenant isolation lands in Packet 7, authentication in Phase 02b. Its § Tenant Context is nonetheless the binding authority the implementing PR must follow.
12 Infrastructure Active Compose stack, Makefile, CI workflow, pre-commit hooks and secret scanning all live since Phase 01.
13 Documentation Active Governs this corpus; the CI link audit walks changed Markdown.
14 Git Workflow Active Conventional Commits, hooks and required checks are live. Two branch-protection settings — Require approvals and Do not allow bypassing — are deferred by maintainer decision (2026-08-10) while the repository has one active contributor; the trigger and what activating them involves are recorded in CONTRIBUTING § Branch protection. Everything else in Standards 14 is enforced today.
15 Performance Adopted No budget is measured and no load test exists. Enforcement lands in Phase 11.
16 Accessibility Adopted No user interface to audit. First surfaces render in Phase 02d; automated axe checks in Phase 06.
17 Code Review Active Applied to every pull request merged so far; the zero-tolerance blocker list is in live use.
18 Audit Coverage Adopted AuditLogBehavior is a shell and audit_log does not exist. Lands in Packet 9 under ADR-0033.
19 Permissions Adopted No permission key, policy or role exists. Lands in Phase 03.
20 Infrastructure Stack Adopted ISecretProvider shipped in Packet 3 and DeploymentMode branching is real, but the ports land in Packet 5 and the Dapr / Kafka / APISIX / Vault adapters are demand-gated to Phase 11 per ADR-0035.
21 Architecture Tests Catalogue Active Twenty-nine test methods run in the architecture assembly and seven further implemented rules run beside it, three of them against an applied schema; the catalogue's own per-row status column distinguishes those from the registered-but-unimplemented majority.

Thirteen Active, nine Adopted. That split is the honest picture of a platform whose foundation is real and whose domain has not been written yet — and it is far more useful to a reviewer than twenty-two identical labels.

Relationship to ADRs

Document type Purpose
ADR (docs/decisions/) A one-time decision with status, context, decision, consequences. Immutable history, corrected only by the two bounded mechanisms in 13-documentation.md § Correcting and Amending ADRs.
Standard (docs/standards/) An ongoing rule that the team applies day to day. Editable as the team learns.

When a standard is established, an ADR records the moment of adoption. The ADR then points at the standard for the living detail.

Tooling

Where a standard can be enforced by automation, it must be:

  • Roslyn analyzers / .editorconfig for backend.
  • ESLint / TypeScript strict mode for frontend.
  • Custom architecture tests (NetArchTest / ArchUnitNET) for module-boundary rules.
  • Test conventions enforced by CI.
  • Commit / PR rules enforced by GitHub Actions and CODEOWNERS.

Manual-only rules are flagged in each document.