Migrate dashboard runtime from Supabase to SQLite#23
Conversation
Q00
left a comment
There was a problem hiding this comment.
Thanks for the SQLite migration work. I found a few merge blockers before this is safe to land.
-
High: the new single-host install path builds the wrong image.
scripts/install-server.shand the generated systemd unit both startdashboard/docker-compose.yaml, which buildsdashboard/Dockerfile. That image never copiespublic/releases; only the rootDockerfiledoes. The PR description says the dashboard should continue serving both client install assets and server install assets, but a fresh single-host install will ship an image without/releases/*. -
High: the SQLite bind mount is likely unwritable on a fresh install.
The container runs asnextjs(uid 1001), while docker-compose bind-mounts${ZEUDE_DATA_DIR}onto/var/lib/zeude. The installer creates the host data directory, but it neverchowns that host path to uid 1001. On first boot, SQLite can fail withpermission deniedwhen it tries to createzeude.db. -
High: the documented fresh-host install command fails for non-root users before Docker starts.
The README tells users to runbash scripts/install-server.sh, but the script defaults to/opt/zeudeand/var/lib/zeudeand creates those paths with plainmkdir -pbefore any sudo path is used. On a normal Linux host, that exits with permission errors before the stack ever comes up. -
Medium:
DATABASE_PROVIDERis still exposed, but runtime selection ignores it.
The env schema still acceptsDATABASE_PROVIDER, butgetOperationalDb()only switches onNODE_ENV === 'test'. If the rollout assumes any staged fallback or compatibility path through Supabase, the app will silently boot against a fresh SQLite file instead of either honoring the setting or failing fast.
Validation from my side:
npm testpassednpx tsc --noEmitpassedCLICKHOUSE_PASSWORD=dev next buildpassednpm run lintstill fails, including newly touched files such asscripts/migrate-from-supabase.cjs,scripts/migrate-sqlite.cjs,src/lib/db/supabase-adapter.ts, andsrc/app/api/config/[agentKey]/route.ts
Requesting changes.
|
Follow-up review after the latest update: the install-path issues look addressed, but I still see two merge blockers.
Re-check from my side:
|
The Supabase operational adapter is incomplete and breaks auth, session, and config flows if DATABASE_PROVIDER=supabase is selected at runtime. Treat Supabase as migration-only, fail fast instead of booting into a broken provider path, and include the lint/test cleanup needed to keep the branch green.
Remove the unused Supabase runtime adapter and the remaining DATABASE_PROVIDER runtime wiring so operational state runs on SQLite only. Document that existing Supabase-backed deployments must migrate to SQLite before upgrading, while keeping Supabase only as the source for migrate:supabase-to-sqlite.
PR Review: Supabase → SQLite Migration63 files, +3264/-1375 — Large migration with clear direction and solid implementation overall. The repository layer abstraction is clean and the migration tooling is well thought out. Posting review based on the self-hosted, single-host threat model (operator = admin, small data scale, no external attacker surface for operational DB). Verdict: Ready to merge with follow-ups noted below.HIGH — Address in next PR1. Duplicated schema DDL across 3 files
Suggestion: extract DDL into a single shared source (e.g. a 2. Missing indexes on FK columns used in WHERE/JOIN These columns are queried on every request but lack indexes:
Session validation (every authenticated request) and install-status upserts (every client sync) will degrade noticeably once user count exceeds ~1000. MEDIUM — Address in subsequent PR3. No cleanup for expired sessions/tokens
4. N+1 query regression in The old Supabase code used Suggestion: add a 5. No runtime validation for
LOW / INFO
Summary
Ship it. I'd prioritize the two HIGH items as a follow-up PR before the next schema change lands. |
Summary
This PR moves Zeude dashboard runtime operational storage from Supabase to SQLite while keeping ClickHouse for analytics.
It also adds:
Supabase -> SQLitemigration pathinstall-server.shWhat Changed
dashboard/src/lib/db/*better-sqlite3npm run migrate:supabase-to-sqlitescripts/install-server.shreleases/install.shflow intact and fixed dashboard URL summary output in install logsArchitecture
flowchart LR subgraph ClientMachine[Developer Machine] CLI[claude / codex shim] LocalCfg[~/.zeude + local CLI config] RealCLI[real claude / codex binary] CLI -->|sync on startup| Dashboard CLI --> RealCLI CLI --> LocalCfg end subgraph ServerHost[Single Host Deployment] Dashboard[Next.js Dashboard] SQLite[(SQLite\noperational state)] CH[(ClickHouse\nanalytics)] Releases[/releases/* assets/] Dashboard <-->|operational reads/writes| SQLite Dashboard <-->|analytics queries + writes| CH Dashboard --> Releases end Supabase[(Legacy Supabase)] -->|one-time migration| SQLiteRuntime Model After This PR
Validation
Completed locally:
cd zeude/dashboard && npm testcd zeude/dashboard && npx tsc --noEmitcd zeude/dashboard && npm run migrate:sqlitecd zeude/dashboard && npm run devcurl -s http://127.0.0.1:3000/api/healthbash zeude/scripts/build-release.shbash -n zeude/scripts/install.shbash -n zeude/scripts/install-server.shDRY_RUN=1 bash zeude/scripts/install-server.shreleases/install.shObserved limitation in this environment:
install-server.shcould not complete here because the Docker daemon socket was unavailable to the sessionFollow-up Manual Checks
Recommended before merge:
install-server.shend-to-end on a host with Docker daemon accessnpm run migrate:supabase-to-sqlite -- --dry-runagainst a real Supabase datasetCommits
368f4f9Migrate dashboard runtime from Supabase to SQLite6e1844fAdd single-host server installer52e22f4Fix install script dashboard summary output