Integração backend da fila de negativação
TLDR: job diário popula
registry_negativationscom debits elegíveis; GET endpoint lista o registry; frontend conectado ao backend sem mocks.
Contexto
O frontend da fila de negativação (branch feat/negativation) está completo visualmente mas 100% mockado. No backend, RegistryNegativation foi criado mas não é populado por nenhum processo ainda.
A regra de negócio está em .project/docs/rules/collections/credit_bureau_listing.md (R-003).
Objetivos
- Criar
NegativationQueueJob(ActiveJob) que roda diariamente às 01:00 e popularegistry_negativationscom os debits elegíveis - Configurar
solid_queuepara scheduling viaconfig/recurring.yml - Refatorar
GET /api/v1/negativation/queuepara ler deregistry_negativations(não derivar em tempo real) - Criar seed de integração cobrindo os 3 estados do frontend
- Substituir os mocks do frontend por chamadas reais ao backend
Fora de escopo
- Chamada real à API do Asaas/Serasa —
gateway_reffica nullable - Endpoints de execução manual (POST) e remoção (DELETE)
- Webhook de reconciliação pós-pagamento (RN-NEG-5)
- Exceção do 2º reparcelamento (RN-NEG-2)
Arquitetura
``` [01:00 AM] NegativationQueueJob ↓ avalia elegibilidade (RN-NEG-1) ↓ cria/atualiza RegistryNegativation por debit elegível ↓ status: pending
GET /api/v1/negativation/queue ↓ lê registry_negativations com status pending|negative|closed ↓ serializa uma linha por product_debit → frontend ```
Regras de negócio aplicadas
Da R-003:
- RN-NEG-1: elegível =
product_debit.consumer_progress > 25Einstallments overdue/defaulted >= 3no mesmodebit
Status do RegistryNegativation:
| status | significado |
|---|---|
pending |
elegível, ainda não executado no Asaas |
negative |
negativado no Asaas/Serasa |
closed |
removido do bureau (dívida paga) |
cancelled |
processo cancelado antes da execução |
Status derivado para o frontend:
registry_negativation.status |
campo status no payload |
|---|---|
pending |
pending |
negative + installments overdue |
negativated |
negative + sem installments overdue |
eligible_for_removal |
Agregação por cliente: installments e amount somam todas as parcelas overdue do cliente. Um cliente com 2 cursos aparece em 2 linhas com os mesmos totais.
Mudanças
modules/backend/Gemfile (modificar)
Adicionar gem "solid_queue".
modules/backend/config/recurring.yml (novo)
yaml
negativation_queue_job:
class: NegativationQueueJob
schedule: every day at 1am
modules/backend/app/jobs/negativation_queue_job.rb (novo)
Job que avalia elegibilidade e cria/atualiza registry_negativations:
- Busca debits com consumer_progress > 25 e >= 3 installments overdue/defaulted
- Para cada debit elegível, faz find_or_create_by!(debit: debit) no registry com status: :pending
- Debits que saíram da elegibilidade não são removidos do registry (auditoria)
modules/backend/app/controllers/api/v1/negativation_controller.rb (modificar)
Substituir Negativation::FetchQueue.call por query direta em RegistryNegativation:
ruby
RegistryNegativation
.where.not(status: :cancelled)
.includes(debit: [:customer, :installments, :product_debits, :user])
modules/backend/app/use_cases/negativation/fetch_queue.rb (deletar)
Lógica migrada para o job. Endpoint passa a ler do registry.
modules/backend/db/seeds/negativation.rb (novo)
Seed com dados cobrindo os 3 estados — cria debits + RegistryNegativation correspondentes.
modules/frontend/src/services/negativation.ts (modificar)
Substituir mock por apiFetch('/api/v1/negativation/queue'). ✅ já feito.
modules/frontend/src/mocks/creditBlacklist.ts (deletar)
Não será mais usado.
Como verificar
NegativationQueueJob.perform_nowpopularegistry_negativationsGET /api/v1/negativation/queueretorna a fila lendo do registry- Cliente com
consumer_progress <= 25não aparece - Cliente com < 3 installments overdue não aparece
- Cliente com 2 cursos aparece em 2 linhas com os mesmos totais
- Frontend exibe dados reais sem imports de mocks
Documentação
Nenhuma mudança necessária — R-003 já documenta as regras aplicadas.