# Supabase migration v2 ## Prerequisites - A backup of the live Supabase database. - SQL Editor access as a role allowed to create extensions, tables, policies, and storage policies. - Supabase schemas/roles (`auth`, `storage`, `authenticated`, `anon`, `service_role`) must exist for the RLS/storage sections. - Review `supabase_audit_report.md`, especially the commented drop candidates. ## Strategy 1. **CREATE:** preserve the cloud UUID `tenants` root and create only Knex-defined tables missing from cloud with `CREATE TABLE IF NOT EXISTS`. 2. **ALTER:** add follow-up migration columns and inject `tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE` only where absent. 3. **RLS:** index every domain `tenant_id`, enable RLS, and recreate tenant-isolation plus service-role policies idempotently. ## Apply Run `supabase_migration_v2.sql` once in the Supabase SQL Editor. It is designed for one execution and safe re-execution. The DROP section is entirely commented; do not uncomment it without a backup and code-usage review. ## SHOULD-DROP review - `assignment_submissions`: overlaps `submissions`; no inbound dump FK, outbound to `assignments`/`users`; verify code usage. - `attendance_new`: canonical table is `attendance`; no inbound dump FK, outbound to `users`/`subjects_new`. - `calendar_events`: canonical table is `events`; no inbound dump FK, outbound to `users`; verify calendar code. - `edutainment_content`: no inbound dump FK, outbound to `subjects_new`/`users`; verify feature retirement. - `edutainment_sessions`: outbound to `edutainment_games`/`users`; drop before or with games. - `edutainment_games`: inbound from `edutainment_sessions`; requires sessions-first or `CASCADE`; outbound to `subjects_new`/`users`. - `messages_new`: canonical table is `messages`; no inbound dump FK, outbound to `users`; verify messaging code. `subjects_new` must not be dropped: Knex explicitly creates it and multiple dump FKs target it. ## Rollback There is no automatic destructive rollback. Restore the pre-migration backup for a full rollback. For a targeted rollback, drop only newly created tables in reverse dependency order and remove policies/indexes/`tenant_id` columns only after confirming no tenant data depends on them. The seed can be removed with: ```sql DELETE FROM tenants WHERE id = '5b39bcb5-506a-456d-b7cb-91730b397cc1'; ``` ## Verification ```sql SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename; ``` Also verify tenant columns and indexes: ```sql SELECT table_name FROM information_schema.columns WHERE table_schema = 'public' AND column_name = 'tenant_id' ORDER BY table_name; ``` ## Tenant UUID alignment The Knex migration and cloud schema both use UUID tenant IDs. The default test tenant is `5b39bcb5-506a-456d-b7cb-91730b397cc1`, and the SuperAdmin controller generates UUIDv4 IDs for new tenants.