You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Local-first SQLite cache for the vocabulary practice loop — serves reads and accepts writes locally, syncs with remote Neon in the background
Full public API: DatabaseCacheService with init(), get_words(), get_word_pairs_with_scores(), record_exercise_result(), refresh(), flush(), get_status()
Stale-while-revalidate refresh policy — fresh data served immediately, background refresh when stale
Transactional outbox pattern — local score writes + event recording in a single SQLite transaction
Idempotent remote replay — event IDs prevent double-application of score deltas on flush
Atomic snapshot rebuild — refresh replaces the full snapshot and reapplies pending events in one transaction
Comprehensive test suite: 44 tests (28 unit, 13 integration, 3 E2E against real Neon)
Auto-Flush
record_exercise_result() now automatically triggers a fire-and-forget background flush via asyncio.create_task
flush() remains available as a public method for explicit use
Background auto-flush uses skip-if-running semantics; explicit flush() waits for completion
Breaking Changes
Removed CachedDatabaseService from database module (legacy, superseded by database_cache)
Bug Fixes
Fixed flush race condition: explicit flush() calls now wait for any running background flush to complete instead of silently skipping. Previously, calling flush() right after record_exercise_result() could return as a no-op if the auto-flush held the lock.
Fixed apply_score_delta to validate delta values (+1/-1) and exercise types (FR32)
Made apply_score_delta atomic (single-transaction check+increment+mark)
Added missing FR21 implementation: get_words() logs warning for untranslated words
Documentation
All module docs synced with implementation — removed phantom Protocol references, fixed architecture diagrams
Shared docs/architecture.md and docs/prd.md updated to reference database_cache and remove CachedDatabaseService
All doc files trimmed to ≤200 lines (repo convention)
PRD FR38-41 updated to document atomic score replay and delta validation
Architecture doc corrected: sampling reads directly from database, not through database_cache
Removed stale database_cached/ directories from prior module rename
Other Changes
Added aiosqlite dependency
Updated vulture_whitelist.py for new public API symbols
Removed obsolete sampling integration tests and latency benchmark test