Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Generics, Builders, and Storage Boundaries

Client history uses a Database trait object because callers can swap or wrap local implementations at runtime. Server handlers instead use AppState<DB> with DB: atuin_server_database::Database, monomorphizing one chosen Postgres or SQLite backend through Axum state.

The V2 record model is generic over payload state: Record<DecryptedData> can be transformed into Record<EncryptedData>. The type prevents upload code from accidentally accepting plaintext and makes the cryptographic boundary visible without a runtime flag.

Builders for Record and history capture encode required fields in construction APIs. Newtypes keep host, record, session, and history IDs distinct. RecordTag is an extensible product discriminator that lets one sync engine carry several domain projections.

Atuin uses trait objects where local runtime substitution matters, generics where one server backend should remain statically checked, and payload-state types where an invalid security transition must be hard to express.