Skip to content

stash eql migration: migration-first, ORM-agnostic EQL v3 install (fixes prisma-next superuser-on-Supabase) #690

Description

@coderdan

Problem

EQL install differs per integration, and prisma-next's approach breaks on Supabase:

  • Drizzle (v3) delegates EQL install to the CLI (stash eql install), which owns four pre-built SQL variants + runtime Supabase selection + grants. Works everywhere.
  • prisma-next owns install by inlining the full v2 bundle into a baked baseline migration (migrations/…/ops.jsoninstallBundle op). That bundle has 9 CREATE OPERATOR CLASS/FAMILY statements → requires superuser → fails on Supabase (Supabase's postgres role is not a superuser). It also applies no grants and has no target awareness (the descriptor is static, so there's no apply-time "is this Supabase?" seam).

Root cause confirmed by reproducing the bundle diff: the CLI's cipherstash-encrypt.sql has 9 operator classes/families; cipherstash-encrypt-supabase.sql has 0 (that's the only difference, ~210 lines). The CLI picks the right one at install time via resolveBundledFilename.

Decisions (owner: @coderdan)

  1. prisma-next is v3-only. v2 was never released for prisma-next, so drop it entirely. Both Drizzle and prisma-next migrations target EQL v3. (prisma-next's move to v3 is PR Feat/prisma next eql v3 #655, in-flight.)
  2. Migration-first, ORM-agnostic install via a new CLI command:
    stash eql migration --drizzle | --prisma  [--supabase]  [--out <dir>] [--name <name>] [--dry-run]
    
    • Emits an EQL-install migration file in the target ORM's format (preferred over direct-to-DB execution, which stays as stash eql install for quick/dev).
    • Single source of install SQL: the CLI's bundled v3 SQL (loadBundledEqlSql({ eqlVersion: 3 })). --supabase appends the v3 grants (supabaseGrantsFor(3)eql_v3 + eql_v3_internal GRANTs to anon/authenticated/service_role). (The v3 bundle itself is a single file used for all targets — its operator classes do not trip the superuser wall the way v2's 9 do.)
    • --drizzle → reuse the existing Drizzle custom-migration emission.
    • --prisma → new emitter writing a Prisma-Next migration.ts (the framework Migration shape) into the user's migrations dir.
  3. prisma-next stops owning install. Its baked-in installBundle baseline (the inlined bundle in ops.json) is removed; users generate the install migration with stash eql migration --prisma [--supabase], exactly as Drizzle users would. This is the change that makes prisma-next Supabase-safe.

Sequencing (3 PRs)

  1. PR1 — stash eql migration --drizzle [--supabase] (v3), off main. Independent of prisma-next; Drizzle v3 is already on main. Adds the eql migration command (registry + dispatch + generation), reusing loadBundledEqlSql/supabaseGrantsFor. --prisma is registered but returns "not yet available (tracked here)" until PR3. Tests + stash/stash-drizzle/stash-cli updates + changeset. Merge this.
  2. PR2 — rebase Feat/prisma next eql v3 #655 (feat/prisma-next-eql-v3) on the merged PR1.
  3. PR3 — --prisma emitter + remove prisma-next's baked baseline, stacked on Feat/prisma next eql v3 #655. Emits the v3 install migration in the framework Migration shape; drops the installBundle op from the descriptor/ops.json; updates the prisma-next skill/example to run stash eql migration --prisma.

Notes

  • Grants: Drizzle/prisma-next apps connect directly as postgres, so the anon/authenticated/service_role grants matter only when the same tables are also reached via PostgREST/RLS. --supabase includes them for parity with stash eql install --supabase; harmless (idempotent) otherwise.
  • This unifies EQL-install SQL under one CLI source of truth (no vendored fork per ORM), which also removes prisma-next's "indivisible bundle" maintenance burden.

Part of the stack 1.0 + EQL v3 GA push.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions