-- ============================================================================ -- 📊 TASK MANAGER - Supabase Database Schema com Row Level Security (RLS) -- ============================================================================ -- Este script cria a tabela 'tasks' e implementa RLS para garantir que -- cada usuário acesse apenas suas próprias tarefas. -- -- Executar em: Supabase SQL Editor -- Ambiente: Development ou Production (conforme necessário) -- ============================================================================ -- ============================================================================ -- 1️⃣ CRIAR TABELA TASKS -- ============================================================================ CREATE TABLE IF NOT EXISTS public.tasks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 🔗 Referência ao usuário user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, -- 📝 Dados da tarefa title VARCHAR(255) NOT NULL, description TEXT, completed BOOLEAN DEFAULT FALSE, -- 📅 Datas due_date TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- 🏷️ Categorização e prioridade category VARCHAR(50), priority VARCHAR(20) DEFAULT 'medium' CHECK (priority IN ('low', 'medium', 'high')), -- 🔍 Índices para performance CONSTRAINT title_not_empty CHECK (char_length(title) >= 3) ); -- Criar índices para melhor performance CREATE INDEX IF NOT EXISTS idx_tasks_user_id ON public.tasks(user_id); CREATE INDEX IF NOT EXISTS idx_tasks_completed ON public.tasks(completed); CREATE INDEX IF NOT EXISTS idx_tasks_created_at ON public.tasks(created_at DESC); CREATE INDEX IF NOT EXISTS idx_tasks_due_date ON public.tasks(due_date); CREATE INDEX IF NOT EXISTS idx_tasks_user_completed ON public.tasks(user_id, completed); -- ============================================================================ -- 2️⃣ HABILITAR RLS (Row Level Security) -- ============================================================================ -- Ativar RLS na tabela ALTER TABLE public.tasks ENABLE ROW LEVEL SECURITY; -- ============================================================================ -- 3️⃣ CRIAR POLÍTICAS DE SEGURANÇA -- ============================================================================ -- ✅ Política 1: Usuários podem ver apenas suas próprias tarefas (SELECT) CREATE POLICY "Users can view their own tasks" ON public.tasks FOR SELECT USING (auth.uid() = user_id); -- ✅ Política 2: Usuários podem inserir tarefas apenas para si mesmos (INSERT) CREATE POLICY "Users can create their own tasks" ON public.tasks FOR INSERT WITH CHECK (auth.uid() = user_id); -- ✅ Política 3: Usuários podem atualizar apenas suas próprias tarefas (UPDATE) CREATE POLICY "Users can update their own tasks" ON public.tasks FOR UPDATE USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id); -- ✅ Política 4: Usuários podem deletar apenas suas próprias tarefas (DELETE) CREATE POLICY "Users can delete their own tasks" ON public.tasks FOR DELETE USING (auth.uid() = user_id); -- ============================================================================ -- 4️⃣ CRIAR FUNÇÃO PARA ATUALIZAR updated_at (TRIGGER) -- ============================================================================ -- Criar função que atualiza o campo updated_at automaticamente CREATE OR REPLACE FUNCTION public.update_tasks_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; -- Criar trigger que dispara a função antes de atualizar DROP TRIGGER IF EXISTS trigger_update_tasks_updated_at ON public.tasks; CREATE TRIGGER trigger_update_tasks_updated_at BEFORE UPDATE ON public.tasks FOR EACH ROW EXECUTE FUNCTION public.update_tasks_updated_at(); -- ============================================================================ -- 5️⃣ CRIAR TIPOS (TypeScript Integration) -- ============================================================================ -- Comentários para documentação e integração com TypeScript COMMENT ON TABLE public.tasks IS 'Tabela de tarefas com Row Level Security habilitado'; COMMENT ON COLUMN public.tasks.id IS 'UUID único da tarefa (auto-gerado)'; COMMENT ON COLUMN public.tasks.user_id IS 'UUID do usuário proprietário da tarefa'; COMMENT ON COLUMN public.tasks.title IS 'Título da tarefa (obrigatório, 3-255 caracteres)'; COMMENT ON COLUMN public.tasks.description IS 'Descrição detalhada (opcional, até 2000 caracteres)'; COMMENT ON COLUMN public.tasks.completed IS 'Flag indicando se tarefa está concluída'; COMMENT ON COLUMN public.tasks.due_date IS 'Data/hora de vencimento da tarefa'; COMMENT ON COLUMN public.tasks.category IS 'Categoria para organização (ex: trabalho, pessoal)'; COMMENT ON COLUMN public.tasks.priority IS 'Prioridade: low, medium, high'; COMMENT ON COLUMN public.tasks.created_at IS 'Timestamp de criação (auto-preenchido)'; COMMENT ON COLUMN public.tasks.updated_at IS 'Timestamp da última atualização (auto-preenchido)'; -- ============================================================================ -- 6️⃣ VERIFICAÇÃO - QUERYS PARA TESTAR -- ============================================================================ -- 🧪 TESTE 1: Verificar se RLS está ativado -- SELECT schemaname, tablename, rowsecurity -- FROM pg_tables -- WHERE tablename = 'tasks'; -- Esperado: rowsecurity = true -- 🧪 TESTE 2: Listar todas as políticas -- SELECT tablename, policyname, qual, with_check -- FROM pg_policies -- WHERE tablename = 'tasks'; -- Esperado: 4 políticas -- 🧪 TESTE 3: Testar isolamento (executar como usuário autenticado) -- SELECT * FROM tasks; -- Mostra apenas tarefas do usuário atual -- INSERT INTO tasks (user_id, title) VALUES (auth.uid(), 'Nova tarefa'); -- UPDATE tasks SET completed = true WHERE id = '...'; -- DELETE FROM tasks WHERE id = '...'; -- ============================================================================ -- 🎯 RESUMO DAS POLÍTICAS RLS -- ============================================================================ -- ┌─────────┬────────────────────────────────────────────┐ -- │ AÇÃO │ PERMISSÃO │ -- ├─────────┼────────────────────────────────────────────┤ -- │ SELECT │ ✅ Ver tarefas próprias │ -- │ INSERT │ ✅ Criar tarefas com user_id próprio │ -- │ UPDATE │ ✅ Atualizar apenas tarefas próprias │ -- │ DELETE │ ✅ Deletar apenas tarefas próprias │ -- │ ADMIN │ ✅ Admin pode sem RLS (role: service_role)│ -- └─────────┴────────────────────────────────────────────┘ -- ============================================================================ -- 📚 REFERÊNCIAS -- ============================================================================ -- - Supabase RLS: https://supabase.com/docs/guides/auth/row-level-security -- - PostgreSQL Triggers: https://www.postgresql.org/docs/current/sql-createtrigger.html -- - JWT Claims: https://supabase.com/docs/guides/auth/jwts -- - Índices PostgreSQL: https://www.postgresql.org/docs/current/sql-createindex.html