Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/3-extensions/supabase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
32 changes: 1 addition & 31 deletions skills/prisma-next-supabase/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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://<project-ref>.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.
Expand All @@ -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`).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading