From cf2a10074429c64d3ddcd5d6896b5f1687bb2001 Mon Sep 17 00:00:00 2001 From: willbot Date: Fri, 17 Jul 2026 11:55:15 +0200 Subject: [PATCH] =?UTF-8?q?docs(skills):=20drop=20the=20RLS-testing=20guid?= =?UTF-8?q?ance=20=E2=80=94=20how=20users=20test=20Supabase=20is=20not=20o?= =?UTF-8?q?ur=20surface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Supabase skill taught pgTAP syntax and a supabase test db workflow; the upgrade recipes and extension README echoed it. None of it is Prisma Next product surface, nothing in the repo runs it, and the endorsement traces to a forwarded suggestion, not a product decision. The skill now covers only what is ours: policy authoring, migrations, role binding, JWT config, connections, grants. Signed-off-by: willbot Signed-off-by: Will Madden --- packages/3-extensions/supabase/README.md | 2 +- .../upgrades/0.15-to-0.16/instructions.md | 3 +- skills/prisma-next-supabase/SKILL.md | 32 +------------------ .../upgrades/0.15-to-0.16/instructions.md | 4 +-- 4 files changed, 4 insertions(+), 37 deletions(-) diff --git a/packages/3-extensions/supabase/README.md b/packages/3-extensions/supabase/README.md index 5ef16aa22d..f2a4149422 100644 --- a/packages/3-extensions/supabase/README.md +++ b/packages/3-extensions/supabase/README.md @@ -18,7 +18,7 @@ The contract is **introspected, not hand-authored**: `pnpm contract:generate` re - **`/pack` subpath**: an `ExtensionPack` value (`supabasePack` default + `supabasePackWith(options)` factory) that an app composes into its config via `extensionPacks`. Tree-shaking-clean — `/pack` imports no runtime code. - **`/runtime` subpath**: the `SupabaseRuntime` role-binding runtime and `supabase({...})` facade (session-coupled `set_config` role + claims binding, per [ADR 230](../../../docs/architecture%20docs/adrs/ADR%20230%20-%20Runtime%20target%20layer%20session-coupled%20connections.md)), plus the `service_role`-only `.supabase` secondary root. - **`/contract` subpath**: branded model handles for the commonly-referenced models (`AuthUser`, `AuthIdentity`, `AuthSession`, `StorageBucket`, `StorageObject`) used for cross-space FK references from app contracts. The handle set is deliberately curated, not one-per-table. -- **Internal test substrate** (not published): `test/fixtures/supabase-reference/set-up-mock-schema.ts` exports `setUpSupabaseMockSchema(client)`, restoring the reference fixture (all Supabase schemas, tables, roles, and the platform's real default privileges) into a test database. Used only by this package's tests — including the hermetic PGlite coverage of the example app's flows (`test/fixtures/example-app/`); `examples/supabase` itself ships only the real-Supabase acceptance suite. User-facing RLS testing is Supabase's own tooling (`supabase start` + `supabase test db`). +- **Internal test substrate** (not published): `test/fixtures/supabase-reference/set-up-mock-schema.ts` exports `setUpSupabaseMockSchema(client)`, restoring the reference fixture (all Supabase schemas, tables, roles, and the platform's real default privileges) into a test database. Used only by this package's tests — including the hermetic PGlite coverage of the example app's flows (`test/fixtures/example-app/`); `examples/supabase` itself ships only the real-Supabase acceptance suite. ## Dependencies diff --git a/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.15-to-0.16/instructions.md b/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.15-to-0.16/instructions.md index 4e9e7a8861..a5360e6de5 100644 --- a/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.15-to-0.16/instructions.md +++ b/skills/extension-author/prisma-next-extension-upgrade/upgrades/0.15-to-0.16/instructions.md @@ -11,8 +11,7 @@ changes: failed with ENOENT before touching a database. Delete any import of `@prisma-next/extension-supabase/test/utils`; keep hermetic test helpers package-internal (tests import them by source path) rather than publishing them as subpath exports whose - on-disk fixtures don't ship. For Supabase-shaped testing, use Supabase's own tooling - (`supabase start` / `supabase db reset`, `supabase test db` with pgTAP). + on-disk fixtures don't ship. detection: glob: "**/*.{ts,mts,cts,js,mjs}" contains: diff --git a/skills/prisma-next-supabase/SKILL.md b/skills/prisma-next-supabase/SKILL.md index 078615c37f..0f4c8ff4d7 100644 --- a/skills/prisma-next-supabase/SKILL.md +++ b/skills/prisma-next-supabase/SKILL.md @@ -210,36 +210,6 @@ The concept: the runtime needs a **direct, session-capable** Postgres connection `.env` carries `DATABASE_URL` and the JWT key source. For current projects that is `SUPABASE_JWKS_URL` — `https://.supabase.co/auth/v1/.well-known/jwks.json` (local stack: `http://127.0.0.1:54321/auth/v1/.well-known/jwks.json`). Only legacy HS256 projects use `SUPABASE_JWT_SECRET` (Project Settings → API → JWT Secret) — and note `supabase status` prints a `JWT_SECRET` even on ES256 projects, so don't infer the mode from its presence; check the JWKS endpoint or a token's header `alg`. -## Workflow — Testing your RLS policies - -The concept: test RLS against the real thing — the Supabase CLI's local stack. RLS is enforced by policies *and* grants, so a test database whose grants differ from a real project can pass policies that production denies (and vice versa); only the actual stack is faithful. Users already run the CLI for local dev, and it ships a test runner: - -- `supabase start` / `supabase db reset` boot and reset the local containers; run `prisma-next db init` (or `migrate`) against the local `DATABASE_URL` to apply your contract. -- `supabase test db` runs [pgTAP](https://pgtap.org/) tests from `supabase/tests/` — the right altitude for RLS assertions ("`anon` cannot see this row"): - -```sql --- supabase/tests/profile-rls.test.sql -begin; -select plan(2); - --- Seed as the superuser (bypasses RLS): one auth user + their profile. -insert into auth.users (id) values ('00000000-0000-0000-0000-000000000001'); -insert into public.profile (id, username, "userId") - values (gen_random_uuid(), 'alice', '00000000-0000-0000-0000-000000000001'); - -set local role anon; -select is((select count(*)::int from public.profile), 0, 'anon sees no profiles (no anon policy matches)'); - -set local role authenticated; -select set_config('request.jwt.claims', '{"sub":"00000000-0000-0000-0000-000000000001","role":"authenticated"}', true); -select is((select count(*)::int from public.profile where "userId" = auth.uid()), 1, 'owner reads exactly their profile'); - -select * from finish(); -rollback; -``` - -- End-to-end runtime behavior (JWT verification, role binding, `RoleBoundDb` queries) is exercised by your app's own integration tests against the same local stack — see `examples/supabase/test/real-supabase.acceptance.test.ts` for the canonical shape. - ## Common Pitfalls 1. **Using the transaction pooler (port 6543).** Session GUC role binding requires a session-capable connection — use the session pooler (5432) or the direct connection. @@ -263,7 +233,7 @@ rollback; ## Reference Files -- `examples/supabase` — the canonical runnable app: config, contract, `db.ts`, hermetic + acceptance tests, README. +- `examples/supabase` — the canonical runnable app: config, contract, `db.ts`, acceptance tests, README. - `packages/3-extensions/supabase/README.md` — package-level reference (JWT modes, role-binding model, unsupported scope). - `packages/3-extensions/supabase/src/runtime/supabase.ts` — the authoritative options/type surface (`SupabaseOptions`, `RoleBoundDb`, `ServiceRoleDb`). diff --git a/skills/upgrade/prisma-next-upgrade/upgrades/0.15-to-0.16/instructions.md b/skills/upgrade/prisma-next-upgrade/upgrades/0.15-to-0.16/instructions.md index 1616916831..56d39dca63 100644 --- a/skills/upgrade/prisma-next-upgrade/upgrades/0.15-to-0.16/instructions.md +++ b/skills/upgrade/prisma-next-upgrade/upgrades/0.15-to-0.16/instructions.md @@ -9,9 +9,7 @@ changes: subpath never worked from npm — the shim reads fixture `.sql` files that were never published, so every call failed with ENOENT before touching a database. There is no working code to migrate: delete the import and whatever test setup called - `bootstrapSupabaseShim`. Test against Supabase's own tooling instead — `supabase start` - / `supabase db reset` for a local stack, and `supabase test db` (pgTAP) for asserting - RLS behaviour (for example that `anon` cannot see a row). + `bootstrapSupabaseShim`. detection: glob: "**/*.{ts,mts,cts,js,mjs}" contains: