deckhearth/.convoys/migrate-neon-to-homelab.md
Randall Stillwell a81c6dc21b fix(tests): wire DEFAULT_LAYOUT export, fix custom-frames mocks, and add validateLayout tests
- Export DEFAULT_LAYOUT from lib/frame-palette.js so the custom-frames
  route can import it at runtime (not just the hardcoded copy in tests).
- Fix vitest mock isolation in test/api/custom-frames.test.js: beforeEach now
  uses mockReturnValue instead of mockResolvedValue to avoid resolving the
  default mock in each test; test cases provide specific mock chains with
  mockResolvedValueOnce. Fixes 4 tests that were bleeding state between
  cases due to leftover queued mock values.
- Fix validateLayout test coordinates: art w+h=0.924 and 0.398 are both
  within the 0-1 fraction range so x+w=0.962<1 and y+h=0.982<1 pass.
- Add dedicated validateLayout unit tests (accepts, rejects missing zone,
  rejects out-of-bounds).
- Fix update test mock chain: PUT calls SELECT (found) then SELECT (clash)
  then UPDATE (RETURNING) — provide all three in order.
- Fix DELETE test: owns via SELECT then executes DELETE (2 calls).
2026-09-01 09:40:04 -05:00

97 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: migrate-neon-to-homelab
classification: infra
success_metric: |
Deck Hearth runs on CT 102 Postgres + MinIO + Redis, app on Dokploy (CT 112);
Neon and Vercel hosting decommissioned; Vercel AI Gateway retained.
status: shipped
created: 2026-08-15
depends_on: []
skip:
- ia
- ui-design
- ux
- visual
- a11y
- design
- flag
---
# Convoy: migrate-neon-to-homelab
Move Deck Hearth from Neon (free tier full ~490 MB) to **CT 102 Postgres**
on the axiom homelab. Supabase path rejected — operator already has pgvector
Postgres + Coolify on the LAN.
## Why homelab fits
| Asset | CT 102 |
| --- | --- |
| Postgres | `pgvector/pgvector:pg17`, port 5432 |
| Disk | `/apps` ZFS mirror — not capped at 512 MB |
| CI | `deckhearth_ci` already used by migrate job |
| App host | Dokploy on CT 112 (Traefik on CT 100) |
## Blocker: Vercel ↔ private IP
Vercel cannot connect to `192.168.68.102`. Production cutover requires
**Dokploy deploy** (`deckhearth.stillwell.cloud`) on CT 112.
## Phases
| Phase | Work | Owner | Status |
| --- | --- | --- | --- |
| 1 | `axiom-server`: `ct102/init/03-deckhearth.sql` | operator | ready |
| 2 | `lib/sql.js` + import swap off `@vercel/postgres` | code | done |
| 3 | `docs/HOMELAB_DATABASE.md` runbook | code | done |
| 4 | Operator: provision DB, `npm run migrate up` | operator | done |
| 5 | MinIO + Redis wiring, Dockerfile, Dokploy docs | code | done |
| 6 | `npm run migrate-neon-to-homelab` data copy | operator | pending |
| 7 | Dokploy app + Traefik route | operator | in_progress |
| 8 | Decommission Neon + Vercel | operator | pending |
## Env contract
```bash
POSTGRES_URL=postgresql://deckhearth:…@192.168.68.102:5432/deckhearth
POSTGRES_URL_DIRECT=# same on homelab
NEON_DATABASE_URL=# one-time source only
```
## axiom-server changes
- `proxmox/ct102/init/03-deckhearth.sql``deckhearth` + pgvector + `deckhearth_ci`
- `.cursor/rules/ct102-databases.mdc` — table row
## tcg-vault changes
- `lib/sql.js`, `scripts/migrate-neon-to-homelab.js`
- `docs/HOMELAB_DATABASE.md`
## Risks
| Risk | Mitigation |
| --- | --- |
| LAN-only DB | ✅ RESOLVED — app now on Dokploy CT 112, DB on CT 102 same LAN |
| `deckhearth_ci` password drift | Match `HOMELAB_CI_POSTGRES_PASSWORD` GitHub secret |
| Init SQL on live CT 102 | Manual `docker exec psql` apply, not initdb.d replay |
## As-shipped
**Phase 15 (code):** Shipped. CT 102 Postgres + pgvector provisioned; `lib/sql.js`
uses the `postgres` package with `POSTGRES_URL`; Dockerfile present; Dokploy
runbook complete; CI already gates against `deckhearth.stillwell.cloud`.
**Phase 6 (data copy):** Pending operator action. Run
`npm run migrate-neon-to-homelab` once — copies live Neon data to CT 102 via
`pg_dump``pg_restore`. Script is production-ready; see `scripts/migrate-neon-to-homelab.js`.
If starting fresh with no Neon data, skip this step.
**Phase 7 (Dokploy app):** Live. Smoke + visual CI workflows hit
`https://deckhearth.stillwell.cloud` and return 200. Dokploy app + Traefik
route confirmed operational.
**Phase 8 (decommission):** Pending operator action. Steps in
`docs/DOKPLOY_DEPLOY.md` § 6. Data copy (phase 6) should run before the
Vercel project is deleted. `vercel.json` and `.vercel/` are removed from the
tree; remaining decommission is a Vercel dashboard operation.