What this domain owns
The learner snapshot and the rules that turn activity into progress. It does not decide lesson visual layout.
Feature flow diagram
Learner action
│
v
recordAttempt / markActivity / updateState
│
v
Browser snapshot ──save──> local browser storage
│
├──> review + streak + mission rules
└──> authenticated cloud sync ──> /api/progress ──> PostgreSQLThis diagram shows the normal direction of control and data. Follow it before changing a boundary or adding a dependency.
Class and relationship diagram
┌──────────────────┐ updates ┌────────────────────┐ syncs ┌───────────────┐
│ Activity action │────────▶│ LearnerState │──────▶│ /api/progress │
└──────────────────┘ ├────────────────────┤ └───────┬───────┘
│ + attempts │ ▼
│ + reviews │ ┌───────────────┐
│ + streak │ │ PostgreSQL │
└───┬────────────┬─────┘ └───────────────┘
▼ ▼
┌────────────┐ ┌──────────────┐
│ Browser │ │ ReviewSchedule│
│ storage │ │ + schedule() │
└────────────┘ └──────────────┘Boxes show the important data types or services. Their fields and main methods are listed inside; arrows show the primary dependency or data relationship.
Sequence diagram
Read this from top to bottom: each arrow is the next interaction in the normal successful path.
Start here in the code
Choose any filename to open it directly in VS Code.
How it works
- An activity calls a progress action.
- The browser snapshot validates and saves locally.
- Review/streak/mission rules derive the next state.
- Authenticated sync writes to the server and reconciles conflicts.
Read this code
lib/store.tsOpen in VS Code — Update local learner state safely
export function updateState(fn: (s: State) => State) {
const next = fn(getState());
writeBrowserStorage(KEY, JSON.stringify(next));
current = next;
emit();
}
export function markActivity(id: string) {
updateState((state) => markStudyActivity(state, id));
}What each part is doing
- Callers provide a pure state transformation instead of mutating the current snapshot.
- The new snapshot is persisted before subscribers re-render.
- markActivity delegates actual completion rules to the domain function.
This is a deliberately short excerpt of the real pattern, with unrelated details omitted. Read the named file for the complete implementation.
Related API and server boundaries
- GET /api/progress loads the signed-in snapshot.
- PUT /api/progress validates and saves a snapshot; 409 means conflict.
Tests to read and run
Implementation notes
This is the home for detailed explanations, decision records, request examples, and diagrams for this feature. Add new feature-specific documentation here instead of expanding the platform overview.