Supabase Reference
Multi-tenant database patterns for Sanctiv.Multi-Tenant Architecture
Key Concepts:- Organizations: Churches with unique slugs and settings
- Users: Belong to exactly one organization, have roles (member/admin/pastor)
- Data Isolation: Row Level Security (RLS) ensures users only access their org’s data
- Journal Entries: Include
user_idandorg_idfor multi-tenant isolation - Goals & Reports: Also scoped to
user_idandorg_id
organizations- Churches with slug, settings, timezonepublic.users- User profiles linked to organizationsjournal_entries- Journal entries with multi-tenant isolationgoals- User goals with categoriesweekly_reports- AI-generated weekly insights
- ✅ Always include
org_idwhen querying or inserting data - ❌ Never hard-code organization IDs
- ✅ Always test with users from different organizations
- ✅ Verify RLS policies prevent cross-org access
Environment Variables
2025 API Key Update: Supabase has transitioned from legacy JWT-based keys to new publishable/secret keys. Always use publishable keys - legacy anon keys are disabled.- Always use
sb_publishable_...keys - legacyanonkeys are disabled - Better security: Independent rotation, shorter expiry periods
- Legacy keys no longer work - use
supabase projects api-keysto get publishable key - Setup workflow automatically extracts publishable key from CLI
Schema
Client Setup
Location:src/lib/supabase.ts
2025 Update: Uses AsyncStorage for React Native session persistence.
@supabase/supabase-js- Supabase client library@react-native-async-storage/async-storage- Already installed in Expo SDK 53
Usage Patterns
Query with RLS
Insert
Row-Level Security (RLS)
Critical: All queries are automatically filtered by RLS policies. Users can only access data from their organization. Testing RLS:- Create test users in different organizations
- Verify user A cannot see user B’s data if in different orgs
- Never bypass RLS in client-side code
- Test all CRUD operations with multi-org users
Service Layer Pattern
After Phase 4: Always use service layer❌ DON’T: Direct Supabase calls in components
✅ DO: Use service layer
Zustand Integration
Multi-Tenant Checklist
When creating/updating data operations:- Include
org_idin all inserts - Filter queries by
org_id - Test with users from different organizations
- Verify RLS policies prevent cross-org access
- Never hard-code organization IDs
- Use
getCurrentUserOrgId()helper - Handle cases where
org_idis null
TypeScript Types
Seed Data (10 Pilot Churches)
Source: sanctiv-master/packages/database/
Package:
@supabase/supabase-js