Architecture Decisions
Record major decisions here. Keep entries short and update them when the decision changes.
ADR-001: Contract-First Development
- Status: accepted
- Decision:
packages/contracts/openapi.yamlis the API source of truth. - Why: backend, web, and mobile must stay synchronized.
- Consequence: generated clients are required; handwritten duplicate API types are forbidden.
ADR-002: Modular Monorepo
- Status: accepted
- Decision: keep backend, web, mobile, contracts, infra, and docs in one repository.
- Why: vertical slices often span all platforms.
- Consequence: ownership boundaries must be directory-based and enforced in review.
ADR-003: Append-Only Asset Events
- Status: accepted
- Decision: asset history is stored as immutable events.
- Why: receiving, correction, handoff, and audit flows need traceability.
- Consequence: current state is derived; corrections are new events.
ADR-004: Idempotent Event Sync
- Status: accepted
- Decision: event ingest deduplicates by client-minted
event_id. - Why: mobile writes must tolerate offline retry and network timeouts.
- Consequence: backend insert uses conflict-safe behavior.
ADR-005: Backend Enforces Authorization
- Status: accepted
- Decision: backend is the final authorization boundary.
- Why: web and mobile controls can be bypassed.
- Consequence: every protected endpoint needs authorization tests.
ADR-006: Generated API Clients
- Status: accepted
- Decision: generate TypeScript and Dart clients from OpenAPI.
- Why: shared API types must not drift.
- Consequence: generated output is checked in or generated consistently by CI, but never hand-edited.
ADR-007: POC Is Reference, Not Product Architecture
- Status: accepted
- Decision:
reference/mobile_app_demodocuments proven workflow behavior, not final module structure. - Why: the POC has useful domain learning but lacks production architecture.
- Consequence: port behavior intentionally into
apps/mobileinstead of copying limitations.