Files
2026-03-14 19:45:08 -03:00

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 Request para token inválido ou expirado
  • 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_hash via user_repo.update()
    • Invalidar token após uso

Bloqueadores das features de Auth acima

  • Migration: password_reset_tokens

    CREATE 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_tokens

    CREATE 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)

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 aud claim (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 Unauthorized se o aud não corresponder
    • Sem isso, qualquer Google token válido de qualquer app é aceito
  • Logout: invalidar refresh token (src/adapters/inbound/auth_handler.rs:121)

    • Atualmente retorna 204 No Content sem nenhuma ação
    • Opção A (simples): tabela revoked_tokens no PostgreSQL com TTL via expires_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

Baixo — Qualidade e Completude

  • Sort de filamentos não aplicado (src/adapters/outbound/postgres_filament_repo.rs)

    • SortOrder enum está definido em ports/filament_repository.rs
    • SQL em list() sempre usa ORDER BY created_at DESC, ignorando o campo sort
    • filament_handler.rs:203 tem // TODO: parse sort string para SortOrder — completar o parse
    • Aplicar o SortOrder no 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 é chamado
    • list_filaments_handler nã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 com repo.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_handler ou remover a rota do router
  • 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::test para 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/