Quando usarlo
L'app salva nuovi dati dell'utente in Supabase, per esempio note, preferiti o voci di un diario, e li mostra in una schermata.
Regole da rispettare
- L'app contiene la chiave publishable, quindi la RLS è l'unica cosa che separa le righe di un utente da quelle di un altro. Ogni nuova tabella abilita la RLS nella migration che la crea.
- Le migration sono append-only: non modificarne mai una già applicata.
- Ogni nuova policy ha un test pgTAP che prova l'accesso consentito e rifiuta il resto.
- Supabase si chiama solo da un repository in
data, dietro un'interfaccia indomain.
Passi
Crea
supabase/migrations/<timestamp>_<nome>.sqlcon un timestamp successivo all'ultimo, sul modello dipush_devices:create table public.notes ( id uuid primary key default gen_random_uuid(), user_id uuid not null default auth.uid() references auth.users(id) on delete cascade, body text not null check (char_length(body) between 1 and 2000), created_at timestamptz not null default now() ); create index notes_user_id_idx on public.notes (user_id); alter table public.notes enable row level security; create policy "notes_select_own" on public.notes for select to authenticated using ((select auth.uid()) = user_id); create policy "notes_insert_own" on public.notes for insert to authenticated with check ((select auth.uid()) = user_id); create policy "notes_delete_own" on public.notes for delete to authenticated using ((select auth.uid()) = user_id); revoke all on public.notes from anon;Aggiungi solo le operazioni che servono all'app: qui gli utenti non possono modificare una nota.
Se una scrittura richiede regole che una policy non può esprimere, come cambiare proprietario o controllare altre tabelle, revoca le scritture dirette ed esponi una funzione
security definerconset search_path = ''e un controllo suauth.uid(), come faregister_push_device.Aggiungi
supabase/tests/database/<nome>_rls.test.sqlsul modello dipush_devices_rls.test.sql: due utenti inauth.users,set local role authenticated,request.jwt.claim.subimpostato a turno su ciascun utente. Verifica che un utente veda e modifichi solo le proprie righe, che scrivere una riga per un altro fallisca con42501e cheanonnon riceva nulla.Esegui
supabase db resetesupabase test dbin locale.In
lib/features/<feature>/domaindefinisci il modello confromJsone unaabstract interface classper il repository, comeProfileRepository. Indataimplementala conSupabaseClient, comeSupabaseProfileRepository: senza sessione, lancia un errore invece di eseguire la query.In
applicationesponi il repository con unProviderche leggesupabaseClientProvider, comeprofileRepositoryProvider, e aggiungi i provider osservati dalla schermata. Per costruire la schermata segui il playbook "Aggiungere una schermata con routing e stato".Aggiungi test Dart per la conversione del modello e per i provider con un repository fake; i test non usano la rete.
Aggiungi tabella, proprietario e regola alla tabella di
DATABASE.md.
Completato quando
- i comandi di verifica passano;
supabase test dbpassa, compreso il nuovo test;- la tabella ha la RLS abilitata e solo le policy che servono all'app;
DATABASE.mdelenca la tabella.
