Problem
The backend uses aiosqlite directly for all persistence. SQLite is great for single-host deploys but caps out for:
- Multi-worker (file-based locking + WAL contention)
- Multi-instance HA
- Operational tooling (backup/restore, replication, observability)
The current code also has direct SQL strings sprinkled throughout backend/securescan/database.py and elsewhere. A Postgres adapter requires rewriting those.
Acceptance criteria
Suggested approach
Use SQLAlchemy 2.0 async (asyncpg driver for postgres, aiosqlite for sqlite). Or: thin adapter that translates a few SQLite-specific SQL idioms to Postgres equivalents (idempotent ALTER TABLE pattern → DO blocks, etc.).
Difficulty
~3 days. Touches every persistence call site; needs careful test coverage.
Problem
The backend uses
aiosqlitedirectly for all persistence. SQLite is great for single-host deploys but caps out for:The current code also has direct SQL strings sprinkled throughout
backend/securescan/database.pyand elsewhere. A Postgres adapter requires rewriting those.Acceptance criteria
SECURESCAN_DATABASE_URLenv var (postgres:// or sqlite://, defaults to sqlite for back-compat).Suggested approach
Use SQLAlchemy 2.0 async (
asyncpgdriver for postgres,aiosqlitefor sqlite). Or: thin adapter that translates a few SQLite-specific SQL idioms to Postgres equivalents (idempotent ALTER TABLE pattern → DO blocks, etc.).Difficulty
~3 days. Touches every persistence call site; needs careful test coverage.