CapítuloZero

Plataforma para gestão de Editoras, Parceiros, Clientes, Serviços, Projetos, Pagamentos e Financeiro — conectando editoras a parceiros criativos com checkout integrado e controle de saldos/saques.

📦 Visão geral

Editora

Entidade raiz (tenant). Toda requisição é autenticada pela ApiKey de uma Editora. Possui clientes, parceiros vinculados e projetos.

Cliente

Contratante vinculado a uma editora. Possui vínculo externo (VinculoId) e tipo customizável (Agente/Autor).

Parceiro

Prestador de serviço. Possui catálogo de serviços, saldo bloqueado/disponível, Pix e pode solicitar saques.

Serviço

Oferta de um parceiro com valor, prazo, descrição, exigências e tags. Pode ser ativado ou inativado.

Projeto

Vincula Cliente ↔ Parceiro dentro de uma Editora. Contém itens, pagamento, entregas, conversas e avaliações.

Financeiro

Saldo bloqueado ao iniciar projeto; liberado após aprovação. Checkout via Pagarme v5 (webhook x-hub-signature). Parceiro solicita saque; admin aprova/rejeita e confirma pagamento.

Auditoria

Todos os commands (ITransactionalRequest) geram um AuditLog na tabela AuditLogs com ação, módulo, ator (Editora/Parceiro/Usuário), IP, rota HTTP e resultado (sucesso/falha com erros).

🎨 Módulos da Plataforma

🔗
Padrão de URL: {módulo}/api/{rota} — a API unificada usa MapGroup() para criar grupos de rota por módulo. Exemplo: parceiro/api/parceiro/auth/login é tratado diretamente pelo grupo /parceiro sem proxy intermediário.

Admin

Rota: /admin/api/...

Gestão de clientes, rotação de ApiKey e processamento de pagamentos/webhooks.

Agente

Rota: /agente/api/...

Clientes tipo Agente: criação de projetos e itens, avaliações, mensagens e consulta de serviços.

Autor

Rota: /autor/api/...

Clientes tipo Autor: criação de projetos e itens, avaliações, mensagens e consulta de serviços.

Editora

Rota: /editora/api/...

Avaliações da editora, aprovação de parceiros, gestão de saques, monitoramento de projetos e stats.

Parceiro

Rota: /parceiro/api/...

Login, CRUD de serviços, financeiro (saldos/saques), mensagens, projetos e resumo do parceiro.

🛡️

Admin /admin

Gestão de clientes, editoras, pagamentos e webhooks

Abrir Swagger →

Fluxo do Admin

Cadastrar Cliente
Rotar ApiKey
Processar Pagamentos

Clientes

MétodoRotaDescriçãoAuth
GETadmin/api/clienteListar clientes (paginado)ApiKey
GETadmin/api/cliente/{id}Obter cliente por idApiKey
POSTadmin/api/clienteCadastrar clienteApiKey
PUTadmin/api/cliente/{id}Atualizar clienteApiKey
DELETEadmin/api/cliente/{id}Excluir clienteApiKey

Editoras

MétodoRotaDescriçãoAuth
POSTadmin/api/editoras/{id}/rotate-keyRotacionar ApiKeyApiKey

Pagamentos

MétodoRotaDescriçãoAuth
POSTadmin/api/pagamentos/webhook/{gateway}Webhook do gatewayPública
POSTadmin/api/pagamentos/confirmarConfirmar pagamentoApiKey
POSTadmin/api/pagamentos/{projetoId}/reconciliar-taxaAgendar reconciliação manual da taxa real do gatewayApiKey

TickerQ Dashboard

💡
O dashboard do TickerQ está disponível em /admin/tickerq (protegido por Basic Auth — usuário e senha configurados em appsettings.json seção TickerQ:Dashboard). Permite visualizar e gerenciar jobs em background.
👤

Agente /agente

Clientes agentes: registro, avaliações, mensagens e serviços

Abrir Swagger →

Fluxo do Agente

Cadastrar Agente
Criar Projeto
Avaliar
Conversar

Cliente

MétodoRotaDescriçãoAuth
POSTagente/api/clienteCadastrar cliente (tipo Agente)ApiKey

Projetos

MétodoRotaDescriçãoAuth
GETagente/api/projetoListar projetosApiKey
GETagente/api/projeto/{id}Obter projetoApiKey
GETagente/api/projeto/{id}/avaliacoesAvaliações do projetoApiKey
POSTagente/api/projetoCriar projetoApiKey
POSTagente/api/projeto/{id}/pagamento/finalizarFinalizar para pagamentoApiKey
GETagente/api/projeto/{id}/pagamento/link?clienteId={id}Obter ou regerar link de checkout (Redis → gateway)ApiKey
PATCHagente/api/projeto/{id}/status/canceladoCancelar projetoApiKey

Itens de Projeto

MétodoRotaDescriçãoAuth
POSTagente/api/projeto/{id}/itensAdicionar itemApiKey
DELETEagente/api/projeto/{id}/itens/{itemId}Remover itemApiKey
PATCHagente/api/projeto/{id}/itens/{itemId}Atualizar quantidadeApiKey
PATCHagente/api/projeto/{id}/itens/{itemId}/briefingAdicionar briefingApiKey

Avaliações

MétodoRotaDescriçãoAuth
POSTagente/api/avaliacaoCriar avaliação (origem Cliente)ApiKey

Mensagens

MétodoRotaDescriçãoAuth
POSTagente/api/projeto/{projetoId}/mensagensEnviar mensagemApiKey
GETagente/api/projeto/{projetoId}/mensagens/conversaObter conversaApiKey
GETagente/api/projeto/{projetoId}/mensagens/{mensagemId}Obter mensagemApiKey
GETagente/api/projeto/{projetoId}/mensagens/ultimaÚltima mensagemApiKey

Serviços

MétodoRotaDescriçãoAuth
GETagente/api/servico/{id}Obter serviçoApiKey
GETagente/api/servicoListar serviçosApiKey
GETagente/api/servico/parceiro/{parceiroId}Serviços de parceiroApiKey

Parceiros (consulta)

MétodoRotaDescriçãoAuth
GETagente/api/parceiro/{id}Obter parceiro por idApiKey
✍️

Autor /autor

Clientes autores: registro, avaliações, mensagens e serviços

Abrir Swagger →

Fluxo do Autor

Cadastrar Autor
Criar Projeto
Avaliar
Conversar

Cliente

MétodoRotaDescriçãoAuth
POSTautor/api/clienteCadastrar cliente (tipo Autor)ApiKey

Projetos

MétodoRotaDescriçãoAuth
GETautor/api/projetoListar projetosApiKey
GETautor/api/projeto/{id}Obter projetoApiKey
GETautor/api/projeto/{id}/avaliacoesAvaliações do projetoApiKey
POSTautor/api/projetoCriar projetoApiKey
POSTautor/api/projeto/{id}/pagamento/finalizarFinalizar para pagamentoApiKey
GETautor/api/projeto/{id}/pagamento/link?clienteId={id}Obter ou regerar link de checkout (Redis → gateway)ApiKey
PATCHautor/api/projeto/{id}/status/canceladoCancelar projetoApiKey

Itens de Projeto

MétodoRotaDescriçãoAuth
POSTautor/api/projeto/{id}/itensAdicionar itemApiKey
DELETEautor/api/projeto/{id}/itens/{itemId}Remover itemApiKey
PATCHautor/api/projeto/{id}/itens/{itemId}Atualizar quantidadeApiKey
PATCHautor/api/projeto/{id}/itens/{itemId}/briefingAdicionar briefingApiKey

Avaliações

MétodoRotaDescriçãoAuth
POSTautor/api/avaliacaoCriar avaliação (origem Cliente)ApiKey

Mensagens

MétodoRotaDescriçãoAuth
POSTautor/api/projeto/{projetoId}/mensagensEnviar mensagemApiKey
GETautor/api/projeto/{projetoId}/mensagens/conversaObter conversaApiKey
GETautor/api/projeto/{projetoId}/mensagens/{mensagemId}Obter mensagemApiKey
GETautor/api/projeto/{projetoId}/mensagens/ultimaÚltima mensagemApiKey

Serviços

MétodoRotaDescriçãoAuth
GETautor/api/servico/{id}Obter serviçoApiKey
GETautor/api/servicoListar serviçosApiKey
GETautor/api/servico/parceiro/{parceiroId}Serviços de parceiroApiKey

Parceiros (consulta)

MétodoRotaDescriçãoAuth
GETautor/api/parceiro/{id}Obter parceiro por idApiKey
📚

Editora /editora

Gestão de avaliações, mensagens, parceiros e saques

Abrir Swagger →

Fluxo da Editora

Avaliar Projeto
Aprovar Parceiro
Aprovar Saque
Confirmar Pagamento

Avaliações

MétodoRotaDescriçãoAuth
POSTeditora/api/avaliacaoCriar avaliação (origem Editora)ApiKey

Mensagens (leitura)

MétodoRotaDescriçãoAuth
GETeditora/api/projeto/{projetoId}/mensagens/conversaObter conversaApiKey
GETeditora/api/projeto/{projetoId}/mensagens/{mensagemId}Obter mensagemApiKey
GETeditora/api/projeto/{projetoId}/mensagens/ultimaÚltima mensagemApiKey

Serviços (leitura)

MétodoRotaDescriçãoAuth
GETeditora/api/servico/{id}Obter serviçoApiKey
GETeditora/api/servicoListar serviços disponíveisApiKey
GETeditora/api/servico/parceiro/{parceiroId}Listar serviços de um parceiroApiKey
GETeditora/api/servico/statsEstatísticas de serviçosApiKey

Admin Parceiros

MétodoRotaDescriçãoAuth
GETeditora/api/parceiro/{id}Obter parceiro por idApiKey
POSTeditora/api/parceiros/{id}/aprovarAprovar parceiroApiKey
POSTeditora/api/parceiros/{id}/reprovarReprovar parceiroApiKey

Admin Saques

MétodoRotaDescriçãoAuth
GETeditora/api/saquesListar solicitações (filtro status/parceiro)ApiKey
GETeditora/api/saques/statsEstatísticas de saquesApiKey
POSTeditora/api/saques/{id}/aprovarAprovar saque → EmProcessamentoApiKey
POSTeditora/api/saques/{id}/rejeitarRejeitar saque (estorna saldo)ApiKey
POSTeditora/api/saques/{id}/confirmar-pagamentoConfirmar pagamento (comprovante)ApiKey

Projetos

MétodoRotaDescriçãoAuth
GETeditora/api/projetoListar projetosApiKey
GETeditora/api/projeto/{id}Obter projetoApiKey
GETeditora/api/projeto/{id}/avaliacoesAvaliações do projetoApiKey
GETeditora/api/projeto/statsEstatísticas de projetosApiKey
PATCHeditora/api/projeto/{id}/status/canceladoCancelar projetoApiKey
🤝

Parceiro /parceiro

Auth, CRUD, Serviços, Financeiro, Mensagens & Projetos

Abrir Swagger →

API completa do parceiro: autenticação, cadastro, gestão de serviços, saldos/saques, mensagens e projetos.

Auth Parceiro

MétodoRotaDescriçãoAuth
POSTparceiro/api/parceiro/auth/loginLogin (email + senha) → retorna tokenApiKey
POSTparceiro/api/parceiro/auth/logoutLogout (invalida token no Redis)Bearer
GETparceiro/api/parceiro/auth/meDados do parceiro autenticadoBearer

Parceiro CRUD

MétodoRotaDescriçãoAuth
GETparceiro/api/parceiroListar parceiros (paginado, filtro nome/email)ApiKey
GETparceiro/api/parceiro/{id}Obter parceiro por id (204 se não encontra)ApiKey
POSTparceiro/api/parceiroCadastrar parceiro vinculado à EditoraApiKey
PUTparceiro/api/parceiro/{id}Atualizar dados geraisApiKey
GETparceiro/api/parceiro/resumoResumo consolidado (saldos, projetos, serviços)Bearer

Serviços do Parceiro RequireParceiroFilter

MétodoRotaDescriçãoAuth
GETparceiro/api/parceiro/servicoListar meus serviços (paginado)Bearer
GETparceiro/api/parceiro/servico/{id}Obter serviço (valida ownership)Bearer
POSTparceiro/api/parceiro/servicoCriar serviçoBearer
PUTparceiro/api/parceiro/servico/{id}Atualizar serviçoBearer
DELETEparceiro/api/parceiro/servico/{id}Excluir serviço (soft-delete)Bearer
PATCHparceiro/api/parceiro/servico/{id}/ativarAtivar serviçoBearer
PATCHparceiro/api/parceiro/servico/{id}/inativarInativar serviçoBearer

Financeiro do Parceiro RequireParceiroFilter

MétodoRotaDescriçãoAuth
GETparceiro/api/parceiro/financeiro/saldosSaldos (bloqueado + disponível)Bearer
GETparceiro/api/parceiro/financeiro/saquesListar solicitações de saqueBearer
POSTparceiro/api/parceiro/financeiro/saquesSolicitar saque (valor ≤ saldo disponível)Bearer
GETparceiro/api/parceiro/financeiro/extratoExtrato de movimentações (filtro tipo)Bearer
PUTparceiro/api/parceiro/financeiro/pixAtualizar dados PixBearer

Projetos

MétodoRotaDescriçãoAuth
GETparceiro/api/projetoListar projetos do parceiroApiKey
GETparceiro/api/projeto/{id}Obter projetoApiKey
GETparceiro/api/projeto/{id}/avaliacoesAvaliações do projetoApiKey
POSTparceiro/api/projeto/{id}/pronto-entregasMarcar como pronto + entregasApiKey
PATCHparceiro/api/projeto/{id}/status/canceladoCancelar projetoApiKey

Mensagens

MétodoRotaDescriçãoAuth
POSTparceiro/api/projeto/{projetoId}/mensagensEnviar mensagem (remetente Parceiro)ApiKey
GETparceiro/api/projeto/{projetoId}/mensagens/conversaObter conversa completaApiKey
GETparceiro/api/projeto/{projetoId}/mensagens/{mensagemId}Obter mensagem por idApiKey
GETparceiro/api/projeto/{projetoId}/mensagens/ultimaÚltima mensagem da conversaApiKey

🔐 Autenticação

ApiKey (Editora)

Header: X-Api-Key: <chave>
A chave é um Value Object de 64 caracteres que codifica o EditoraId + timestamp.
O middleware tenta resolver via Redis (cache 1h) e faz fallback para o Postgres.

Bearer Token (Parceiro)

Header: Authorization: Bearer <token>
Sessão server-side no Redis (não é JWT). Obtido via POST api/parceiro/auth/login.
Endpoints protegidos usam RequireParceiroFilter (IEndpointFilter) que exige token válido + parceiro ativo.

Rotas públicas

Não exigem autenticação:

  • POST admin/api/pagamentos/webhook/{gateway}
  • /swagger, /openapi
  • /admin/tickerq (protegido por Basic Auth próprio)
  • /health, /alive (apenas Development)

🔄 Fluxo do Projeto

Reservado AguardandoPagamento EmAndamento Pronto Finalizado
TransiçãoRequisitosEfeitos
Reservado → AguardandoPagamentoProjeto deve ter ≥ 1 itemGera pagamento e inicia checkout
AguardandoPagamento → EmAndamentoPagamento aprovadoCria conversa; credita saldo bloqueado do parceiro
EmAndamento → ProntoParceiro marca como prontoPode adicionar URLs de entrega
Pronto → FinalizadoAvaliação aprovada do Cliente + EditoraMove saldo bloqueado → disponível
* → CanceladoQualquer status exceto FinalizadoEstorna saldo bloqueado se EmAndamento com pagamento aprovado

💰 Fluxo Financeiro

Saldo Bloqueado

Aumenta quando pagamento é aprovado e projeto entra EmAndamento. Valor = ValorLiquido do pagamento.

Saldo Disponível

Aumenta quando projeto é Finalizado (avaliações aprovadas). Saldo bloqueado é transferido para disponível.

Saque

Parceiro solicita (valor ≤ disponível) → Admin aprova → Admin confirma pagamento (Pix/TED + comprovante). Se rejeitado, valor é estornado.

Reconciliação de Taxa

Após pagamento aprovado, um job TickerQ consulta os payables do Pagarme para obter a taxa real cobrada pelo gateway (fee + anticipation_fee + fraud_coverage_fee). Ajusta TaxaCobrada no pagamento e o saldo do parceiro (SaldoBloqueado ou SaldoDisponivel conforme status do projeto). Flag TaxaReconciliada indica se já foi reconciliado. Admin pode forçar via POST admin/api/pagamentos/{projetoId}/reconciliar-taxa. O agendamento é abstraído por IReconciliacaoJobScheduler (impl TickerQ registrada no módulo Admin). Inspecione jobs via dashboard TickerQ.

⏱️ Background Jobs (TickerQ)

💡
Jobs executam em background via TickerQ com persistent store EF Core Postgres (schema ticker). Inspecione via dashboard TickerQ (Basic Auth).

ReconciliarTaxaGatewayJob

Consulta payables do Pagarme para obter taxa real. Trigger: 5min após aprovação, retry a cada 10min (max 6 tentativas).

LimparCheckoutsExpiradosJob

Cancela projetos AguardandoPagamento há mais de 48h. Executa a cada 1 hora.

PollStatusPagamentoJob

Fallback para webhook perdido: consulta status de pagamentos pendentes no gateway. Executa a cada 30 minutos. Aprova ou reprova conforme resposta.

🗄️ Cache Redis (Stats)

💡
Endpoints de stats/resumo usam IDistributedCache (Redis) com TTL de 5 minutos para reduzir carga no banco.
ChaveEndpointTTL
stats:projeto:{editoraId}GET editora/api/projeto/stats5 min
stats:saque:{editoraId}GET editora/api/saques/stats5 min
stats:servico:{editoraId}GET editora/api/servico/stats5 min
stats:resumoParceiro:{parceiroId}:{editoraId}GET parceiro/api/parceiro/resumo5 min
checkout:link:{projetoId}GET {mod}/api/projeto/{id}/pagamento/link3h

📊 Observabilidade

Aspire Dashboard

Disponível em http://localhost:8085. Coleta métricas, traces e logs exportados via OTLP/gRPC pelos containers api e migrationwork. Ativo quando OTEL_EXPORTER_OTLP_ENDPOINT está configurado (injetado automaticamente pelo Aspire).

New Relic (OTLP)

Quando a variável NEW_RELIC_LICENSE_KEY está presente, um segundo exportador OTLP/gRPC envia traces, métricas e logs para otlp.nr-data.net:4317em paralelo ao Aspire Dashboard, sem substituí-lo.

💡
Configurado em ServiceDefaults/Extensions.csAddOpenTelemetryExporters(). A chave New Relic é propagada via parâmetro Aspire new-relic-license-key (secret) e configurada em src/CapZeroApp.AppHost/appsettings.Production.json.

🏗️ Arquitetura

┌────────────────────────────────────────────────────────────────┐
│                  API Unificada — CapZeroApp.Api                 │
│         Kestrel serve arquivos estáticos + rotas modulares      │
│                                                                │
│   MapGroup("/admin")    ── módulo Admin  (clientes, editoras,  │
│                                           pagamentos, TickerQ) │
│   MapGroup("/agente")   ── módulo Agente (clientes, projetos,  │
│                                           itens, mensagens)    │
│   MapGroup("/autor")    ── módulo Autor  (idêntico ao Agente,  │
│                                           tipo Autor)          │
│   MapGroup("/editora")  ── módulo Editora (avaliações,         │
│                                           parceiros, saques)   │
│   MapGroup("/parceiro") ── módulo Parceiro (auth, serviços,    │
│                                           financeiro)          │
│   /                     ── arquivos estáticos (esta doc)       │
└────────────────────────────────────────────────────────────────┘
         │                    │
    ┌────▼────┐         ┌────▼────┐
    │ Postgres │         │  Redis  │
    │capzerodb │         │  cache  │
    └─────────┘         └─────────┘

  URL: {módulo}/api/{rota}  (estrutura preservada, sem proxy intermediário)
  Ex: parceiro/api/parceiro/auth/login  →  MapGroup("/parceiro") resolve direto
  Ex: editora/api/saques                →  MapGroup("/editora") resolve direto

  Migration Worker: aplica migrations + seed da Editora padrão "Flyve"

  1 container · 1 pool Postgres · 1 conexão Redis
  • Domain & Application (lógica de negócio)
  • Presentation.Shared (endpoints reutilizáveis)
  • Infrastructure (auth, persistence, payment)
💡
Rodar localmente: dotnet run --project src/CapZeroApp.AppHost — sobe Postgres, Redis, migration worker e a API unificada.
⚠️
Padrão de URL: todas as rotas seguem {módulo}/api/{rota}. A API usa MapGroup() por módulo — sem gateway ou reverse proxy entre o cliente e a aplicação. Ex: parceiro/api/parceiro/servico é resolvido diretamente pelo grupo /parceiro.

⚙️ Padrões de código

Minimal API + Mediator

Cada endpoint é uma classe estática com um Map*() extension method. Endpoints chamam IMediator.Send(). Commands implementam ITransactionalRequest e rodam dentro de transação EF Core.

Result Pattern

Validações retornam Result<T> com erros agregados (operador +). Sem exceções para regras de negócio. Falhas mapeadas via result.ToEndpointResult().

Value Objects

Campos críticos usam VOs (ApiKey, Nome, Email, Money, Pix, Url…) criados via Create().

Soft-Delete

Entidades com ISoftDelete têm filtro global no DbContext. Exclusão via MarkAsDeleted().

AuditBehavior (Pipeline)

Comportamento externo ao TransactionalBehavior. Registra cada command com contexto de autenticação (Editora, Parceiro, Usuário), método HTTP, rota, IP e resultado. Falhas de auditoria nunca afetam o fluxo principal. Gravação via scope DI isolado.

📋 Auditoria

💡
Toda operação de escrita (ITransactionalRequest) é auditada automaticamente via AuditBehavior no pipeline do Mediator. A auditoria roda fora da transação de negócio (scope DI isolado) e nunca interrompe o fluxo principal em caso de falha.

Tabela AuditLogs (PostgreSQL)

ColunaTipoDescrição
IduuidPK gerado automaticamente
TimestamptimestamptzMomento exato da operação (UTC)
EditoraIduuid?Tenant que originou a requisição (X-Api-Key)
ParceiroIduuid?Parceiro autenticado via Bearer, se presente
UsuarioIduuid?Usuário do parceiro autenticado, se presente
Acaovarchar(200)Nome do Command/Request (ex.: CadastrarParceiroCommand)
Modulovarchar(50)Módulo inferido da rota HTTP (ex.: parceiro, admin)
HttpMethodvarchar(10)Método HTTP (GET, POST, PATCH…)
Rotavarchar(500)Caminho da requisição
IpOrigemvarchar(50)IP do cliente
Sucessobooltrue se o command retornou Result.IsSuccess
Errosvarchar(2000)?Erros de negócio ou mensagem de exceção em caso de falha

Pipeline de execução

HTTP Request AuditBehavior (outer) TransactionalBehavior Handler de Domínio Commit TX INSERT AuditLog (scope isolado)
⚠️
Somente commands são auditados — queries (GET) não implementam ITransactionalRequest e não geram registros. Isso evita ruído na tabela e mantém a auditoria focada em operações com efeito colateral.

🚀 Melhorias futuras