Move user-owned derived state and enrichment caches from synchronous SQLite calls to PostgreSQL while preserving their API contracts and transaction behavior.
Depends on #150
Scope:
- Migrate favorites/tags, local overrides, blobs/media metadata, geocode cache, AI discovery/dismissals, augmentation state, deaths metadata, and refresh/linking writes.
- Convert JSON-encoded columns to jsonb where appropriate while keeping wire response shapes stable.
- Preserve uniqueness/upsert rules, cache invalidation, cascading deletes, content-addressed blob semantics, and local-override durability.
- Propagate async behavior through service/route callers and add parity tests for CRUD, conflicts, and rollback.
Acceptance criteria:
- No migrated service imports sqlite.service or sqlite-writer.
- CRUD behavior and response payloads match existing fixtures, including empty/null values and boolean fields.
- Concurrent upserts do not create duplicate favorites, dismissals, provider links, media, or geocode entries.
- Local overrides survive a PostgreSQL rebuild from JSON and still win over provider data.
Files/areas: server/src/services/{favorites,local-override,blob,geocode,ai-discovery,augmentation,deaths,familysearch-refresh}.service.ts, related routes, writer hooks, tests.
Part of #120
After this issue ships, check its box in #120. If it was the last open child, comment on #120 with a summary of the delivered children and close #120 as completed.
Move user-owned derived state and enrichment caches from synchronous SQLite calls to PostgreSQL while preserving their API contracts and transaction behavior.
Depends on #150
Scope:
Acceptance criteria:
Files/areas: server/src/services/{favorites,local-override,blob,geocode,ai-discovery,augmentation,deaths,familysearch-refresh}.service.ts, related routes, writer hooks, tests.
Part of #120
After this issue ships, check its box in #120. If it was the last open child, comment on #120 with a summary of the delivered children and close #120 as completed.