An easy-to-host PDS on the ATProtocol, MacOS. Grandma-approved.

docs: update project context for MM-72 SQLite migration infrastructure

- Root CLAUDE.md: add SQLite/sqlx to tech stack, correct rusqlite
references to sqlx's libsqlite3-sys, update freshness date
- New crates/relay/src/db/CLAUDE.md: document db module contracts,
invariants, key decisions (custom migration runner, single-connection
pool, decoupled open_pool signature)

authored by malpercio.dev and committed by

Tangled b08aa97e 1c4c52ef

+36 -3
+4 -3
CLAUDE.md
··· 1 1 # ezpds 2 2 3 - Last verified: 2026-03-09 3 + Last verified: 2026-03-11 4 4 5 5 ## Tech Stack 6 6 - Language: Rust (stable channel via rust-toolchain.toml) 7 7 - Build: Cargo workspace (resolver v2) 8 + - Database: SQLite via sqlx 0.8 (runtime-tokio + sqlite features) 8 9 - Dev Environment: Nix flake + devenv (direnv integration via .envrc) 9 10 - Task Runner: just 10 11 ··· 22 23 - Managed entirely by Nix flake + devenv; do not install tools globally 23 24 - direnv auto-activates via `.envrc` (`use flake . --impure --accept-flake-config`) 24 25 - Rust toolchain pinned in `rust-toolchain.toml` (stable, with rustfmt + clippy + rust-analyzer) 25 - - Shell provides: just, cargo-audit, sqlite (runtime binary + dev headers/library for rusqlite), pkg-config 26 - - `LIBSQLITE3_SYS_USE_PKG_CONFIG=1` is set automatically by devenv 26 + - Shell provides: just, cargo-audit, sqlite (runtime binary + dev headers/library for sqlx's libsqlite3-sys), pkg-config 27 + - `LIBSQLITE3_SYS_USE_PKG_CONFIG=1` is set automatically by devenv (links sqlx against Nix-provided SQLite instead of bundled) 27 28 - Binary cache: devenv.cachix.org (activated by `--accept-flake-config`); speeds up cold shell builds significantly 28 29 - nixpkgs pin: `cachix/devenv-nixpkgs/rolling` (devenv's own nixpkgs fork — package versions may differ from upstream nixpkgs.search.dev) 29 30
+32
crates/relay/src/db/CLAUDE.md
··· 1 + # Database Module 2 + 3 + Last verified: 2026-03-11 4 + 5 + ## Purpose 6 + Owns SQLite connection lifecycle and schema migration for the relay's server-level database. 7 + Keeps database concerns out of handler code and provides a reusable pool+migration API 8 + that can later serve per-user SQLite databases (Wave 3/4). 9 + 10 + ## Contracts 11 + - **Exposes**: `open_pool(url: &str) -> Result<SqlitePool, DbError>`, `run_migrations(pool: &SqlitePool) -> Result<(), DbError>`, `DbError` 12 + - **Guarantees**: Pool uses WAL journal mode and max 1 connection. Migrations are forward-only, idempotent, and applied in a single transaction. `schema_migrations` table tracks applied versions. 13 + - **Expects**: Valid sqlx SQLite URL (e.g. `"sqlite::memory:"`, `"sqlite:path.db"`). Pool must be open before calling `run_migrations`. 14 + 15 + ## Dependencies 16 + - **Uses**: sqlx (SqlitePool, SqliteConnectOptions), thiserror 17 + - **Used by**: `main.rs` (startup sequence), `app::AppState` (holds the pool), test helpers 18 + - **Boundary**: Handlers never call `open_pool`/`run_migrations` directly; they receive the pool via `AppState.db` 19 + 20 + ## Key Decisions 21 + - Custom migration runner over sqlx's built-in `migrate!()`: gives control over transaction boundaries and avoids sqlx's `_sqlx_migrations` table 22 + - Single connection pool (`max_connections(1)`): avoids SQLite write contention, sufficient for v0.1 23 + - `open_pool` accepts `&str` (not Config/AppState): keeps the function reusable for future per-user DBs 24 + 25 + ## Invariants 26 + - Migration SQL files are append-only; never modify an applied migration 27 + - Migration versions are sequential positive integers starting at 1 28 + - WAL mode is always enabled (set via SqliteConnectOptions, not raw PRAGMA) 29 + 30 + ## Key Files 31 + - `mod.rs` - Pool creation, migration runner, DbError, tests 32 + - `migrations/V001__init.sql` - server_metadata table (WITHOUT ROWID)