psitta

Documentation Index

docs/architecture/persistence.md

Purpose

Describe the Persistence layer, responsible for storing and retrieving application data.

This layer:

No business logic should reside here.

⚠️ Persistence only records states computed by the Domain.


Diagram

%%{init: {"class": {"hideEmptyMembersBox": true}} }%%
classDiagram

namespace Persistence {
  class WordRepository
  class SentenceRepository
  class ExerciseRepository
  class ChapterRepository
  class SrsRepository
  class SettingsRepository
}

class SQLiteDatabase

WordRepository --> SQLiteDatabase
SentenceRepository --> SQLiteDatabase
ExerciseRepository --> SQLiteDatabase
ChapterRepository --> SQLiteDatabase
SrsRepository --> SQLiteDatabase
SettingsRepository --> SQLiteDatabase

Repository Responsibilities

General Principle

A repository represents a business concept used by the application, not necessarily a single SQL table.

Each repository:


Main Repositories

WordRepository

SentenceRepository

ExerciseRepository

ChapterRepository

SrsRepository

👉 For the MVP, SRSState, SRSConfig, and SentenceState are intentionally grouped here (may be split later).

SettingsRepository


DB ↔ Domain Mapping

Mapping between SQLite and the Domain is confined to Persistence.

Two possible implementations:

In all cases:


Optimisations and Performance

All technical optimisations are exclusively managed within this layer, including:

These optimisations can evolve without impacting:


Key Implementation Boundaries ⚠️

1. Boundaries never to cross


2. Repository methods

Methods must be:

getAllWordsFromTable()

getDueWords(chapterId)


3. Future evolution


Golden Rule

Everything related to “how it is stored” or “how it is fast” belongs to Persistence, and to Persistence alone.