The Wave 1 Supabase migration creates the squad, kanban, time-tracking, invoicing, notification, and chat tables from remastery spec section 2 โ with Row Level Security and indexes. Run it in the Supabase SQL editor, in order, then prove it worked.
6
table groups
19
tables + join tables
RLS
on, everywhere
6
verify queries
1Before you run
Preflight checklist
The full DDL lives in the remastery spec (public/swarm/remastery/README.md, section 2). This page is the run order and the proof โ run each block in the Supabase SQL editor for the project that hosts the app, top to bottom.
1
Back up first
Snapshot the database (Supabase dashboard โ Database โ Backups) before running anything. A migration you can roll back is a migration you can run calmly.
2
Confirm the squads table exists
The migration references public.squads(id) and public.squad_members(squad_id, user_id). If your project predates squads, create those base tables first โ every foreign key below hangs off them.
3
Run as a service-role SQL editor session
RLS policies reference auth.uid(). Run the DDL in the SQL editor (bypasses RLS) and test the policies afterward as an authenticated app user, not as the editor.
2Block A
Squad projects and members
Creates squad_projects (name, description, repository_url, target_game_slug) and the squad_project_members join table with lead / contributor / reviewer roles. Depends on public.squads and auth.users.
block A โ tables
2 tables
squad_projectssquad_id โ squads
squad_project_membersPK (project_id, user_id)
3Block B
Kanban boards, cycles, columns, cards
Creates kanban_boards, kanban_cycles (sprint windows with 0โ100 progress), kanban_columns (positioned lists), and kanban_cards (priority, estimate_hours, due_date, labels, assignee, position). Cards link to boards, cycles, columns, and optionally to time entries.
block B โ tables
4 tables
kanban_boardsowner + squad
kanban_cyclesstart/end_date
kanban_columnsposition
kanban_cardscolumn + cycle + assignee
4Block C
Time tracking and invoicing
Creates time_projects (rates, budgets, billable flags), time_entries (start/end, duration_seconds, invoiced flag, optional card link), invoice_clients, invoices (draft โ sent โ paid, with deleted_at for the 30-day trash), and invoice_line_items. Money-adjacent tables are owner-scoped: every policy keys off auth.uid() = user_id.
block C โ tables
5 tables
time_projects / time_entriesowner-scoped
invoice_clientsowner-scoped
invoicesdeleted_at = trash
invoice_line_itemsvia parent invoice
5Block D
Notifications and chat
Creates notifications (category, title, message, action_url, is_read) plus chat_threads, chat_participants, and chat_messages. Chat reads require thread membership; message inserts require the sender to be a participant.
6Block E
Enable RLS and create policies
Enable Row Level Security on every new table, then create the policies in spec order: squad/kanban membership checks, owner-only time and invoice policies, own-notifications read/update, and chat membership-gated read/insert. Run the whole RLS block as one transaction so a halfway policy set never ships.
7Block F
Performance indexes
Create the six indexes last: invoices by (user_id, deleted_at) for the trash tab, time_entries by (user_id, project_id, start_time), kanban_cards by (column_id, position), notifications by (user_id, is_read, created_at), chat_messages by (thread_id, created_at), and dps_nodes by (status, last_heartbeat).
8Proof
Verify queries โ all six must return clean
1
Tables exist
Query information_schema.tables for the 19 names. Every block-AโD table must appear exactly once.
2
RLS is on
Query pg_tables where rowsecurity is true for each new table. Any false row means block E did not finish โ re-run it.
3
Policies exist
Query pg_policies for squad_projects_read, kanban_boards_access, kanban_cards_access, time/invoice owner policies, notifications read/update, and the three chat policies.
4
Indexes exist
Query pg_indexes for idx_invoices_user_deleted, idx_time_entries_user_proj, idx_kanban_cards_pos, idx_notifications_unread, idx_chat_messages_time, and idx_dps_nodes_active.
5
Trash lifecycle works
Insert a draft invoice, set deleted_at, confirm it disappears from the active list query (deleted_at IS NULL) and appears in the trash query.
6
Membership gating works
As two test users, confirm cross-squad board reads and non-member chat reads return zero rows.
Green on all six? Continue to squad workspaces. Anything red is a migration problem, not an app problem โ fix it here before opening the app pages.