psitta

Documentation index

Persistence repositories

Purpose

Repositories are the application-facing API of the persistence layer. They combine DAO operations and mappers so callers work with domain or application objects rather than normalized SQLite rows.

flowchart LR
    CONTROLLER["Controller"] --> REPOSITORY["Repository"]
    REPOSITORY --> DAO["One or more DAOs"]
    REPOSITORY --> MAPPER["Mapper"]
    DAO --> DB[(SQLite)]

Current repositories

Repository Main responsibility
ExerciseRepository Create, load, select, save, delete, and reset word or sentence exercise aggregates
SessionRepository Store results and resume snapshots, rebuild unfinished sessions, and coordinate answer transactions
ExerciseHistoryRepository Read submitted-answer history with exercise and half-open date filters
ContentRepository Create, load, update, and delete application content and its ordered field values
MediaRepository Resolve media metadata by SHA-256
SentenceGroupRepository Create groups and instances, move instances, and delete sentence structures

Exercise selection and persistence

ExerciseRepository.getDueExercises selects rows whose next_review is not null and is at or before the supplied time. Results are ordered by earliest review and may be filtered by the persisted word or sentence type.

getNewExercises selects exercises with no answer history, ordered by exercise identifier. When loaded normally, history existence determines the initial session status: newExercise or toReview.

Saving an exercise updates its SRS state, sentence states when applicable, and all buffered history entries. resetProgress restores a new SRS state, removes history, and resets per-sentence progress.

Session aggregate

SessionRepository owns the persistence boundary for session lifecycle:

The repository receives an existing ExerciseRepository so answer persistence can reuse saveInTransaction without nesting independent transactions.

Content and sentence structure

ContentRepository maps normalized content, field_value, and field_definition rows into application Content models. Media-valued fields include media metadata; HTML media:// lookup is handled separately through MediaRepository.

SentenceGroupRepository changes sentence-group structure but is not currently constructed by AppDependencies. The current composition root supports reading content during sessions, not an application workflow for creating learning material.

Boundary rules

The controller layer currently depends on concrete repository classes. This is an explicit MVP trade-off, not evidence that repository interfaces already exist.