Skip to content

ADR-0017: Infrastructure Migrations — PostgreSQL→D1 and Dexie→SQLite WASM

Status: accepted
Date: 2026-06-27
Supersedes: ADR-0008, ADR-0010, ADR-0001
Deciders: @barateza

Context

The Neemias backend originally ran on a Fastify/Node.js server with PostgreSQL (ADR-0008) and nightly pg_dump backups (ADR-0010). The frontend used Dexie/IndexedDB as the canonical client storage engine (ADR-0001).

Two migrations reshaped the architecture in 2025-2026:

  1. PostgreSQL → Cloudflare D1 (2025 Q3-Q4) — The backend was rewritten as a Cloudflare Worker, and the database was migrated from PostgreSQL to D1 (SQLite at the edge). This eliminated server maintenance, simplified deployments, and aligned with the edge-native architecture.

  2. Dexie/IndexedDB → SQLite WASM (2026 Q2) — The frontend storage was migrated from Dexie/IndexedDB to @sqlite.org/sqlite-wasm with OPFS persistence. This was the Storage Web Migration (SWM), tracked in issues #230-#295. The motivation was schema alignment with D1 (shared SQL DDL from Zod schemas) and eliminating the dual-write pattern (Dexie + D1 sync).

This ADR records both migrations so future architecture reviews have a single source of truth.

Decision

PostgreSQL → D1

  • What changed: workers/ now handles all backend logic. The D1 database (c965d6fc-ee7e-41dd-bc81-65b05652aa17) is the source of truth. Migrations live in migrations/ and are applied via wrangler d1 migrations apply.
  • Why: Edge-native, zero-maintenance database. No more Docker Compose, no more pg_dump. Backups are Cloudflare-managed.
  • Impact: ADR-0008 (PostgreSQL schema) is superseded. ADR-0010 (pg_dump backups) is superseded. The legacy Fastify server is archived at docs/backend/legacy-fastify.md.

Dexie → SQLite WASM

  • What changed: The StorageBackend interface now has a single implementation: SQLiteStore. Data is persisted via OPFS (opfs-sahpool VFS) or MemoryVFS (tests). Dexie, dexie-react-hooks, and the repository pattern (db/repositories/) were removed.
  • Why: Shared schema with D1 — both use SQLite, both generated from the same Zod schemas in @neemias/schemas. The Zod→SQL generator (generateSchemaSQL.ts) produces DDL for both environments. No more dual-write sync complexity.
  • Impact: ADR-0001 (Dexie storage) is superseded. The DexieAdapter was removed in #294. The dexie package was removed in #295.

Consequences

Positive

  • Single SQL dialect across frontend and backend (SQLite)
  • Schema generated from Zod — impossible for frontend and backend to drift
  • No more IndexedDB/Dexie version migration headaches
  • OPFS persistence is more reliable than IndexedDB in Safari

Negative

  • SQLite WASM bundle is larger than Dexie (~500KB gzipped vs ~70KB)
  • OPFS requires a secure context (HTTPS or localhost)
  • Cold start includes WASM instantiation (~50ms on first load)

References

Distributed under MIT License.