87 lines
3.2 KiB
Markdown
87 lines
3.2 KiB
Markdown
# AdventureOS Architecture
|
|
|
|
This document describes the system architecture and behavioural invariants that must be preserved during refactoring.
|
|
|
|
## Package Structure
|
|
|
|
```
|
|
packages/
|
|
domain/ Pure domain rules, entities, value objects — no external deps
|
|
application/ Use cases and port interfaces — depends on domain only
|
|
shared/ Deprecated re-export shim → @adventureos/domain
|
|
db/ Drizzle schema, migrations, connection
|
|
|
|
apps/web/
|
|
src/
|
|
adapters/ Persistence, AI, Calibre implementations of ports
|
|
infrastructure/ Composition root, env wiring
|
|
app/api/ HTTP adapters (Next.js route handlers)
|
|
components/ UI adapters
|
|
lib/services/ Legacy service layer (migrating to application use cases)
|
|
```
|
|
|
|
### Dependency Rule
|
|
|
|
- `domain` → nothing external
|
|
- `application` → `domain`
|
|
- `adapters` / `infrastructure` / `app/api` → `application`, `domain`, `db`
|
|
- Domain must not import controllers, ORM, HTTP, or config
|
|
|
|
## Behavioural Invariants
|
|
|
|
Derived from [PRODUCT.md](./PRODUCT.md). These must not change without explicit approval.
|
|
|
|
### XP and Progression
|
|
|
|
- **No XP loss** under normal operation. Undo revokes XP via compensating negative events, not deletion.
|
|
- **Soft caps** apply diminishing returns per source (`adventure_item`, `spiritual`, `reading`) — see `DAILY_SOFT_CAPS` in domain.
|
|
- **Level curve** is defined by `levelFromXp` / `xpForLevel` — cap at level 150.
|
|
- **Rest days** award `XP_AWARDS.rest_day` without requiring item completion.
|
|
- **Daily visit** XP is awarded once per logical day.
|
|
|
|
### Adventure Items
|
|
|
|
- Item states: `blank` → `started` → `partial` → `done` (derived by type-specific rules).
|
|
- Partial credit is always awarded for non-blank state transitions.
|
|
- **Semantic keys** (`exercise`, `prayer`, `litanies`, etc.) identify items for scoring/XP. Label-string fallback remains for backward compatibility until all templates use `config.semanticKey`.
|
|
|
|
### Day Boundary
|
|
|
|
- Logical "today" respects configurable day-boundary hour and grace window (`getLogicalToday`, `isWithinGraceWindow`).
|
|
- Week starts on Monday (`startOfWeek` with `weekStartsOn: 1`).
|
|
|
|
### Undo
|
|
|
|
- Actions recorded via `recordAction` with `beforeState` / `afterState`.
|
|
- Undo creates compensating XP events and marks originals as revoked.
|
|
- Each `actionType` has a dedicated undo handler — handlers must stay synchronized with record sites.
|
|
|
|
### Anti-Burnout
|
|
|
|
- No streak destruction, no failure screens.
|
|
- Grace days and welcome-back flows preserve progress.
|
|
- Forgiving day modes do not penalize the user.
|
|
|
|
### Auth
|
|
|
|
- Single-tenant: one user per installation (`requireUser` uses `limit(1)`).
|
|
- Use cases receive explicit `userId` — auth resolution happens in HTTP/cron adapters only.
|
|
|
|
## Migration Status
|
|
|
|
| Slice | Status |
|
|
|-------|--------|
|
|
| UpdateAdventureItem use case | Migrated via composition root |
|
|
| Remaining adventure operations | Legacy services |
|
|
| Reading, dashboard, AI | Legacy services |
|
|
| Admin CMS (Drizzle schema) | Persistence adapter |
|
|
|
|
## Running Checks
|
|
|
|
```bash
|
|
npm run test # domain + application + web + shared
|
|
npm run lint # ESLint (web)
|
|
npm run typecheck # tsc --noEmit
|
|
npm run build # Next.js production build
|
|
```
|