Full Prisma migration: Supabase SDK data access removed from 13 files

Dshamir replaces every `supabase.from()` call in the backend with Prisma client queries against Postgres, decoupling persistence from the Supabase SDK. This is the fork's largest single change - 13 files rewritten, roughly 2100 lines net removed.

infrastructuresecurity

The thread runs across six commits. Prisma is initialized, a 408-line schema is added with 17 models, 7 enums, a deletedAt soft-delete column on six tables, and an AuditLog model. A custom Prisma client wraps the base client with a $extends hook: for findMany, findFirst, and count on soft-delete models it injects where: { ...args.where, deletedAt: null } automatically; for delete and deleteMany it converts the call to an updateMany that sets deletedAt: new Date(). This means callers write ordinary Prisma queries and get soft-delete behavior for free.

The capstone commit touches 8 routes (chat, projectChat, projects, documents, tabular, workflows, user, downloads) and 5 libraries (access, chatTools, documentVersions, userApiKeys, userSettings). The mechanical change is replacing supabase.from("table").select(...).eq(...).single() patterns with prisma.model.findUnique(...) equivalents. The schema uses camelCase field names (userId, sharedWith, deletedAt) so all the access checks that previously used snake_case fields required corresponding updates.

One nuance: the self-hosted stack still runs gotrue and postgrest containers. This migration is specifically about DB access - Prisma holds the service-role Postgres connection and bypasses RLS, while the PostgREST anon role remains in place for whatever it was doing. That separation becomes load-bearing in the later RLS hardening work, where a deny-all policy is applied specifically to block the PostgREST anon role while leaving Prisma's service-role unaffected.

The soft-delete extension has a type cast: (basePrisma as any)[model[0].toLowerCase() + model.slice(1)].update(...). It works, but the as any indicates Prisma's type system doesn't know about the custom behavior at compile time. The schema also has several as any casts on JSON fields - acknowledged in the fork's own roadmap as technical debt.

So what Importing this wholesale is a significant commitment - it rewrites the entire route and data-access layer and introduces a schema you would need to keep synchronized. Evaluate it as a reference rather than a cherry-pick. The soft-delete Prisma extension and the `audit.ts` utility are the most reusable pieces in isolation. Worth studying if you are planning to move off Supabase SDK data access; probably not worth porting piecemeal.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from Dshamir/AI-Legal, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
7af01ab6 [P3] chore: initialize Prisma ORM Dshamir 2026-05-23 ↗ GitHub
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
872dcfc5 [P3] feat: add complete Prisma schema with enums and soft-delete Dshamir 2026-05-23 ↗ GitHub
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
139c4d38 [P3] feat: add Prisma client with soft-delete extension Dshamir 2026-05-23 ↗ GitHub
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7b042604 [P3] feat: add audit log utility Dshamir 2026-05-23 ↗ GitHub
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
54378941 [P3] feat: add Prisma seed script Dshamir 2026-05-23 ↗ GitHub
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9485e7d9 [P3] feat: migrate all routes and libs from Supabase SDK to Prisma Dshamir 2026-05-23 ↗ GitHub
commit body
Replace every supabase.from() query across 13 files with Prisma client
calls. Auth middleware (auth.ts) intentionally retained Supabase for
admin.auth.getUser(). Added audit logging on create/update/delete
operations in route handlers.

Files migrated:
- Routes: chat, projectChat, projects, documents, tabular, workflows,
  user, downloads
- Libraries: access, chatTools, documentVersions, userApiKeys,
  userSettings

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-521.md from inside the repo you want the changes in.

⬇ Download capture-thread-521.md