Part of #257 — Phase 1 step (5).
RFC: #275.
Goal
Replace RemoteStore with SqliteStore, conforming to the async
Store protocol and using the shared SQLAlchemy Core helpers for
portable queries. SQLite-native concerns (PRAGMAs, single-writer
locking) live inside this class.
Scope
- New
server/backend/src/cq_server/store/_sqlite.py implementing
SqliteStore.
- SQLite PRAGMAs (
foreign_keys=ON, journal_mode=WAL,
synchronous=NORMAL, busy_timeout=5000) wired via SQLAlchemy
engine connect event.
- Async surface; sync work via threadpool shim where pragmatic.
- Replace
RemoteStore references throughout server/backend.
- Delete the old
store.py (move to store/__init__.py re-exporting
Store + SqliteStore).
Out of scope
CQ_DATABASE_URL wiring — handled in the "Wire CQ_DATABASE_URL
and store factory" Phase 1 child.
- Removing
_ensure_* DDL — handled in the "Remove ad-hoc
_ensure_* DDL" Phase 1 child, gated on the baseline-migration
child being deployed.
Acceptance criteria
- All existing server tests pass without modification beyond
import-path updates.
- No behavior change visible to callers.
daily_counts(), tier, review columns all work.
Definition of Done
- TDD: any new internal behavior (PRAGMA wiring, threadpool shim)
lands with a failing test first. Existing behavior coverage is
preserved.
- End-to-end smoke: start the server against a tmp SQLite database
and exercise at least one read + one write through an API endpoint.
- Full test suite green.
- Lint clean.
- No public docs change required at this step (env-var docs in the
CQ_DATABASE_URL child, architecture docs in the Phase 4
documentation child).
Blocked by
- Define async
Store protocol (Phase 1 child).
- Shared SQLAlchemy Core query helpers (Phase 1 child).
Part of #257 — Phase 1 step (5).
RFC: #275.
Goal
Replace
RemoteStorewithSqliteStore, conforming to the asyncStoreprotocol and using the shared SQLAlchemy Core helpers forportable queries. SQLite-native concerns (PRAGMAs, single-writer
locking) live inside this class.
Scope
server/backend/src/cq_server/store/_sqlite.pyimplementingSqliteStore.foreign_keys=ON,journal_mode=WAL,synchronous=NORMAL,busy_timeout=5000) wired via SQLAlchemyengine
connectevent.RemoteStorereferences throughoutserver/backend.store.py(move tostore/__init__.pyre-exportingStore+SqliteStore).Out of scope
CQ_DATABASE_URLwiring — handled in the "WireCQ_DATABASE_URLand store factory" Phase 1 child.
_ensure_*DDL — handled in the "Remove ad-hoc_ensure_*DDL" Phase 1 child, gated on the baseline-migrationchild being deployed.
Acceptance criteria
import-path updates.
daily_counts(),tier, review columns all work.Definition of Done
lands with a failing test first. Existing behavior coverage is
preserved.
and exercise at least one read + one write through an API endpoint.
CQ_DATABASE_URLchild, architecture docs in the Phase 4documentation child).
Blocked by
Storeprotocol (Phase 1 child).