Files
PersonalBlog/docs/engineering-standards.md
T
2026-08-27 08:18:48 +00:00

4.5 KiB

Engineering standards

TypeScript (§10)

Server baseline: target ES2023, module NodeNext, moduleResolution NodeNext, strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitOverride, useUnknownInCatchVariables, verbatimModuleSyntax, declaration, sourceMap. Admin/Vite may use moduleResolution: "Bundler". ESM-first; no any in public SDK contracts; runtime data validated even when TS types exist; public contract types narrow and intentionally versioned.

Data access & transactions (§24)

Kysely exists only in the DB adapter/extension-storage implementation: PostListSection → ContentQueryService → ContentRepository (interface) → PostgresContentRepository → Kysely/pg. Mutating commands are transactional (validate → BEGIN create revision / update entry / update publish state → COMMIT → best-effort domain event).

Migrations (§25)

Core migration IDs immutable and ordered. Each extension owns an independent chain in eppp_extension_migrations. Startup: connect → advisory migration lock → core migrations → discover/validate manifests → extension migrations → release lock → activate registries → readiness. Never edit a released migration; fix mistakes in a new one; destructive changes require backup/recovery notes; favour expand/contract; failure identifies extension/migration ID; replicas cannot race; PG major upgrades are separate operator procedures.

Test strategy (§58)

  • Unit (Vitest 4.1.10): content transitions, slug rules, manifest/version validation, theme/preference resolution, settings validation, block schema/migration, navigation validation.
  • Integration (real PostgreSQL 18.6): repositories, transactions, migrations, advisory lock, sessions, preference persistence, extension migration ledger, queries/indexes. Fastify injection for route-level integration.
  • E2E (Playwright 1.62.1): bootstrap/login, create draft, draft-not-public, publish, edit/revision, Home composition, navigation, logout/session expiry, theme selection, preference persistence, extension disable safety. Public flows run in Chromium, Firefox, WebKit.
  • Container smoke: build → compose → ready → bootstrap fixture → publish → fetch Home/article → restart → verify persistence.

CI/CD quality gates (§59)

Every PR: frozen install, formatting/lint, typecheck, unit tests, architecture fitness tests, PostgreSQL integration tests, admin build, server/public build, manifest/schema validation. Main/release additionally: Docker image build, Compose smoke, Playwright critical E2E, migrate-from-previous fixture, restore test, dependency/security scan, SBOM generation.

Architecture fitness tests (§57, CI-enforced)

FIT-001 core imports no concrete extension · FIT-002 no Amber token values in core · FIT-003 unique namespaced extension IDs · FIT-004 unique contribution IDs · FIT-005 manifests validate · FIT-006 default settings validate · FIT-007 old document fixtures render/migrate · FIT-008 disable/re-enable without data loss · FIT-009 invalid/missing theme falls back · FIT-010 browser bundles can't import server/DB packages · FIT-011 UI can't import Kysely/pg · FIT-012 no core hydration bundle · FIT-013 migration IDs immutable/unique · FIT-014 golden tuple passes · FIT-015 no outbound HTTP outside hardened fetch · FIT-016 chart SVG has no literal colour values · FIT-017 embed iframes only allowlisted + CSP matches.

Definition of Ready (§44)

A story enters a sprint only when: outcome, acceptance criteria, owning module, core-vs-extension ownership, data/schema impact, migration requirement, security impact, failure states, UX states, API impact, observability need, test strategy, dependencies are all known. "Add plugin support" is not a ready story.

Definition of Done (§45)

Acceptance criteria pass; dependency rules pass; runtime input validated; unit/integration/E2E tests pass; immutable migrations; failure state implemented/tested; accessibility + responsive verified; security addressed; diagnostics appropriate; schema/API version bumped if needed; older fixtures still work/migrate; docs updated; Docker build succeeds; Compose smoke passes; peer review completed.

Non-functional requirements (§66)

Latency targets are measurement-first (reference hardware agreed in Sprint 7). Byte budgets are day-one and CI-asserted (v1.1): public HTML <30 KB compressed; CSS <20 KB compressed; public JS outside opt-in islands = 0 bytes (FIT-012); each island <10 KB compressed; third-party requests on initial load = zero.