5.9 KiB
MeowSpool Backend — TODO
Última atualização: 14/03/2026
Crítico — Funcionalidades Quebradas
Auth: Email e Reset de Senha
Todos os três handlers abaixo retornam 200 OK sem executar nenhuma lógica real.
Dependem de infraestrutura compartilhada que ainda não existe (ver "Bloqueadores").
-
forgot_password_handler(src/adapters/inbound/auth_handler.rs:131)- Gerar token de reset seguro (UUID v4 ou CSPRNG)
- Salvar na tabela
password_reset_tokens(ver migration abaixo) - Enviar email com link de reset via serviço de email
- Token deve ter TTL de 1h e ser invalidado após uso
-
verify_email_handler(src/adapters/inbound/auth_handler.rs:138)- Validar token recebido contra tabela
email_verification_tokens - Chamar
user_repo.verify_email(user_id)(método já implementado no repo) - Marcar token como usado / deletar após validação
- Retornar
400 Bad Requestpara token inválido ou expirado
- Validar token recebido contra tabela
-
reset_password_handler(src/adapters/inbound/auth_handler.rs:143)- Validar token recebido contra tabela
password_reset_tokens - Verificar TTL e se já foi usado
- Hash da nova senha com Argon2id
- Atualizar
password_hashviauser_repo.update() - Invalidar token após uso
- Validar token recebido contra tabela
Bloqueadores das features de Auth acima
-
Migration:
password_reset_tokensCREATE TABLE password_reset_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, token TEXT NOT NULL UNIQUE, used_at TIMESTAMPTZ, expires_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX ON password_reset_tokens (token); -
Migration:
email_verification_tokensCREATE TABLE email_verification_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, token TEXT NOT NULL UNIQUE, used_at TIMESTAMPTZ, expires_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX ON email_verification_tokens (token); -
Serviço de email (
src/infrastructure/email_service.rs— novo arquivo)- Adicionar dependência:
lettre(SMTP) ou integração com API (Resend, SendGrid, Mailgun) - Adicionar vars de ambiente no
config.rs:SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASS,EMAIL_FROM - Implementar
send_password_reset_email(to, reset_link) - Implementar
send_verification_email(to, code)
- Adicionar dependência:
Perfil de Usuário
update_me_handler(src/adapters/inbound/user_handler.rs:64)- Handler valida formato de email mas não persiste nada
- Implementar chamada a
user_repo.update()com os campos recebidos - Considerar campos permitidos:
name(se adicionado ao domínio),email - Revalidar unicidade de email antes de atualizar
Médio — Segurança
-
Google OAuth: validar
audclaim (src/adapters/inbound/auth_handler.rs:159)- O parâmetro
_client_idé recebido mas ignorado - Após obter o payload do tokeninfo do Google, verificar que
aud == GOOGLE_CLIENT_ID - Rejeitar com
401 Unauthorizedse oaudnão corresponder - Sem isso, qualquer Google token válido de qualquer app é aceito
- O parâmetro
-
Logout: invalidar refresh token (
src/adapters/inbound/auth_handler.rs:121)- Atualmente retorna
204 No Contentsem nenhuma ação - Opção A (simples): tabela
revoked_tokensno PostgreSQL com TTL viaexpires_at - Opção B (recomendada): Redis com
SET revoked:{jti} 1 EX <ttl> - Middleware de auth deve checar blocklist ao validar tokens
- Adicionar campo
jti(JWT ID) aos tokens para identificação única
- Atualmente retorna
Baixo — Qualidade e Completude
-
Sort de filamentos não aplicado (
src/adapters/outbound/postgres_filament_repo.rs)SortOrderenum está definido emports/filament_repository.rs- SQL em
list()sempre usaORDER BY created_at DESC, ignorando o camposort filament_handler.rs:203tem// TODO: parse sort string para SortOrder— completar o parse- Aplicar o
SortOrderno SQL com match:net_weight_g ASC,net_weight_g DESC,created_at DESC
-
Paginação: retornar total de itens
FilamentRepository::count()está implementado no repo mas nunca é chamadolist_filaments_handlernão retorna metadados de paginação- Adicionar ao response:
{ data: [...], total: N, page: N, per_page: N } - Chamar
repo.count(user_id, filter)em paralelo comrepo.list()
-
GET /spool-presets/:id— handler ausente- Rota está registrada no
router.rs - Nenhum handler correspondente existe em
spool_preset_handler.rs - Implementar
get_preset_handlerou remover a rota do router
- Rota está registrada no
-
Testes
- Sem nenhum teste unitário ou de integração no projeto
- Prioridade:
AuthService(hash, JWT),FilamentService(cálculos de peso, conflito offline), handlers de auth - Usar
sqlx::testpara testes de repositório com banco real em transação
Referência Rápida — Arquivos por Área
| Área | Arquivo |
|---|---|
| Handlers de auth | src/adapters/inbound/auth_handler.rs |
| Handler de usuário | src/adapters/inbound/user_handler.rs |
| Handler de filamentos | src/adapters/inbound/filament_handler.rs |
| Handler de presets | src/adapters/inbound/spool_preset_handler.rs |
| Repo de usuário | src/adapters/outbound/postgres_user_repo.rs |
| Repo de filamentos | src/adapters/outbound/postgres_filament_repo.rs |
| Serviço de auth | src/application/auth_service.rs |
| Config / env vars | src/config.rs |
| Migrations | backend/migrations/ |