Architecture & scalability engineering
This document is the operational handoff for the implemented engineering items in BACKLOG K1-K70. Deferred product/enterprise explorations remain unchecked in the backlog.
Contracts, data flow, and projections
- Shared event DTOs and stream names live in
internal/platform/events.go. Registration emitsUserCreatedEvent, includingdisplay_name(K2/K4). - Every service publisher persists to
audit.event_outboxbefore attempting Redis delivery. The worker’s generic outbox relay publishes any stream, not only audit events (K6). - Users and RBAC consumer groups start at stream ID
0. Operators can reset a worker group withgo run ./services/worker -replay-from-start <stream>; stop active workers first (K7). - Registration is a choreographed, idempotent saga: auth commits identity and emits
user.created; users updates its profile projection; RBAC assigns the defaultuserrole. Replays use upserts (K8). WebhookProviderand the existingplatform.Mailerform anti-corruption boundaries: domain jobs never expose provider HTTP/SMTP response models (K9).- The users list is the CQRS read side. Dashboard totals and daily registration series use concurrently refreshed materialized views, refreshed once per minute under a distributed scheduler lock (K5/K13/K14).
Extension points and services
- Worker handlers implement
WorkerHandlerand register by name. SetWORKER_HANDLERS=email,audit,webhookto enable plugins per deployment (K20/K21). - Gateway upstream discovery is environment-driven. Each
UPSTREAMSvalue may contain comma-separated endpoints for failover/load distribution (K22). infra/k8s/blue-green.yamlsupplies two slots and a stable Service selector; promotion and rollback are single selector patches (K24).- Auth exposes
POST /internal/token/introspect, protected byX-Internal-Secret. It checks signature, expiry, current account state, and current claims version (K29). - User states use the shared active/inactive/deleted state machine. Deleted is terminal (K37).
- Users exposes authenticated multipart
POST /api/v1/users/avatar/resize. Inputs are capped at 8 MiB and 4096x4096, then emitted as <=512x512 JPEG using only the Go standard library (K48). services/scheduleris a two-replica, leader-elected scheduler. Jobs come fromSCHEDULED_JOBSJSON and publish through the universal outbox (K53-K55).
Edge and infrastructure
- Redis-backed idempotency and distributed rate limiting remain the shared edge implementations (K56/K57).
- Vault/ESO rotation and cert-manager resources live under
infra/k8s/security; rotation preserves the previous key during rollout and certificates rotate their private keys automatically (K60/K61). - Gateway has two replicas behind a Kubernetes Service/HPA. Middleware names are selected with
GATEWAY_MIDDLEWARES(K62/K63). - OpenAPI extensions configure transformations and policy:
x-request-headers,x-cache-ttl, andx-consumer-quota-per-minute.CONSUMER_QUOTASJSON overrides route quotas by JWT subject. Cache keys include the subject (K65/K66/K68). WEBSOCKET_ROUTESmaps any gateway path to an HTTP(S) upgrade target;REALTIME_UPSTREAMremains the/wscompatibility fallback (K67).
Fitness gates
node scripts/check-template-drift.mjs detects missing template artifacts for contract services. node scripts/check-architecture.mjs rejects direct service-to-service Go imports and migrations that create another service’s schema. Both run in CI (K1/K70).
Before rollout, run go test ./..., both Node checks, manifest validation, and the repository’s existing contract/quality gates.