Domain Architecture (Monorepo)
Goals
- Keep domain logic in packages
- Keep storage primitives generic (no implicit behaviors)
- Provide small, reusable domain helpers (indexes, sorting)
- Apps wire domains via env getters and runtime DI only
Layers
- Base primitives:
@repo/storage(drivers, BaseStorage) - Domain packages:
@repo/app-video-flow(server db, types, helpers), others similar - Apps:
apps/library,apps/branded-video-flow, etc. (no domain logic)
Patterns
- Repositories per domain extend
BaseStorage - Index helpers per domain (e.g.,
clientsindex timestamps) - Optional Redis ZSETs for recency
- No
process.envin packages; apps inject env via getters
Video Flow Domain (example)
- Repo:
packages/app-video-flow/src/server/db/storage.ts - Index helper:
client-index.ts(proposed) withupsertClientIndex - Apps consume via
getClients().videoFlow.getStorageClient()
Consistency Checklist
- Types live in packages
- Save operations update domain indexes
- Read operations enrich entities from indexes
- Avoid app-local domain services (migrate into packages)
Migration Notes
- Introduce helpers as opt-in utilities
- Keep BaseStorage generic
- Incrementally adopt across save paths
TODOs (Kanbn Traceability)
- Task:
.kanbn/tasks/domain-refactor-video-flow.md - PRD:
prds/domain-refactor-video-flow-prd.md