Skip to content

ADR-012: Domain Cache Sync Pattern

Status: Accepted
Date: 2026-03-09
Deciders: CepatEdge maintainers

Context

High-read domains need predictable API performance without excessive DB load. Generic cache invalidation after every mutation causes extra DB reads and stale list/detail divergence.

Decision

Adopt a domain-level cache sync pattern for read-heavy modules:

  • Cache-first reads with explicit DB fallback on miss.
  • Separate cache shapes for list and detail.
  • Domain-local sync helpers that patch both list and detail caches after DB writes.
  • No request-body to cache writes; patch payloads must come from persisted DB results.
  • List cache schema versioning to support safe payload evolution.

Implementation Rules

  1. Keep cache update helpers close to the domain (e.g. cache/<domain>/sync.ts).
  2. Mutation flow is always: DB write -> build patch from DB result -> sync caches.
  3. Detail cache can be richer than list cache; list must only contain fields needed by list UI.
  4. Keep permissions/session-specific computed fields out of globally shared list cache.
  5. Introduce cache version bumps when list contract changes.

Concrete Examples

Users module

  • cache/user/sync.ts exposes helpers like cacheUserProfile, cacheUserAvatar, cacheUserSecurity.
  • /users list cache stores only list-needed fields (lean shape).
  • /users/:id detail cache keeps richer profile/security/avatar data.

Maintenance module

  • Maintenance cache now uses detail read-through (getMaintenanceRequest) and full-list cache hydration on miss.
  • Mutations and attachment changes re-sync list/detail via maintenance cache helpers.
  • List filtering/pagination reads from cache; DB is hit for writes and cache-miss hydration.

Consequences

Positive

  • Lower repeated DB read load.
  • Better list/detail consistency.
  • Predictable extension pattern for new domains.

Negative

  • More domain cache orchestration code.
  • Requires strict discipline to wire all mutation points.

Follow-Up

  • Use this ADR as the baseline for future read-heavy modules (analytics views, audit lists, logs).