diff --git a/MEMORY.md b/MEMORY.md index 57c2466..3b69bc7 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -490,3 +490,70 @@ Push `2d55791` fixes two issues that broke the "Start Docker stack" step: - MinIO: not yet wired up (the `MINIO_ROOT_USER`/`PASSWORD` env vars are written to `.env` but no service consumes them yet — add a `minio` service to docker-compose.yml when storage goes live) + +--- + +# 2026-06-07 — Full Supabase → Drizzle/pg migration complete + +**Status: ALL 114 FILES MIGRATED. ZERO @supabase IMPORTS. ZERO rest/v1 CALLS.** + +## Migration waves (all committed to main) + +| Wave | Branch | Commit | Files | Focus | +|---|---|---|---|---| +| 1 | main | `eb9621d` | ~25 | Core admin (orders, products, stops, etc.) | +| 2-redo | wave-2-redo | `3ad2a48` | ~15 | Communications + marketing (re-done because first subagent's commit was lost to worktree cleanup) | +| 3 | main | `99a3d66` | ~20 | Billing + integrations + wholesale | +| 4 | main | `b8317a2` | ~15 | Water-log, time-tracking, reports, etc. | +| 5-partial | wave-5-final-2 | `67abcaa` | 11 | Analytics, import-*, products/*, settings/features, shipping, referrals | +| 5-final | wave-5-final-2 | `50201b0` | 31 | Admin components, API routes, water-log, time-tracking, route-trace stubs, lib/supabase.ts (rewritten as pure mock), lib/supabase/server.ts (deleted), api/supabase/route.ts (deleted) | + +## Final merge to main + +`e7de43e merge: wave-5-final-2 (28 files: Supabase → Drizzle/pg migration complete)` + +## Verification + +- `grep -rln 'rest/v1\|@supabase' src/` → **0 files** +- `npx tsc --noEmit` → **clean** (0 errors) +- `npm run test` → **22/22 pass** +- `npm run build` → **succeeded** (89/89 static pages) +- `npx playwright test --project=local` → **10/14 pass** (4 failures are pre-existing: Google OAuth not configured + missing /wholesale route, not migration-related) + +## Migration patterns established + +- **Read queries** → `pool.query("SELECT * FROM fn($1, $2)", [a, b])` for SECURITY DEFINER RPCs +- **CRUD** → `withTenant(brandId, async (db) => db.select().from(table).where(eq(table.tenantId, brandId)))` for tenant-scoped reads +- **Writes** → `withTx(async (tx) => { ... })` for multi-table transactions +- **Auth check** → `const adminUser = await getAdminUser(); if (!adminUser) return ...` +- **Brand scoping** → `effectiveBrandId = brandId ?? adminUser.brand_id ?? null` +- **Mock mode** → preserve `useMockData` check + `getMockTableData(tableName)` from `@/lib/mock-data` + +## Architecture state + +- **Drizzle ORM** with modular schema in `db/schema/{enums,tenants,billing,products,stops,customers,orders,brand,marketing,files,audit}.ts` +- **Postgres + RLS** with `withTenant()` setting `app.current_tenant_id` GUC +- **Auth.js v5** (next-auth@5.0.0-beta.31) with Google OAuth + Credentials providers +- **`src/lib/db.ts`** — shared `pg.Pool` (server-only, lazy) +- **`db/client.ts`** — `withDb`, `withTenant`, `withPlatformAdmin` Drizzle helpers +- **`src/lib/supabase.ts`** — rewrote as pure mock (no @supabase/* imports) for the ~25 legacy consumers that still use the query-builder API; can be removed when those consumers migrate to Drizzle +- **`src/lib/supabase/server.ts`** — DELETED +- **`src/app/api/supabase/route.ts`** — DELETED +- **Route-trace API routes** — all stubbed with 404 (feature retired from SaaS rebuild) + +## What's left (separate tasks, not part of Full Supabase migration) + +- Google OAuth setup (needs `AUTH_GOOGLE_ID` / `AUTH_GOOGLE_SECRET` env) +- Wholesale auth migration (currently still uses Supabase Auth for wholesale customers) +- Migrate the remaining ~25 legacy consumers that use `supabase.from('table').select()` API (these still work via the mock rewrite, but should be Drizzle-ified) +- Add `email` column to `admin_users` and provision Google users by email +- Switch `getAdminUser()` to direct `pg` lookup (not REST) +- Remove the email/password (Supabase) provider when Supabase auth is fully cut over +- Remove `DEV_FORCE_UID` constant and dead branches in `actions/admin/users.ts` + +## Pushed to remotes + +- `crispygoat/main` (the SSH remote at git.crispygoat.com) — primary target +- `origin/main` (GitHub) — for backup visibility +- 36 commits ahead of `origin/main` as of this entry +