docs(rls): Add SQL script and RLS setup guide - Tasks table with Row Level Security
This commit is contained in:
201
backend-api/RLS_SETUP_GUIDE.md
Normal file
201
backend-api/RLS_SETUP_GUIDE.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# 🔐 Implementar RLS no Supabase - Guia Passo a Passo
|
||||||
|
|
||||||
|
## 📌 O que é RLS (Row Level Security)?
|
||||||
|
|
||||||
|
Row Level Security é um mecanismo de segurança no PostgreSQL que permite controlar qual linhas de dados cada usuário pode acessar. No nosso caso, garante que:
|
||||||
|
|
||||||
|
✅ **Usuário A** pode ver/editar apenas suas tarefas
|
||||||
|
✅ **Usuário B** pode ver/editar apenas suas tarefas
|
||||||
|
❌ **Usuário A NÃO** consegue acessar tarefas de **Usuário B**
|
||||||
|
|
||||||
|
## 🚀 Como Implementar no Supabase
|
||||||
|
|
||||||
|
### Passo 1: Acessar o SQL Editor do Supabase
|
||||||
|
|
||||||
|
1. Vá para [https://supabase.com/dashboard](https://supabase.com/dashboard)
|
||||||
|
2. Selecione seu projeto **"todolist-fullstack"**
|
||||||
|
3. No menu lateral, clique em **SQL Editor**
|
||||||
|
4. Clique em **New Query**
|
||||||
|
|
||||||
|
### Passo 2: Copiar o Script SQL
|
||||||
|
|
||||||
|
1. Abra o arquivo: `backend-api/SQL_TASKS_TABLE_RLS.sql`
|
||||||
|
2. Copie todo o conteúdo
|
||||||
|
3. Cole no editor SQL do Supabase
|
||||||
|
|
||||||
|
### Passo 3: Executar o Script
|
||||||
|
|
||||||
|
1. Clique no botão **▶️ RUN** (canto inferior direito)
|
||||||
|
2. Aguarde a execução completar (deve levar 2-5 segundos)
|
||||||
|
3. Verifique se não houve erros (aparecerá "Successfully" em verde)
|
||||||
|
|
||||||
|
### Passo 4: Verificar a Tabela Criada
|
||||||
|
|
||||||
|
1. Vá para **Database** → **Tables** no menu lateral
|
||||||
|
2. Você deve ver a tabela `tasks` listada
|
||||||
|
3. Clique nela para visualizar:
|
||||||
|
- Schema das colunas
|
||||||
|
- Índices criados
|
||||||
|
- Políticas RLS (abas "Row Level Security")
|
||||||
|
|
||||||
|
## 📋 O que o Script Cria
|
||||||
|
|
||||||
|
### 1️⃣ Tabela `tasks`
|
||||||
|
|
||||||
|
| Coluna | Tipo | Descrição |
|
||||||
|
|--------|------|-----------|
|
||||||
|
| `id` | UUID | ID único (auto-gerado) |
|
||||||
|
| `user_id` | UUID | Referência ao usuário (auth.users) |
|
||||||
|
| `title` | VARCHAR(255) | Título obrigatório |
|
||||||
|
| `description` | TEXT | Descrição opcional |
|
||||||
|
| `completed` | BOOLEAN | Status de conclusão |
|
||||||
|
| `due_date` | TIMESTAMP | Data de vencimento |
|
||||||
|
| `category` | VARCHAR(50) | Categoria para organização |
|
||||||
|
| `priority` | VARCHAR(20) | low \| medium \| high |
|
||||||
|
| `created_at` | TIMESTAMP | Auto-preenchido |
|
||||||
|
| `updated_at` | TIMESTAMP | Auto-atualizado |
|
||||||
|
|
||||||
|
### 2️⃣ Índices para Performance
|
||||||
|
|
||||||
|
```sql
|
||||||
|
idx_tasks_user_id -- Buscar tarefas por usuário
|
||||||
|
idx_tasks_completed -- Filtrar concluídas/pendentes
|
||||||
|
idx_tasks_created_at -- Ordenar por data de criação
|
||||||
|
idx_tasks_due_date -- Ordenar por vencimento
|
||||||
|
idx_tasks_user_completed -- Query combinada (comum)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3️⃣ Row Level Security (RLS) - 4 Políticas
|
||||||
|
|
||||||
|
#### ✅ SELECT - Ver tarefas próprias
|
||||||
|
```sql
|
||||||
|
auth.uid() = user_id
|
||||||
|
```
|
||||||
|
Usuário vê apenas suas tarefas.
|
||||||
|
|
||||||
|
#### ✅ INSERT - Criar tarefas próprias
|
||||||
|
```sql
|
||||||
|
auth.uid() = user_id
|
||||||
|
```
|
||||||
|
Usuário só consegue inserir tarefa com seu `user_id`.
|
||||||
|
|
||||||
|
#### ✅ UPDATE - Editar tarefas próprias
|
||||||
|
```sql
|
||||||
|
auth.uid() = user_id
|
||||||
|
```
|
||||||
|
Usuário só consegue atualizar suas tarefas.
|
||||||
|
|
||||||
|
#### ✅ DELETE - Deletar tarefas próprias
|
||||||
|
```sql
|
||||||
|
auth.uid() = user_id
|
||||||
|
```
|
||||||
|
Usuário só consegue deletar suas tarefas.
|
||||||
|
|
||||||
|
### 4️⃣ Trigger para `updated_at`
|
||||||
|
|
||||||
|
Atualiza o campo `updated_at` automaticamente toda vez que uma tarefa é modificada.
|
||||||
|
|
||||||
|
## 🧪 Testar a Implementação
|
||||||
|
|
||||||
|
### Teste 1: Verificar RLS Ativado
|
||||||
|
|
||||||
|
No SQL Editor, execute:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT schemaname, tablename, rowsecurity
|
||||||
|
FROM pg_tables
|
||||||
|
WHERE tablename = 'tasks';
|
||||||
|
```
|
||||||
|
|
||||||
|
**Esperado:**
|
||||||
|
```
|
||||||
|
schemaname | tablename | rowsecurity
|
||||||
|
----------|-----------|-----------
|
||||||
|
public | tasks | true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Teste 2: Listar Políticas RLS
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT tablename, policyname
|
||||||
|
FROM pg_policies
|
||||||
|
WHERE tablename = 'tasks'
|
||||||
|
ORDER BY policyname;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Esperado:**
|
||||||
|
```
|
||||||
|
tablename | policyname
|
||||||
|
-----------|------------------------------------------
|
||||||
|
tasks | Users can create their own tasks
|
||||||
|
tasks | Users can delete their own tasks
|
||||||
|
tasks | Users can update their own tasks
|
||||||
|
tasks | Users can view their own tasks
|
||||||
|
```
|
||||||
|
|
||||||
|
### Teste 3: Testar Isolamento (via Supabase Dashboard)
|
||||||
|
|
||||||
|
1. Vá para **Authentication** → **Users** no dashboard
|
||||||
|
2. Crie 2 usuários de teste:
|
||||||
|
- `user1@test.com` / `password123`
|
||||||
|
- `user2@test.com` / `password123`
|
||||||
|
|
||||||
|
3. Autentique como `user1` no frontend
|
||||||
|
4. Crie uma tarefa para `user1`
|
||||||
|
5. Autentique como `user2` no frontend
|
||||||
|
6. Verifique que `user2` NÃO consegue ver a tarefa de `user1`
|
||||||
|
|
||||||
|
## ⚠️ Troubleshooting
|
||||||
|
|
||||||
|
### "Error: relation tasks does not exist"
|
||||||
|
- Verifique se você copiou o script inteiro
|
||||||
|
- Certifique-se de executar o script completo de uma vez
|
||||||
|
|
||||||
|
### "Error: policy already exists"
|
||||||
|
- Você está executando o script duas vezes
|
||||||
|
- Solução: Execute apenas uma vez ou delete as políticas primeiro
|
||||||
|
|
||||||
|
### RLS não está funcionando
|
||||||
|
- Verifique se RLS está **habilitado** (não desabilitado)
|
||||||
|
- Confirme que o `user_id` na tabela corresponde ao `auth.uid()` do usuário autenticado
|
||||||
|
|
||||||
|
## 🔗 Integração com Backend (NestJS)
|
||||||
|
|
||||||
|
O TasksService já está preparado para trabalhar com RLS:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// O Supabase valida automaticamente:
|
||||||
|
// - Usuário só acessa suas tarefas (RLS)
|
||||||
|
// - Não consegue inserir tarefa com outro user_id
|
||||||
|
// - Não consegue atualizar/deletar tarefa de outro usuário
|
||||||
|
|
||||||
|
async findAll(userId: string) {
|
||||||
|
const { data, error } = await this.supabaseService
|
||||||
|
.getClient()
|
||||||
|
.from('tasks')
|
||||||
|
.select('*')
|
||||||
|
.eq('user_id', userId); // ← RLS já filtra automaticamente
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Referências Úteis
|
||||||
|
|
||||||
|
- 📖 [Supabase RLS Guide](https://supabase.com/docs/guides/auth/row-level-security)
|
||||||
|
- 🔒 [PostgreSQL Security](https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-RLS)
|
||||||
|
- 🚀 [Best Practices](https://supabase.com/docs/guides/database/basics/best-practices)
|
||||||
|
|
||||||
|
## ✅ Próximos Passos
|
||||||
|
|
||||||
|
Após executar o script SQL:
|
||||||
|
|
||||||
|
1. ✅ Executar SQL no Supabase
|
||||||
|
2. ✅ Verificar tabela criada
|
||||||
|
3. ➡️ **Próximo**: Testar endpoints de tasks via Postman/Insomnia
|
||||||
|
4. ➡️ **Depois**: Implementar Frontend (Next.js)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Status**: 🟡 Aguardando execução manual no Supabase
|
||||||
|
**Responsável**: Você (execute o SQL_TASKS_TABLE_RLS.sql no SQL Editor)
|
||||||
160
backend-api/SQL_TASKS_TABLE_RLS.sql
Normal file
160
backend-api/SQL_TASKS_TABLE_RLS.sql
Normal 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
|
||||||
@@ -1,34 +1,67 @@
|
|||||||
# ✅ PROGRESSO - FASE 1: BACKEND (50% COMPLETO)
|
# ✅ PROGRESSO - FASE 1: BACKEND (70% COMPLETO)
|
||||||
|
|
||||||
**Data Atualização**: 1 de dezembro de 2025 (Sessão 1 Finalizada)
|
**Data Atualização**: 1 de dezembro de 2025 (Sessão 1 em Progresso)
|
||||||
**Última Versão**: v0.1.0 (Initial: Auth + Design System)
|
**Última Versão**: v0.2.0 (Tasks Module + RLS)
|
||||||
**Git Commits**: 2 (35272b8, b51c598)
|
**Git Commits**: 4 (35272b8, b51c598, 58df03d, 6a73cce)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎯 Progresso Geral
|
## 🎯 Progresso Geral
|
||||||
|
|
||||||
```
|
```
|
||||||
Fase 1: Backend [████████████░░░░░░░░░░░░] 50% ✅
|
Fase 1: Backend [██████████████████░░░░░░░░] 70% ✅
|
||||||
├─ Setup [████████████████████░] 100% ✅
|
├─ Setup [████████████████████░] 100% ✅
|
||||||
├─ Auth Module [████████████████████░] 100% ✅
|
├─ Auth Module [████████████████████░] 100% ✅
|
||||||
├─ Tasks Module [░░░░░░░░░░░░░░░░░░░░░] 0%
|
├─ Tasks Module [████████████████████░] 100% ✅
|
||||||
├─ RLS Supabase [░░░░░░░░░░░░░░░░░░░░░] 0%
|
├─ RLS Supabase [██████████████░░░░░░░] 75% 🟡
|
||||||
├─ API Docs [████████████░░░░░░░░░] 60%
|
├─ API Docs [████████████████████░] 100% ✅
|
||||||
└─ Dockerfile [░░░░░░░░░░░░░░░░░░░░░] 0%
|
└─ Dockerfile [░░░░░░░░░░░░░░░░░░░░░] 0%
|
||||||
|
|
||||||
Fase 2: Frontend [░░░░░░░░░░░░░░░░░░░░░] 0%
|
Fase 2: Frontend [░░░░░░░░░░░░░░░░░░░░░] 0%
|
||||||
Fase 3: Mobile [░░░░░░░░░░░░░░░░░░░░░] 0%
|
Fase 3: Mobile [░░░░░░░░░░░░░░░░░░░░░] 0%
|
||||||
Fase 4: DevOps/Deploy [░░░░░░░░░░░░░░░░░░░░░] 0%
|
Fase 4: DevOps/Deploy [░░░░░░░░░░░░░░░░░░░░░] 0%
|
||||||
|
|
||||||
TOTAL [████░░░░░░░░░░░░░░░░░░░░] 12%
|
TOTAL [████████░░░░░░░░░░░░░░░░░] 17%
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📋 O QUE FOI IMPLEMENTADO
|
## 📋 O QUE FOI IMPLEMENTADO
|
||||||
|
|
||||||
**Dependências Instaladas**:
|
**Commit 1 - Initial Setup**:
|
||||||
|
- ✅ 49 dependências instaladas
|
||||||
|
- ✅ Configuração centralizada (ConfigModule)
|
||||||
|
- ✅ Auth Module completo (JWT + Supabase)
|
||||||
|
- ✅ Design System documentado
|
||||||
|
|
||||||
|
**Commit 2 - Documentation Reorganization**:
|
||||||
|
- ✅ Documentação movida para `docs/ia/`
|
||||||
|
- ✅ Roadmap e Progresso criados
|
||||||
|
|
||||||
|
**Commit 3 - Roadmap Update**:
|
||||||
|
- ✅ ROADMAP_EXECUCAO.md com todos os 4 fases
|
||||||
|
- ✅ PROGRESSO.md atualizado para 50%
|
||||||
|
|
||||||
|
**Commit 4 - Tasks Module** (NOVO):
|
||||||
|
- ✅ `tasks.service.ts` com 6 métodos (CRUD + stats)
|
||||||
|
- ✅ `tasks.controller.ts` com 6 endpoints protegidos
|
||||||
|
- ✅ `create-task.dto.ts` com validações
|
||||||
|
- ✅ `update-task.dto.ts` para PATCH
|
||||||
|
- ✅ `tasks.module.ts` integrado ao app.module.ts
|
||||||
|
- ✅ API.md atualizado com todos endpoints
|
||||||
|
|
||||||
|
**Commit 4 (Preparando) - RLS Setup**:
|
||||||
|
- ✅ `SQL_TASKS_TABLE_RLS.sql` - Script completo com:
|
||||||
|
- Criação da tabela `tasks` com schema completo
|
||||||
|
- Índices para performance (5 índices)
|
||||||
|
- Row Level Security (4 políticas)
|
||||||
|
- Trigger automático para `updated_at`
|
||||||
|
- Comentários e documentação inline
|
||||||
|
- ✅ `RLS_SETUP_GUIDE.md` - Guia passo a passo:
|
||||||
|
- Como executar no Supabase SQL Editor
|
||||||
|
- Como testar RLS
|
||||||
|
- Troubleshooting
|
||||||
|
- Integração com backend
|
||||||
- ✅ `@supabase/supabase-js` - Cliente Supabase
|
- ✅ `@supabase/supabase-js` - Cliente Supabase
|
||||||
- ✅ `@nestjs/config` - Configuração centralizada
|
- ✅ `@nestjs/config` - Configuração centralizada
|
||||||
- ✅ `@nestjs/jwt` - JWT para autenticação
|
- ✅ `@nestjs/jwt` - JWT para autenticação
|
||||||
@@ -73,42 +106,87 @@ backend-api/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ✅ Passo 1.2: Módulo de Autenticação (COMPLETO)
|
### ✅ Passo 1.3: Módulo de Tarefas (COMPLETO) - NOVO
|
||||||
|
|
||||||
**Implementado**:
|
**Implementado**:
|
||||||
|
|
||||||
#### Auth Service (`auth.service.ts`)
|
#### Tasks Service (`tasks.service.ts`)
|
||||||
- ✅ `signup()` - Registrar usuário
|
- ✅ `create(userId, createTaskDto)` - Criar tarefa
|
||||||
- ✅ `login()` - Fazer login
|
- ✅ `findAll(userId, filters)` - Listar com filtros
|
||||||
- ✅ `logout()` - Fazer logout
|
- ✅ `findOne(id, userId)` - Obter tarefa específica
|
||||||
- ✅ `validateToken()` - Validar JWT
|
- ✅ `update(id, userId, updateTaskDto)` - Atualizar tarefa
|
||||||
- ✅ `requestPasswordReset()` - Recuperar senha
|
- ✅ `remove(id, userId)` - Deletar tarefa
|
||||||
- ✅ `generateToken()` - Gerar JWT
|
- ✅ `getStats(userId)` - Obter estatísticas
|
||||||
|
|
||||||
#### Auth Controller (`auth.controller.ts`)
|
#### Tasks Controller (`tasks.controller.ts`)
|
||||||
- ✅ `POST /auth/signup` - Registrar
|
- ✅ `POST /tasks` - Criar tarefa
|
||||||
- ✅ `POST /auth/login` - Login
|
- ✅ `GET /tasks` - Listar com query filters
|
||||||
- ✅ `POST /auth/logout` - Logout
|
- ✅ `GET /tasks/stats` - Estatísticas
|
||||||
- ✅ `GET /auth/me` - Perfil atual
|
- ✅ `GET /tasks/:id` - Obter tarefa
|
||||||
- ✅ `POST /auth/forgot-password` - Recuperar senha
|
- ✅ `PATCH /tasks/:id` - Atualizar tarefa
|
||||||
|
- ✅ `DELETE /tasks/:id` - Deletar tarefa
|
||||||
|
|
||||||
|
#### DTOs e Validações
|
||||||
|
- ✅ `CreateTaskDto` - title (obrigatório), description, dueDate, category, priority, completed
|
||||||
|
- ✅ `UpdateTaskDto` - Todos campos opcionais (PATCH)
|
||||||
|
- ✅ Validação com class-validator (min/max length, tipos)
|
||||||
|
|
||||||
#### Segurança
|
#### Segurança
|
||||||
- ✅ JWT Strategy - Extração e validação de tokens
|
- ✅ Todos endpoints protegidos com `@UseGuards(JwtAuthGuard)`
|
||||||
- ✅ JWT Guard - Proteção de rotas
|
- ✅ Injeção automática de `userId` via `@CurrentUser()`
|
||||||
- ✅ CurrentUser Decorator - Injeção do usuário autenticado
|
- ✅ Validação de propriedade (usuário só acessa suas tarefas)
|
||||||
- ✅ Validação de DTOs com class-validator
|
|
||||||
|
#### Features
|
||||||
|
- ✅ Filtros: completed, category, priority
|
||||||
|
- ✅ Ordenação: sortBy (created_at, due_date, priority), order (asc/desc)
|
||||||
|
- ✅ Resposta estruturada com success, message, data
|
||||||
|
- ✅ Tratamento de erros (BadRequestException, NotFoundException)
|
||||||
|
|
||||||
|
### 🟡 Passo 1.4: RLS no Supabase (75% COMPLETO) - NOVO
|
||||||
|
|
||||||
|
**Implementado**:
|
||||||
|
|
||||||
|
#### SQL Script (`SQL_TASKS_TABLE_RLS.sql`)
|
||||||
|
- ✅ Criar tabela `tasks` com schema completo:
|
||||||
|
- id, user_id, title, description, completed, due_date, category, priority
|
||||||
|
- created_at, updated_at com timestamps
|
||||||
|
- ✅ Criar 5 índices para performance:
|
||||||
|
- idx_tasks_user_id
|
||||||
|
- idx_tasks_completed
|
||||||
|
- idx_tasks_created_at
|
||||||
|
- idx_tasks_due_date
|
||||||
|
- idx_tasks_user_completed
|
||||||
|
- ✅ Habilitar RLS na tabela
|
||||||
|
- ✅ Criar 4 políticas de segurança:
|
||||||
|
- SELECT: Ver apenas tarefas próprias
|
||||||
|
- INSERT: Criar apenas com user_id próprio
|
||||||
|
- UPDATE: Atualizar apenas tarefas próprias
|
||||||
|
- DELETE: Deletar apenas tarefas próprias
|
||||||
|
- ✅ Criar trigger automático para updated_at
|
||||||
|
- ✅ Adicionar comments SQL para documentação
|
||||||
|
|
||||||
|
#### Setup Guide (`RLS_SETUP_GUIDE.md`)
|
||||||
|
- ✅ Passo a passo para executar no Supabase
|
||||||
|
- ✅ Explicação detalhada das políticas RLS
|
||||||
|
- ✅ 3 testes para validar implementação
|
||||||
|
- ✅ Troubleshooting e soluções de erros
|
||||||
|
- ✅ Referências e próximos passos
|
||||||
|
|
||||||
|
**Pendente (5%)**:
|
||||||
|
- ❌ Executar script no Supabase SQL Editor (manual)
|
||||||
|
- ❌ Testar isolamento de dados entre usuários
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📊 Progresso Visual
|
## 📊 Progresso Visual
|
||||||
|
|
||||||
```
|
```
|
||||||
Fase 1: Backend [████████████░░░░░░░░░░░░] 50%
|
Fase 1: Backend [██████████████████░░░░░░░░] 70%
|
||||||
├─ Setup [████████████████████░] 100% ✅
|
├─ Setup [████████████████████░] 100% ✅
|
||||||
├─ Auth Module [████████████████████░] 100% ✅
|
├─ Auth Module [████████████████████░] 100% ✅
|
||||||
├─ Tasks Module [░░░░░░░░░░░░░░░░░░░░░] 0%
|
├─ Tasks Module [████████████████████░] 100% ✅
|
||||||
├─ RLS Supabase [░░░░░░░░░░░░░░░░░░░░░] 0%
|
├─ RLS Supabase [██████████████░░░░░░░] 75% 🟡
|
||||||
├─ API Docs [████████████░░░░░░░░░] 60%
|
├─ API Docs [████████████████████░] 100% ✅
|
||||||
└─ Dockerfile [░░░░░░░░░░░░░░░░░░░░░] 0%
|
└─ Dockerfile [░░░░░░░░░░░░░░░░░░░░░] 0%
|
||||||
|
|
||||||
Fase 2: Frontend [░░░░░░░░░░░░░░░░░░░░░] 0%
|
Fase 2: Frontend [░░░░░░░░░░░░░░░░░░░░░] 0%
|
||||||
@@ -169,91 +247,116 @@ NestJS Backend Architecture
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📝 Próximas Ações (Passo 3)
|
## 📝 Próximas Ações
|
||||||
|
|
||||||
### Passo 1.3: Módulo de Tarefas
|
### Passo 1.4: RLS no Supabase (MANUAL)
|
||||||
- [ ] Criar `tasks.service.ts` com CRUD
|
1. ✅ Script SQL criado (`SQL_TASKS_TABLE_RLS.sql`)
|
||||||
- [ ] Criar `tasks.controller.ts` com endpoints
|
2. ✅ Guia de setup criado (`RLS_SETUP_GUIDE.md`)
|
||||||
- [ ] Criar DTOs (create-task, update-task)
|
3. ➡️ **AÇÃO NECESSÁRIA**: Você deve executar o script no Supabase SQL Editor:
|
||||||
- [ ] Integrar com Supabase (query builder)
|
- Acesse [Supabase Dashboard](https://supabase.com/dashboard)
|
||||||
- [ ] Adicionar validações
|
- Vá para SQL Editor
|
||||||
|
- Cole o conteúdo de `SQL_TASKS_TABLE_RLS.sql`
|
||||||
|
- Clique em RUN
|
||||||
|
|
||||||
### Passo 1.4: RLS no Supabase
|
### Passo 1.5: Testar Endpoints de Tasks
|
||||||
- [ ] Criar tabela `tasks` no Supabase
|
- [ ] Testar CRUD via Postman/Insomnia
|
||||||
- [ ] Implementar RLS policies
|
- [ ] Validar filtros e ordenação
|
||||||
- [ ] Testar isolamento de dados
|
- [ ] Verificar isolamento RLS entre usuários
|
||||||
|
|
||||||
### Passo 1.5: Completar Documentação
|
|
||||||
- [ ] Adicionar endpoints de Tasks
|
|
||||||
- [ ] Exemplos de uso (cURL)
|
|
||||||
- [ ] Erros documentados
|
|
||||||
|
|
||||||
### Passo 1.6: Dockerfile
|
### Passo 1.6: Dockerfile
|
||||||
- [ ] Criar Dockerfile
|
- [ ] Criar Dockerfile para backend
|
||||||
|
- [ ] Criar docker-compose.yml
|
||||||
- [ ] Testar containerização
|
- [ ] Testar containerização
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧪 Como Testar Agora
|
## 🧪 Como Testar Agora
|
||||||
|
|
||||||
### 1. Configurar .env
|
### 1. Executar RLS Script no Supabase (PENDENTE)
|
||||||
```bash
|
```
|
||||||
cp backend-api/.env.example backend-api/.env
|
1. Vá para: https://supabase.com/dashboard
|
||||||
# Editar com suas credenciais Supabase
|
2. SQL Editor → New Query
|
||||||
|
3. Cole: backend-api/SQL_TASKS_TABLE_RLS.sql
|
||||||
|
4. Clique: RUN
|
||||||
|
5. Verifique: Sem erros vermelhos
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Rodar em desenvolvimento
|
### 2. Testar Tasks Endpoints com cURL
|
||||||
|
```bash
|
||||||
|
# Criar tarefa
|
||||||
|
curl -X POST http://localhost:3000/api/tasks \
|
||||||
|
-H "Authorization: Bearer {token}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"title":"Fazer compras","priority":"high"}'
|
||||||
|
|
||||||
|
# Listar tarefas
|
||||||
|
curl -X GET "http://localhost:3000/api/tasks?completed=false&sortBy=due_date" \
|
||||||
|
-H "Authorization: Bearer {token}"
|
||||||
|
|
||||||
|
# Obter estatísticas
|
||||||
|
curl -X GET http://localhost:3000/api/tasks/stats \
|
||||||
|
-H "Authorization: Bearer {token}"
|
||||||
|
|
||||||
|
# Atualizar tarefa
|
||||||
|
curl -X PATCH http://localhost:3000/api/tasks/{id} \
|
||||||
|
-H "Authorization: Bearer {token}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"completed":true}'
|
||||||
|
|
||||||
|
# Deletar tarefa
|
||||||
|
curl -X DELETE http://localhost:3000/api/tasks/{id} \
|
||||||
|
-H "Authorization: Bearer {token}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Rodar Backend em Desenvolvimento
|
||||||
```bash
|
```bash
|
||||||
cd backend-api
|
cd backend-api
|
||||||
npm run start:dev
|
npm run start:dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Testar endpoints com cURL
|
|
||||||
```bash
|
|
||||||
# Signup
|
|
||||||
curl -X POST http://localhost:3000/api/auth/signup \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"email":"test@example.com","password":"Test123456"}'
|
|
||||||
|
|
||||||
# Login
|
|
||||||
curl -X POST http://localhost:3000/api/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"email":"test@example.com","password":"Test123456"}'
|
|
||||||
|
|
||||||
# Get Profile (com token)
|
|
||||||
curl -X GET http://localhost:3000/api/auth/me \
|
|
||||||
-H "Authorization: Bearer {seu_token}"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📚 Arquivos Documentados
|
## 📚 Arquivos Documentados
|
||||||
|
|
||||||
- ✅ `API.md` - Documentação completa dos endpoints
|
- ✅ `API.md` - Documentação completa dos endpoints (Auth + Tasks)
|
||||||
- ✅ `ROADMAP_EXECUCAO.md` - Plano de execução
|
- ✅ `ROADMAP_EXECUCAO.md` - Plano de execução para 4 fases
|
||||||
- ✅ `.env.example` - Template de variáveis
|
- ✅ `.env.example` - Template de variáveis
|
||||||
|
- ✅ `SQL_TASKS_TABLE_RLS.sql` - Script SQL com RLS (NOVO)
|
||||||
|
- ✅ `RLS_SETUP_GUIDE.md` - Guia passo a passo RLS (NOVO)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 💡 O que você aprendeu nesta sessão
|
## 💡 O que você aprendeu nesta sessão
|
||||||
|
|
||||||
1. **Estrutura NestJS** - Módulos, Controllers, Services, Guards
|
**Sessão 1 - Backend Core**:
|
||||||
2. **Autenticação com JWT** - Token generation, validation, protection
|
1. Estrutura NestJS - Módulos, Controllers, Services, Guards
|
||||||
3. **Integração Supabase** - Client setup, user creation
|
2. Autenticação com JWT - Token generation, validation, protection
|
||||||
4. **Validação de DTOs** - class-validator, class-transformer
|
3. Integração Supabase - Client setup, user creation, queries
|
||||||
5. **Decoradores** - @Controller, @UseGuards, @CurrentUser
|
4. Validação de DTOs - class-validator, class-transformer
|
||||||
6. **ConfigModule** - Gerenciamento de variáveis de ambiente com Joi
|
5. Decoradores - @Controller, @UseGuards, @CurrentUser
|
||||||
7. **Arquitetura em camadas** - Separação de responsabilidades
|
6. ConfigModule - Gerenciamento de variáveis com Joi
|
||||||
|
7. Arquitetura em camadas - Separação de responsabilidades
|
||||||
|
8. **NOVO**: CRUD com Supabase - Create, Read, Update, Delete
|
||||||
|
9. **NOVO**: Query Filters - Filtros dinâmicos, ordenação
|
||||||
|
10. **NOVO**: Row Level Security - Isolamento de dados por usuário
|
||||||
|
11. **NOVO**: PostgreSQL Triggers - Atualização automática de timestamps
|
||||||
|
12. **NOVO**: Database Indexing - Performance optimization
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 Próximas Sessões Planejadas
|
## 🚀 Próximas Sessões Planejadas
|
||||||
|
|
||||||
1. **Hoje**: Implementar Módulo de Tarefas (Passo 1.3)
|
1. **Hoje**:
|
||||||
2. **Hoje/Amanhã**: RLS no Supabase (Passo 1.4)
|
- ✅ Implementar Módulo de Tarefas (Passo 1.3)
|
||||||
3. **Amanhã**: Dockerfile (Passo 1.6)
|
- ✅ Preparar RLS Supabase (Passo 1.4)
|
||||||
4. **Depois**: Frontend Next.js (Fase 2)
|
- ➡️ Executar SQL no Supabase (MANUAL)
|
||||||
|
- ➡️ Testar isolamento RLS
|
||||||
|
|
||||||
|
2. **Depois**:
|
||||||
|
- Criar Dockerfile (Passo 1.6)
|
||||||
|
- Iniciar Frontend Next.js (Fase 2)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Status Final**: Backend 50% completo e pronto para integração com frontend! 🎉
|
**Status Final**: Backend 70% completo com Tasks CRUD + RLS docs pronto! 🎉
|
||||||
|
**Ação Necessária**: Execute o SQL script no Supabase para completar RLS (5%)
|
||||||
|
|||||||
Reference in New Issue
Block a user