Supabase Integration
CRITICAL: Backend-First Execution Order
You MUST set up the Supabase backend BEFORE writing any Swift code. Follow this exact order:
Phase 1: Backend Setup (via Supabase MCP)
- Create all tables with
mcp__supabase__execute_sql — columns, types, foreign keys, constraints, indexes
- Enable RLS on every table —
ALTER TABLE ... ENABLE ROW LEVEL SECURITY
- Create RLS policies for every table — SELECT, INSERT, UPDATE, DELETE as appropriate
- Create storage buckets — public for images, private for documents
- Create storage policies — per-user folder enforcement on
storage.objects
- Create triggers — for
updated_at, denormalized counters, etc.
- Verify with
mcp__supabase__list_tables and mcp__supabase__list_storage_buckets
- Check auth config with
mcp__supabase__get_auth_config to confirm providers are enabled (auto-configured by nanowave)
Phase 2: Swift Code
- Write
Config/AppConfig.swift — Supabase URL + anon key
- Write
SupabaseService.swift — shared client
- Write models with
Codable + CodingKeys matching the table columns you just created
- Write services that query the tables you just created
- Write views
NEVER skip Phase 1. If you write Swift code that references tables that don't exist, the app will crash at runtime.
Client Initialization
Initialize SupabaseClient once in a shared service. Use PKCE auth flow (default for mobile).
import Supabase
@Observable
final class SupabaseService {
static let shared = SupabaseService()
let client: SupabaseClient
private init() {
client = SupabaseClient(
supabaseURL: URL(string: AppConfig.supabaseURL)!,
supabaseKey: AppConfig.supabaseAnonKey
)
}
}
AppConfig Pattern
Store Supabase credentials as static constants — injected by nanowave during build.
enum AppConfig {
static let supabaseURL = "https://PROJECT_REF.supabase.co"
static let supabaseAnonKey = "YOUR_ANON_KEY"
}
Key Rules
- Backend first — create tables, RLS, buckets via MCP before writing Swift code
- Never manage tokens manually — Supabase SDK auto-refreshes sessions
- Auth architecture is handled by the
authentication skill (AuthService, guards, modes) — this skill covers only the Supabase auth API calls
- Data access architecture (repository protocols, DTOs, domain mapping) is handled by the
repositories skill — this skill covers Supabase API patterns used inside concrete repository implementations
- Models use Codable (NOT @Model) — Supabase is the persistence layer, not SwiftData
- All operations are async/await — no callbacks, no Combine
- RLS on every table — never leave a table without Row Level Security
- Use XcodeGen MCP to add "Sign in with Apple" entitlement when auth is needed
- Auth providers are auto-configured by the nanowave pipeline — use
mcp__supabase__get_auth_config to verify, use mcp__supabase__configure_auth_providers only if manual adjustment is needed
Available MCP Tools
mcp__supabase__execute_sql — run SQL queries (SELECT, DML)
mcp__supabase__list_tables — list tables in schemas
mcp__supabase__apply_migration — track DDL as versioned migrations
mcp__supabase__list_storage_buckets — list storage buckets
mcp__supabase__get_project_url — get project URL for Swift client
mcp__supabase__get_anon_key — get anon key for Swift client
mcp__supabase__get_logs — query project logs
mcp__supabase__configure_auth_providers — enable/disable auth providers (apple, google, email, phone, anonymous)
mcp__supabase__get_auth_config — check current auth provider configuration
mcp__supabase__set_secrets — set edge function environment variables (name/value pairs)
mcp__supabase__list_secrets — list all project secrets
mcp__supabase__delete_secrets — delete secrets by name
References
Core
- Schema Setup — table creation, types, foreign keys, triggers
- RLS Policies — Row Level Security patterns for every table type
- Auth Patterns — email auth, Apple Sign In, auth state, guards
- Database Patterns — CRUD, filtering, realtime subscriptions
Storage
- Storage Setup — bucket creation, storage policies, path conventions
- Storage Patterns — upload, download, public/signed URLs
- Storage Service — StorageService singleton, image compression, PhotosPicker flow, ViewModel upload patterns
Management API
- Secrets API — edge function environment variables (create, list, delete)
- Edge Functions — deploying and managing edge functions via API
- API Keys — retrieving project anon/service_role keys
- Realtime — enabling per-table realtime via SQL publication
- Webhooks & Triggers — database webhooks, pg_net, Vault integration
1---2name: supabase3description: Supabase Swift SDK patterns for auth, database, and storage. Use when implementing app features related to supabase.4---5# Supabase Integration67## CRITICAL: Backend-First Execution Order89You MUST set up the Supabase backend BEFORE writing any Swift code. Follow this exact order:1011### Phase 1: Backend Setup (via Supabase MCP)121. **Create all tables** with `mcp__supabase__execute_sql` — columns, types, foreign keys, constraints, indexes132. **Enable RLS** on every table — `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`143. **Create RLS policies** for every table — SELECT, INSERT, UPDATE, DELETE as appropriate154. **Create storage buckets** — public for images, private for documents165. **Create storage policies** — per-user folder enforcement on `storage.objects`176. **Create triggers** — for `updated_at`, denormalized counters, etc.187. **Verify** with `mcp__supabase__list_tables` and `mcp__supabase__list_storage_buckets`198. **Check auth config** with `mcp__supabase__get_auth_config` to confirm providers are enabled (auto-configured by nanowave)2021### Phase 2: Swift Code228. Write `Config/AppConfig.swift` — Supabase URL + anon key239. Write `SupabaseService.swift` — shared client2410. Write models with `Codable` + `CodingKeys` matching the table columns you just created2511. Write services that query the tables you just created2612. Write views2728**NEVER skip Phase 1.** If you write Swift code that references tables that don't exist, the app will crash at runtime.2930## Client Initialization3132Initialize `SupabaseClient` once in a shared service. Use PKCE auth flow (default for mobile).3334```swift35import Supabase3637@Observable38final class SupabaseService {39 static let shared = SupabaseService()40 let client: SupabaseClient4142 private init() {43 client = SupabaseClient(44 supabaseURL: URL(string: AppConfig.supabaseURL)!,45 supabaseKey: AppConfig.supabaseAnonKey46 )47 }48}49```5051## AppConfig Pattern5253Store Supabase credentials as static constants — injected by nanowave during build.5455```swift56enum AppConfig {57 static let supabaseURL = "https://PROJECT_REF.supabase.co"58 static let supabaseAnonKey = "YOUR_ANON_KEY"59}60```6162## Key Rules6364- **Backend first** — create tables, RLS, buckets via MCP before writing Swift code65- **Never manage tokens manually** — Supabase SDK auto-refreshes sessions66- **Auth architecture** is handled by the `authentication` skill (AuthService, guards, modes) — this skill covers only the Supabase auth API calls67- **Data access architecture** (repository protocols, DTOs, domain mapping) is handled by the `repositories` skill — this skill covers Supabase API patterns used inside concrete repository implementations68- **Models use Codable** (NOT @Model) — Supabase is the persistence layer, not SwiftData69- **All operations are async/await** — no callbacks, no Combine70- **RLS on every table** — never leave a table without Row Level Security71- **Use XcodeGen MCP** to add "Sign in with Apple" entitlement when auth is needed72- **Auth providers are auto-configured** by the nanowave pipeline — use `mcp__supabase__get_auth_config` to verify, use `mcp__supabase__configure_auth_providers` only if manual adjustment is needed7374## Available MCP Tools7576- `mcp__supabase__execute_sql` — run SQL queries (SELECT, DML)77- `mcp__supabase__list_tables` — list tables in schemas78- `mcp__supabase__apply_migration` — track DDL as versioned migrations79- `mcp__supabase__list_storage_buckets` — list storage buckets80- `mcp__supabase__get_project_url` — get project URL for Swift client81- `mcp__supabase__get_anon_key` — get anon key for Swift client82- `mcp__supabase__get_logs` — query project logs83- `mcp__supabase__configure_auth_providers` — enable/disable auth providers (apple, google, email, phone, anonymous)84- `mcp__supabase__get_auth_config` — check current auth provider configuration85- `mcp__supabase__set_secrets` — set edge function environment variables (name/value pairs)86- `mcp__supabase__list_secrets` — list all project secrets87- `mcp__supabase__delete_secrets` — delete secrets by name8889## References9091### Core92- [Schema Setup](references/schema-setup.md) — table creation, types, foreign keys, triggers93- [RLS Policies](references/rls-policies.md) — Row Level Security patterns for every table type94- [Auth Patterns](references/auth-patterns.md) — email auth, Apple Sign In, auth state, guards95- [Database Patterns](references/database-patterns.md) — CRUD, filtering, realtime subscriptions9697### Storage98- [Storage Setup](references/storage-setup.md) — bucket creation, storage policies, path conventions99- [Storage Patterns](references/storage-patterns.md) — upload, download, public/signed URLs100- [Storage Service](references/storage-service.md) — StorageService singleton, image compression, PhotosPicker flow, ViewModel upload patterns101102### Management API103- [Secrets API](references/secrets-api.md) — edge function environment variables (create, list, delete)104- [Edge Functions](references/edge-functions.md) — deploying and managing edge functions via API105- [API Keys](references/api-keys.md) — retrieving project anon/service_role keys106- [Realtime](references/realtime.md) — enabling per-table realtime via SQL publication107- [Webhooks & Triggers](references/webhooks-triggers.md) — database webhooks, pg_net, Vault integration