Domain Service Boundaries
Barbelic app code should depend on domain APIs instead of knowing Supabase table details directly.
App-Facing Facade
src/react/services/barbelicApi.ts is the typed facade consumed by React controllers and app shells.
It delegates to:
domains/authProfileDomain.ts: auth state, current profile, onboarding profile data.domains/workoutDomain.ts: workout/session/plan/daily condition mutations.domains/catalogDomain.ts: exercise catalog, archetypes, aliases, details, Wodup mappings.domains/importDomain.ts: Wodup JSONL upload, import start, import polling.domains/statsDomain.ts: screen RPC packages and materialized stats read models.domains/adminDomain.ts: admin/debug/export operations.
Repository Boundary
barbelicRepository.ts is the strict adapter for the current Supabase contract. It must not accept retired request shapes, silently skip missing RPCs, or synthesize successful writes.
General app screens must not call it directly. They go through barbelicApi.ts, whose exports are typed aliases to domain APIs rather than runtime capability checks or compatibility wrappers.
Raw table access remains allowed only inside repository/debug/admin paths, not inside ordinary screen controllers.
Current-Contract Rule
The application supports one deployed request shape per operation. A contract change is a coordinated database migration plus frontend release, not a new fallback branch.
- Controllers and domains pass explicit camelCase DTOs.
- Repository adapters reject unknown or retired input fields before issuing an RPC.
- Repository adapters translate the accepted DTO to the database's snake_case wire shape once.
- Database row/RPC response adapters translate snake_case output to view models once.
- External-provider normalization is confined to the import boundary and never becomes an app ID alias.
Server receipt idempotency, revision checks, owner-scoped draft caching, and explicit retry are the current reliability mechanisms. They must not be used to reinterpret an old schema or turn a missing RPC into a synthetic success.
Enforced Import Rules
tests/react/frontendImportBoundaries.test.mjs scans src/react and fails when these rules regress:
- UI screens and controllers must not import
services/barbelicRepository.tsdirectly. - UI files under
src/react/uimust stay presentational: noservices/*,controllers/*,app.tsx, orappController.tsximports. - Normal app-facing paths must not reference raw loader names such as
loadDebugSnapshotRows,loadAdminCatalogRows,loadCalendarRows, orloadSessionDetailRows. - Mobile and desktop UI are separate platforms.
ui/mobile,mobileApp.tsx, andmobileRoot.tsxmust not import desktop code;ui/desktop,desktopApp.tsx, anddesktopRoot.tsxmust not import mobile code. - Shared UI under
ui/sharedmust not import either platform-specific UI tree.
Allowed flow:
UI/screen props -> app controllers -> barbelicApi.ts -> domain services -> barbelicRepository.ts/RPC adapters.
Admin, debug, export, and import internals may still use raw loaders through their domain service modules, but ordinary app screens must stay behind domain APIs.
Next Extraction Steps
The domain module boundary is stable. Future extraction may move implementation from barbelicRepository.ts into lower-level domain repositories without changing React screens:
Move catalog table reads/writes intoDone (v0.18.0 A03, #1330): catalog reads/writes live indomains/catalogRepository.ts.domains/repositories/catalogRepository.tswith pure validation/mapping indomains/catalogCodec.ts; profile/onboarding reads/writes live indomains/repositories/profileRepository.tswithdomains/profileCodec.ts, the narrow avatar-signing helperdomains/profileAvatarSigning.ts, and the shared input-contract checksservices/currentInputContract.ts.- Move Wodup import batch reads/writes into
domains/importRepository.ts. - Move workout save/delete RPC wrappers into
domains/workoutRepository.ts. - Keep screen data behind RPC functions in
domains/statsDomain.ts.
A01 extraction boundary (v0.18.0)
The A01 production wiring now uses G03 feature ports, bounded legacy repository ports and nine real domain repository destinations. See RPC transport and domain extraction for the exact moved functions, retry responsibilities, temporary adapters and A02–A06 handoff.