docs(rls): Add SQL script and RLS setup guide - Tasks table with Row Level Security

This commit is contained in:
Erik Silva
2025-12-01 01:36:57 -03:00
parent 6a73cce6c3
commit 20fb631c9d
3 changed files with 549 additions and 85 deletions

View File

@@ -0,0 +1,160 @@
-- ============================================================================
-- 📊 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