Next.js Supabase V3 (#463)

Version 3 of the kit:
- Radix UI replaced with Base UI (using the Shadcn UI patterns)
- next-intl replaces react-i18next
- enhanceAction deprecated; usage moved to next-safe-action
- main layout now wrapped with [locale] path segment
- Teams only mode
- Layout updates
- Zod v4
- Next.js 16.2
- Typescript 6
- All other dependencies updated
- Removed deprecated Edge CSRF
- Dynamic Github Action runner
This commit is contained in:
Giancarlo Buomprisco
2026-03-24 13:40:38 +08:00
committed by GitHub
parent 4912e402a3
commit 7ebff31475
840 changed files with 71395 additions and 20095 deletions

View File

@@ -1,43 +1,22 @@
# Database & Authentication
# @kit/supabase — Database & Authentication
## Non-Negotiables
1. 3 clients: `getSupabaseServerClient()` (server, RLS enforced), `useSupabase()` (client hook, RLS enforced), `getSupabaseServerAdminClient()` (bypasses RLS, use rarely and only if needed)
2. NEVER use admin client without manually validating authorization first
3. NEVER modify `database.types.ts` manually — regenerate with `pnpm supabase:web:typegen`
4. NEVER add manual auth checks when using standard client — trust RLS
5. ALWAYS add indexes on foreign keys
6. ALWAYS include `account_id` in storage paths
7. Use `Tables<'table_name'>` from `@kit/supabase/database` for type references, don't create new types
## Skills
For database work:
- `/postgres-expert` - Schemas, RLS, migrations
- `/postgres-expert` — Schemas, RLS, migrations, query optimization
## Client Usage
## SQL Helper Functions
### Server Components (Preferred)
```typescript
import { getSupabaseServerClient } from '@kit/supabase/server-client';
const client = getSupabaseServerClient();
const { data } = await client.from('table').select('*');
// RLS automatically enforced
```
### Client Components
```typescript
'use client';
import { useSupabase } from '@kit/supabase/hooks/use-supabase';
const supabase = useSupabase();
```
### Admin Client (Use Sparingly)
```typescript
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
// CRITICAL: Bypasses RLS - validate manually!
const adminClient = getSupabaseServerAdminClient();
```
## Existing Helper Functions
```sql
public.has_role_on_account(account_id, role?)
public.has_permission(user_id, account_id, permission)
public.is_account_owner(account_id)
@@ -46,29 +25,16 @@ public.is_team_member(account_id, user_id)
public.is_super_admin()
```
## Type Generation
## Key Imports
```typescript
import { Tables } from '@kit/supabase/database';
| Function | Import |
| ------------- | -------------------------------------------------------------------------------- |
| Server client | `getSupabaseServerClient` from `@kit/supabase/server-client` |
| Client hook | `useSupabase` from `@kit/supabase/hooks/use-supabase` |
| Admin client | `getSupabaseServerAdminClient` from `@kit/supabase/server-admin-client` |
| Require user | `requireUser` from `@kit/supabase/require-user` |
| MFA check | `checkRequiresMultiFactorAuthentication` from `@kit/supabase/check-requires-mfa` |
type Account = Tables<'accounts'>;
```
## Exemplar
Never modify `database.types.ts` - regenerate with `pnpm supabase:web:typegen`.
## Authentication
```typescript
import { requireUser } from '@kit/supabase/require-user';
import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa';
const user = await requireUser(client);
const requiresMfa = await checkRequiresMultiFactorAuthentication(client);
```
## Security Guidelines
- Standard client: Trust RLS
- Admin client: Validate everything manually
- Always add indexes for foreign keys
- Storage paths must include account_id
- `apps/web/app/[locale]/home/(user)/_lib/server/load-user-workspace.ts` — server client with RLS