Pular para o conteúdo principal

Status: Approved · v2 · SPEC-DOMAIN-WALLET-001

depends_on: SPEC-DOMAIN-TEAM-001, SPEC-DOMAIN-TORCIDA-001

used_by: IS-MVP-09.1, IS-MVP-09.3, IS-MVP-09.4

Carteiras e créditos

Saldo interno não sacável de times e torcidas, formado por lotes rastreáveis e usado em ações da plataforma.

Objetivo e limites

Esta especificação define o comportamento canônico do domínio Carteiras e créditos no RaizFC. Ela deve ser consultada antes de alterar contratos, mocks, endpoints, telas, permissões ou Increment Specifications relacionados.

Incluído no MVP

  • Wallet para time e torcida.
  • Créditos equivalentes a centavos de uso interno.
  • Lotes com origem e expiração de 90 dias.
  • Apoio 95/5.
  • Patrocínio 80/20.
  • Transferência sem taxa time↔torcida aprovada.
  • Consumo FIFO.

Fora do MVP

  • Saque.
  • Cashback.
  • Rendimento.
  • Criptomoeda.
  • Carteira de campeonato/campo/serviço.

Atores e responsabilidades

AtorResponsabilidade
ApoiadorRealiza contribuição anônima ou identificada.
Gestor financeiroConsulta saldo/extrato, transfere e usa créditos.
Responsável principalPossui acesso total financeiro.
SistemaCredita, debita, expira e aplica FIFO.
OperaçãoAudita e corrige apenas por fluxo autorizado.

Conceitos canônicos

Wallet

Conta interna de créditos, não bancária.

CreditLot

Lote com saldo remanescente, origem e expiresAt.

LedgerEntry

Movimentação imutável.

Available Balance

Soma de lotes válidos menos reservas/consumos.

Reserved Balance

Crédito temporariamente comprometido por operação.

Invariantes

  • Saldo disponível nunca é negativo.
  • Toda alteração de saldo produz ledger entry e referência de origem.
  • Créditos expirados não podem ser usados.
  • Consumo usa FIFO por expiração.
  • Lotes são imutáveis em origem e valor inicial.
  • Wallet pertence apenas a team ou torcida no MVP.
  • Transferência só ocorre entre torcida approved e seu time.
  • Crédito não é sacável nem transferível a usuário.
  • Operações financeiras críticas exigem Idempotency-Key.

Estados

EstadoSignificadoVisibilidade/efeito
activeCarteira operacionalRecebe e usa créditos.
restrictedUso limitadoPode receber, mas não gastar/transferir conforme motivo.
closedEntidade encerradaSem novas operações; histórico preservado.

Transições permitidas

OrigemAçãoDestinoAutoridadeEfeitos
create_with_entityactiveSistemaSaldo zero.
activerestrictrestrictedOperação/status da entidadeBloqueia saídas.
restrictedrestoreactiveOperaçãoLibera.
active/restrictedcloseclosedSistema/operaçãoPreserva extrato.

Permissões

Permission keyQuem recebe por padrãoAção protegidaAuditoria
wallet.viewFinancial/Admin/OwnerSaldo e extratoSim
wallet.transferFinancial/Admin/OwnerTransferir time↔torcidaSim
wallet.spendFinancial/Admin/OwnerAções pagasSim
wallet.exportFinancial/Admin/OwnerExportar extratoSim

Fluxos funcionais

Crédito por apoio

  1. Pagamento confirmado dispara efeito idempotente.
  2. Sistema calcula 95% para entidade e 5% plataforma.
  3. Cria lote de créditos com expiresAt +90 dias.
  4. Cria ledger entry credit/support.
  5. Atualiza saldo derivado e notifica gestores.

Crédito por patrocínio

  1. Pagamento confirmado calcula 80/20.
  2. Lote referencia sponsorshipId.
  3. Patrocínio ativa em transação lógica consistente.

Consumo

  1. Gestor escolhe ação e visualiza preço fixo.
  2. Backend valida permissão, status e saldo.
  3. Reserva/consome lotes FIFO.
  4. Cria entries por lote consumido e referência da ação.
  5. Falha posterior deve liberar reserva ou compensar de forma auditada.

Transferência

  1. Gestor escolhe torcida/time vinculado e valor.
  2. Valida approved link e saldo.
  3. Consome FIFO na origem.
  4. Cria lote na destinatária com política de expiração preservada ou reiniciada conforme decisão canônica: preservar menor expiração remanescente.
  5. Cria entries espelhadas sem taxa.

Expiração

  1. Job encontra saldo remanescente em lotes vencidos.
  2. Cria debit/expiration.
  3. Atualiza saldo e envia resumo aos gestores.

Casos-limite e erros

CenárioComportamento esperadoCódigo/estado
Saldo insuficienteNão alterar lotesINSUFFICIENT_CREDITS
Idempotency repetidaRetornar operação originalIDEMPOTENCY_REPLAY
Wallet restritaBloquear saídaWALLET_RESTRICTED
Transferência inválidaRejeitarINVALID_WALLET_TRANSFER
Lote expira durante reservaUsar regra transacional e impedir saldo inconsistenteCREDIT_LOT_EXPIRED
Valor não positivoRejeitarINVALID_MONEY_AMOUNT

Privacidade e exposição pública

  • Saldo, lotes e extrato são privados.
  • Página pública pode exibir apoiadores sem valores.
  • A origem agregada pode ser usada em métricas sem identificar doadores anônimos.
  • Logs não registram payload Pix completo.

Notificações e auditoria

  • Crédito recebido.
  • Transferência enviada/recebida.
  • Saldo insuficiente para ação.
  • Expiração próxima/realizada.
  • Restrição/restauração.
  • Toda movimentação possui auditoria e requestId.

API relacionada

MétodoRotaAcessoFinalidade
GET/api/v1/wallets/:ownerType/:ownerIdwallet.viewResumo
GET/api/v1/wallets/:ownerType/:ownerId/ledgerwallet.viewExtrato
POST/api/v1/wallets/:ownerType/:ownerId/transferswallet.transferTransferir
POST/api/v1/wallets/:ownerType/:ownerId/spendwallet.spendConsumir
GET/api/v1/wallets/:ownerType/:ownerId/credit-lotswallet.viewLotes

Contratos compartilhados

  • WalletEntity
  • WalletSummaryDto
  • CreditLotDto
  • LedgerEntryDto
  • WalletEntryType
  • CreateWalletTransferRequest
  • SpendCreditsRequest
  • MoneyAmount

Requisitos de UX

  • Carteira mostra saldo disponível, créditos a expirar, entradas/saídas e ações.
  • Nunca usar símbolo que sugira saque ou investimento.
  • Confirmação de gasto mostra custo, saldo antes/depois e finalidade.
  • Extrato tem filtros por tipo e período.
  • Apoiadores públicos ficam fora da tela privada de extrato.

Comportamento dos mocks

  • Wallets com saldo zero, suficiente, insuficiente, lotes próximos de expirar e restricted.
  • Consumo realmente altera lotes in-memory.
  • Replay idempotente retorna mesma resposta.
  • Job de expiração controlável.

Critérios de aceite

  • Saldo derivado não fica negativo.
  • Toda operação possui ledger.
  • FIFO aplicado.
  • Expiração em 90 dias.
  • Transferência limitada ao vínculo time-torcida.
  • Valores em centavos.

Testes obrigatórios

  • Splits 95/5 e 80/20.
  • FIFO.
  • Expiração.
  • Idempotência.
  • Restrição.
  • Transferência e expiração preservada.
  • Concorrência de consumo.

Pós-MVP

  • Previsão de caixa.
  • Orçamentos por categoria.
  • Mais tipos de entidade, se comprovado.
  • Integrações contábeis.

Decisões registradas

  • Créditos não são sacáveis.
  • 1 crédito corresponde a R$1 de capacidade interna, armazenado em centavos.
  • Somente time e torcida possuem wallet.
  • Transferência sem taxa.

Machine summary

spec: SPEC-DOMAIN-WALLET-001
domain: Carteiras e créditos
must_preserve:
- Saldo disponível nunca é negativo.
- Toda alteração de saldo produz ledger entry e referência de origem.
- Créditos expirados não podem ser usados.
- Consumo usa FIFO por expiração.
- Lotes são imutáveis em origem e valor inicial.
- Wallet pertence apenas a team ou torcida no MVP.
- Transferência só ocorre entre torcida approved e seu time.
- Crédito não é sacável nem transferível a usuário.
touches:
- contracts
- mocks
- api
- frontend
- backend
- tests
- documentation