# 08 - DICT + MED/GID legado (CRK/Corner) - ciclo de vida de chaves, reivindicacoes, infracoes, devolucoes, MED

Fonte: decompilado em `.scratch/legado-pix-decompiled/` (DICT.Core.*, GID.Core.*) + scripts SQL
`LegadoPIX/Pix/DICT/DATABASE` (DB `des_4dict` / `DES_4DICT`) e `LegadoPIX/Pix/Med_gid/scripts` (DB `crk_gdi` / `CRK_GDI`).
Read-only. Objetivo: confronto com a nossa cabine DICT/MED.

## 0. Arquitetura de processos (Windows Services / .NET workers)

DICT roda a API web (`DICT.Web.Api`) + gRPC (`DICT.Worker.GRPC`) + 6 workers de background, cada um um
executavel proprio, com laco `while` + `Task.Delay(intervalo)`:

- `Worker.Claims` (reivindicacoes) -> 5 sub-fases num unico worker `WorkerBuscaSolicitacao`.
- `Worker.Devolucao` (solicitacao de devolucao especial MED-DICT).
- `Worker.Infracao` (3 hosted services: BuscaInfracao interna, BuscaInfracaoSolicitante, RecepcaoInfracao).
- `Worker.Protecao` (protecao antivarredura / rate-limit por pagamento).
- `Worker.Sincronismo` (VSYNC/CID por participante controlado x 5 tipos de chave).
- `Worker.Statistics` (atualiza estatisticas de chave/dono).

GID/MED roda a API `GID.Api` + `GID.Worker.Eventos` (polling de `event-notifications` do BACEN por participante).

Config central em `TB_PARAMETRO` (DICT) e `TB_PARAMETRO`/`TB_GRUPO_PARAMETRO` (GID). Multi-participante:
`ParticipantesControlados` / `Participantes` (um DICT/MED serve varios ISPB - modelo de bureau/multibanco CRK).

## 1. CHAVES DICT - ciclo de vida

### Tipos de chave (`enumKeyType` / `TB_TIPOCHAVE`)
1 CPF, 2 CNPJ, 3 PHONE, 4 EMAIL, 5 EVP (aleatoria). Enum ainda declara IDENTIFIER / CUSTOM_IDENTIFIER /
COMPANY_CODE (nao carregados na `TB_TIPOCHAVE`, legado de outras pracas).

### Tipos de conta (`enumAccountType`)
CACC, SLRY, SVGS, TRAN, CAHO, CCTE, DBMO, DORD, DBMI (GID adiciona OTHR).

### Status de conta (`enumAccountStatus`): ACTIVE(1), BLOCKED(2), ONHOLD(3) (retida por portabilidade cancelada).

### Entidade local
`Contadict` (base local de chaves espelhada do DICT: TextoChave, IdCID, SPBParticipante, CPFCNPJ, Nome,
DataAberturaConta, DataCriacaoChave, DataPosseChave, Bloqueado, AccountStatus). `Operacao` = transacao
DICT (consulta/inclusao/exclusao/alteracao/claim/infracao/devolucao), com `enumTipoOperacao` (abaixo).

### Operacoes (`enumTipoOperacao` / `TB_TIPOOPERACAO`)
1 Consulta, 2 Inclusao, 3 Exclusao, 4 Alteracao, 8 ConsultaInterna, 10 Reivindicar, 11 Doar,
15 ConfirmarReivindicacao, 16 CancelarReivindicacao, 21 ReivindicarPosse, 22 DoarPosse,
30 VSync, 31 SincLog, 32 SincBase, 40 ReportarInfracao, 41 ConfirmarInfracao, 42 CancelarInfracao,
43 ConsultaVinculo, 44 CancelarDevolucao, 45 FecharDevolucao, 46 AtualizacaoEstatisticas.

### Endpoints de chave (`entriesController` + `iEntriesController` em ingles):
- `POST entries/IncluiChave` (IncludeKey) - cadastro.
- `PUT entries/AlteraChave` (ChangeKey) - alteracao de vinculo conta/chave.
- `PUT entries/AlteraBloqueioChave` - bloqueio/desbloqueio de chave.
- `DELETE entries/ExcluiChave` (DeleteKey) - exclusao.
- `GET entries/ConsultaChave` (ConsultKey) - consulta DICT no BACEN (envia PI-EndToEndId).
- `GET entries/ConsultaChaveBaseLocal` (ConsultLocalDatabaseKey) - le da base local (`Contadict`) sem ir ao BACEN.
- `GET entries/ConsultaChavePorConta` (QueryKeyByAccount) - lista chaves por agencia/conta.
- `GET entries/DerivaTpChave` - deriva o tipo da chave pelo formato.
- `GET entries/ListaChaves` (ListKeys) - lista.
- `POST entries/Sincronismo` - dispara sincronismo.
- `POST keys/VerificarExistenciaChaves` - verifica existencia em lote (VerifyKeys / `check-keys`).

### Limites e validade (BACEN) - `TB_PARAMETRO` (defaults):
- `NR_QtLimiteContasPF = 5`  (max chaves PF).
- `NR_QtLimiteContasPJ = 20` (max chaves PJ).
- `NR_QtSegundosValidadeConsulta = 60` (janela de validade de uma consulta DICT usada para pagar).
- `NR_QtLimitReivindicacoes = 100`.
- `NR_QtSegundosIntervaloConsultaArquivo = 5`.
- Grupos de metodo BACEN: entries / claims / cids/events / cids/entries / cids/files.

## 2. REIVINDICACOES (Claims)

### Tipos (`enumTipoReivindicacao` / `TB_TIPOREIVINDICACAO`): 1 OWNERSHIP (Posse), 2 PORTABILITY (Portabilidade).
### Motivos (`enumTipoMotivoReivindicacao` / `TB_TIPOMOTIVOREIVINDICACAO`):
1 USER_REQUESTED, 2 ACCOUNT_CLOSURE, 3 FRAUD, 4 DEFAULT_OPERATION, 5 RECONCILIATION.
### Papel de cancelamento (`enumTipoCancelamentoReivindicacao`): DONOR, CLAIMER.

### Maquina de estados (`enumTipoSituacao` / `TB_TIPOSITUACAO`):
1 OPEN, 2 WAITING_RESOLUTION, 3 CONFIRMED, 4 CANCELLED, 5 COMPLETED.
Estados locais extra na carga: 101 WAITING_VALIDATION (aguardando validacao de posse),
102 KEY_INCLUDED (chave incluida localmente).

### Endpoints (`claimsController`):
- `POST claims/ReivindicaChave` (abre posse ou portabilidade; reivindicador).
- `GET claims/ListaReivindicacao` / `GET claims/ListaReivindicacaoBacen` / `GET claims/ConsultaReivindicacaoChave`.
- `POST claims/ConfirmaReivindicacao` (doador confirma).
- `POST claims/CancelaReivindicacao` (doador ou reivindicador cancela).
- `POST claims/ConcluiReivindicacaoPosse` / `POST claims/ConcluiReivindicacaoPortabilidade`.

### Prazos (BACEN) e automacao no worker `Claims` (`WorkerBuscaSolicitacao`, 5 fases por ciclo):
1. `BuscaSolicitacaoDoacaoChave` - varre no BACEN reivindicacoes onde SOMOS o doador (WAITING_RESOLUTION).
2. `AtualizaSolicitacaoCancelada` - equaliza canceladas.
3. `AtualizaSolicitacaoConfirmada` - equaliza confirmadas.
4. `AtualizaQuarentenaPrimeiraEtapa (Posse)` - fim do periodo de resolucao de posse.
5. `AtualizaQuarentenaPortabilidade`.
Condicionais por flag:
- `ExecutaWorkerConcluiReivindicacaoPosseAutomatico` -> conclui posse automaticamente apos quarentena.
- `ExecutaWorkerCancelamentoPosse30Dias` -> `BuscaFinalizaReivindicacaoPosse30diasAutomatico` (posse de 30 dias).
Parametros de tempo:
- `NR_QtSegundosQuarentaPosse = 604800` = **7 dias** (periodo de resolucao de posse - primeira etapa).
- `ResolutionPeriodEnd` / `DataFimPerodoResolucao` e `DataFimPeriodoConclusao` (30 dias de conclusao da posse)
  vindos do BACEN e persistidos em `OperacaoReivindicacao`; `TratarDiasAberto` usa `DictPeriodoResolucao`.
- Intervalos de loop: `NR_QtSegundosVerificacaoReivindicacoes = 3600` (1h),
  `NR_QtSegundosQuarentaPosse` reusado como delay das fases de quarentena.
Resumo BACEN: OWNERSHIP = 7 dias de resolucao + 30 dias de posse; PORTABILITY = 7 dias de resolucao.
Cancelamento com conta encerrada (`enumTipoCancelamento`, `TB_TIPOCANCELAMENTO`, 12 motivos): posse nao
validada, chave em outra conta/IF, exclusao/inclusao rejeitada pelo BACEN, reivindicacao cancelada, etc.

## 3. INFRACOES (Infracao / marcador de fraude)

### Tipos (`enumInfractionType`): FRAUD(1), AML_CTF(2), REFUND_REQUEST(3), REFUND_CANCELLED(4).
### Status do relato (`enumInfractionReportStatus` / `enumTipoSituacaoInfracao`): OPEN(1), ACKNOWLEDGED(2), CLOSED(3), CANCELLED(4).
### Resultado de analise (`enumAnalysisResult`): AGREED(1), DISAGREED(2).
### Papel (`enumPosicaoParticipante`): Reportador / Contestado. `Infracao.Reportador` bool.
### Situacao/tipo de fraude do relato (`enumSituationType`): SCAM, ACCOUNT_TAKEOVER, COERCION, FRAUDULENT_ACCESS, OTHER, UNKNOWN.

### Marcador de fraude (`Fraude` / `enumTipoFraude` / `enumStatusFraude`):
- `enumTipoFraude`: APPLICATION_FRAUD (falsidade ideologica), MULE_ACCOUNT (conta laranja),
  SCAMMER_ACCOUNT (conta de fraudador), OTHER, UNKNOWN.
- `enumStatusFraude`: NEW(1), REGISTERED(2), CANCELLED(3).
- Entidade `Fraude` liga a chave/CPF-CNPJ + `MarcacaoFraudeInfracao` (marcador vinculado a um relato).

### Endpoints de infracao (`infractionreportsController`):
- `POST infractionreports/IncluirInfracao` (abre relato).
- `POST infractionreports/Cancelar` / `POST infractionreports/Fechar` (analise + resultado AGREED/DISAGREED).
- `GET infractionreports/ConsultarInfracao` / `ListaInfracoes` / `POST ListaInfracoesBacen`.
### Endpoints de fraude (`statisticsController`):
- `POST statistics/IncluirMarcacaoFraude`, `GET ConsultarMarcacaoFraude`, `POST CancelarMarcacaoFraude`,
  `GET ListaFraude`, `POST CheckFraud`.
- `GET statistics/ConsultaEstatistica` (dono) / `GET ConsultaEstatisticaChave` (chave) - traz FraudMarkers do BACEN.

### Worker `Infracao` (3 hosted services, delay `NR_QtSegundosIntervaloWorkerInfracao`):
- `BuscaRelatoInfracao(Interna=true)` - infracoes onde somos o contestado (recebedor), por participante,
  mantendo `_dataReferenciaPorParticipante` (cursor incremental).
- `BuscaRelatoInfracao(Interna=false)` - infracoes onde somos o solicitante/reportador.
- `BuscaSolicitacaoRelatorioInfracao` (RecepcaoInfracao).
`enumTipoProcesso`: ATUALIZA_INFRACAO_REPORTADOR, ATUALIZA_INFRACAO_RECEBEDOR, RECEPCIONA_INFRACAO_BACEN.

## 4. DEVOLUCOES no contexto DICT (Devolucao Especial / refunds)

DICT tem um trilho de "devolucao especial" separado do MED, ligado a infracao/relato:
### `SolicitacaoDevolucao`: IdTransacao, IdMotivo, Valor, IdSolicitacaoBacen, IdStatus, participante
solicitante/contestado, `IdRelatoInfracao` (vinculo com a infracao), IdStatusAnalise, IdMotivoRejeicao, IdDevolucao.
### `enumMotivoDevolucao` (refundReason): FRAUD, OPERATIONAL_FLAW, REFUND_CANCELLED, PIX_AUTOMATICO.
### `enumStatusDevolucao`: OPEN(1), CLOSED(2), CANCELLED(3).
### `enumStatusAnaliseDevolucao`: TOTALLY_ACCEPTED, PARTIALLY_ACCEPTED, REJECTED.
### `enumMotivoRejeicaoDevolucao`: NO_BALANCE, ACCOUNT_CLOSURE, CANNOT_REFUND, OTHER, INVALID_REQUEST.
### Endpoints (`refundsController`): `POST IncluiDevEspecial`, `GET ListarDevEspecial`, `POST CancelarDevEspecial`,
`GET ConsultarDevEspecial`, `POST FecharDevEspecial`.
### Worker `Devolucao` (`WorkerBuscaSolicitacaoDevolucao`, delay `NR_QtSegundosIntervaloWorkerDevolucao`):
`BuscaSolicitacaoDevolucao` varre e equaliza solicitacoes de devolucao com o BACEN. Nota: o refund efetivo
(pacs.004) vive no dominio SPI/liquidacao; aqui e o registro/analise DICT-MED da devolucao.

## 5. PROTECAO (Worker Protecao) + SINCRONISMO + ESTATISTICAS

### Protecao (antivarredura / rate-limit por pagamento) - `ValidaProtecaoUseCase`:
- `RegraProtecao`: por SPBParticipante x TipoPessoa define `QtSegundosLimite`, `QtConsultasLimite`,
  `QtSegundosPeriodicidadeVerifPagto`, `DhUltimaVerificacaoPagto`.
- Logica: cruza consultas DICT (`OperacaoConsulta.IdFimAFim`) com pagamentos efetivos (`ListarPagto` no Multi/
  liquidacao). Consulta que NAO virou pagamento dentro da janela = varredura/scan. Materializa a regra de
  limitacao BACEN (participante que consulta muito sem pagar e limitado). Delay `NR_QtSegundosIntervaloWorkerProtecao`.
- Correlato: `limitationPolicyController` (`GET ListaPoliticas`, `GET ConsultaPolitica`) e `consultasPercentisController`
  (`POST ConsultaPercentil`, `POST ConsultaPercentilReivindicacao`) que medem tempo de resposta (ANS/percentis).

### Sincronismo (`Worker.Sincronismo`) - CID/VSYNC:
- Por participante controlado x 5 tipos de chave (CPF,CNPJ,PHONE,EMAIL,EVP) chama `SincronismoUseCase.Processar`.
- Ao parar, desbloqueia horario (`AlteraSituacaoBloqueio VSync`). Historico em `HistSincronismo` (URL, SHA256,
  QtBytes, `enumTipoSituacaoSincronismo`: REQUESTED/PROCESSING/AVAILABLE/ERROR).
- `enumCidSetEventType`: ADDED/REMOVED (eventos CID). Arquivos CID via `cids/files`, vinculos via `cids/entries`,
  eventos via `cids/events`. Janela de operacao por `HorarioParticipante`/`TB_TIPOHORARIO` (Categorias A/B/C/D
  do BACEN, com bloqueio eventual 20h-08h na categoria B).

### Estatisticas (`Worker.Statistics`): atualiza `KeysStatistic`/`OwnersStatistic` (KeyStatistics/OwnerStatistics,
FraudMarkers) periodicamente; `NR_DiasAtualizaEstatisticasBase`.

## 6. MED / GID - Recuperacao de Valores (MED 2.0) + eventos + TRCK002 + camt.025

DB `crk_gdi`. Trata a **API de Recuperacao de Valores** (funds-recoveries) do BACEN + rastreamento (tracking graph)
+ TRCK002 (registro de rastreamento) + camt.025 (retorno de status).

### Status da recuperacao (`enumFundsRecoveryStatus`):
CREATED(1) -> TRACKED(2) -> AWAITING_ANALYSIS(3) -> ANALYSED(4) -> REFUNDING(5) -> COMPLETED(6) / CANCELLED(7).

### Eventos (`enumEventType`), polling em `/event-notifications?Participant=&Cursor=`:
- FUNDS_RECOVERY_ANALYSED -> grava status ANALYSED.
- FUNDS_RECOVERY_CANCELLED -> CANCELLED.
- FUNDS_RECOVERY_COMPLETED -> COMPLETED.
- FUNDS_RECOVERY_INFORMATION_UPDATED -> re-consulta a RV + o grafo de rastreamento.
`enumEntityType`: FUNDS_RECOVERY. Cursor incremental por participante (`ObtemUltimoEvento`).

### Endpoints MED (`RecuperacaoValorController` -> BACEN `/funds-recoveries/...`):
- `POST Incluir` -> `POST funds-recoveries/` (assinado XMLDSig; valida IdTransacaoRaiz: 32 chars, inicia E/D,
  bloco data yyyyMMddHHmm, **nao anterior a 80 dias**; SituationType OTHER exige Detalhes).
- `GET Consultar` -> `GET funds-recoveries/{id}`.
- `POST Atualizar` -> `PUT funds-recoveries/{id}` (so em CREATED/TRACKED/AWAITING_ANALYSIS).
- `POST Cancelar` -> `POST funds-recoveries/{id}/cancel` (nao em COMPLETED/CANCELLED).
- `GET ConsultarGrafoRastreamento` -> `GET funds-recoveries/{id}/tracking-graph` (grafo Pessoa/Conta/Transacao).
- `GET ListarNotificacoesInfracao` -> `GET funds-recoveries/{id}/infraction-reports`.
- `POST SolicitarDevolucao` -> `POST funds-recoveries/{id}/refund` (so em ANALYSED).
- `GET ListarSolicitacaoDevolucao` -> `GET funds-recoveries/{id}/refunds`.
- `POST Listar` / `GET Detalhar` (locais).
Refund do MED: `enumRefundReason` (FRAUD, OPERATIONAL_FLAW, REFUND_CANCELLED, PIX_AUTOMATICO,
FUNDS_RECOVERY_CANCELLED), `enumRefundStatus` (OPEN/CLOSED/CANCELLED), `enumRefundAnalysisResult`
(TOTALLY/PARTIALLY_ACCEPTED/REJECTED), `enumRefundRejectionReason` (NO_BALANCE, ACCOUNT_CLOSURE,
INVALID_REQUEST, OTHER). `enumInfractionNotificationReason`: REFUND_REQUEST, REFUND_CANCELLED.

### TRCK002 (`MED20Controller` + `TRCK002UseCase`) - mensagem de rastreamento cautelar/bloqueio:
- `POST MED20/addTrck002` (adiciona TRCK002), `POST retCamt025` (recebe camt.025), `POST monitorList`,
  `POST getStatusOperacao`, `POST ListStatusData`, `GET hist/{uniqueId}`.
- `TB_TRCK002` (script `03.AjusteTabela.sql`): EndToEndId, InstructionReturnId, InitiationForm, Amount,
  ISPB/Branch/Account/AccountType/CpfCnpj do Debtor e Creditor, MessageId, ProtocoloSPI, RetornoBACEN,
  `Status` (default 1). `enumTransactionStatus`: PendenteDeEnvio(1), Confirmado(2), Rejeitado(3).
  E a cadeia de rastreamento/bloqueio da transacao raiz (grafo de "para onde o dinheiro foi").

### camt.025 (`TB_CAMT025`, script `02.TabelaCamt025.sql`) - retorno de status da operacao:
UniqueId, CdMsg, MessageId, MessageIdOriginal, MsgDefIdr, DtHrOperacao, `SituacaoTransacao`, CodigoErro,
DetalheErro, `IdSystem = 5 para GID`, IspbIF. `enumNaturezaMensagem` Debito/Credito/NaoFinanceira,
`enumSentidoMsg` Envio/Retorno. Modelo `Message`/`ISpiMessage` (EndToEndId, RtrId, NumCtrlSTR,
MessageIdOrig/EndToEndIdOrig, DtHrLiquidacao, IdStatus=`enumStatusOperacao`).

### Worker GID (`GID.Worker.Eventos`): por participante, `CarregarNotificacoesEventos` (polling event-notifications),
delay `IntervaloWorker`. Notificacoes locais em `NotificacoesEventoController` (`POST Listar`).

## 7. Assinatura / cripto / conexao BACEN (contexto)
- Dominios de cert (`enumDominioCertificado`): SPICN(100 conexao) / SPISG(101 assinatura) (`TB_PARAMETRO` CD_DominioConexao=100, CD_DominioSign=101).
- `enumFlagProdTeste`: Teste(T)/Producao(P); `Ambiente = Homologacao` -> Teste. XMLDSig via `SignXmlUseCase` (assina antes de enviar ao BACEN).
- `Chave`/`ChavePrivada`/`Dominio` (base local de certificados).

## 8. Confrontar com a NOSSA cabine DICT/MED - checklist de existencia

Chaves/consulta:
- [ ] Consulta a base LOCAL sem ir ao BACEN (`ConsultaChaveBaseLocal`) - temos read model local de chaves espelhado (`Contadict`)?
- [ ] Consulta por conta (`QueryKeyByAccount`) e verificacao em lote (`check-keys`)?
- [ ] Limites PF=5 / PJ=20 e validade de consulta 60s aplicados na nossa cabine?
Reivindicacoes:
- [ ] Maquina OPEN/WAITING_RESOLUTION/CONFIRMED/CANCELLED/COMPLETED + estados locais WAITING_VALIDATION/KEY_INCLUDED?
- [ ] Automacao de quarentena de posse (7 dias resolucao) e conclusao/cancelamento de posse aos 30 dias?
- [ ] Portabilidade com fim de periodo de resolucao vindo do BACEN e conclusao (Servico/Web)?
- [ ] Doador vs reivindicador (nos como doador varrendo o BACEN periodicamente)?
Infracoes/fraude:
- [ ] Marcador de fraude proprio (APPLICATION_FRAUD/MULE_ACCOUNT/SCAMMER_ACCOUNT) + status NEW/REGISTERED/CANCELLED?
- [ ] Trilhas separadas reportador (interna) x solicitante e recepcao de infracao do BACEN por cursor?
- [ ] SituationType (SCAM/ACCOUNT_TAKEOVER/COERCION/FRAUDULENT_ACCESS/OTHER/UNKNOWN) e AnalysisResult AGREED/DISAGREED?
Devolucao DICT (especial, ligada a infracao):
- [ ] `IncluiDevEspecial`/analise TOTALLY/PARTIALLY_ACCEPTED/REJECTED + motivos de rejeicao?
Protecao/rate-limit:
- [ ] Regra de protecao antivarredura (correlaciona consulta DICT x pagamento efetivo) - **temos isso? provavel gap**.
- [ ] Politica de limitacao / percentis / ANS (tempo de resposta) monitorados?
Sincronismo:
- [ ] VSYNC/CID por participante x tipo de chave, arquivos CID (files/entries/events), historico com SHA256?
- [ ] Categorias de horario A/B/C/D com bloqueio eventual (20h-08h)?
MED/GID (Recuperacao de Valores 2.0):
- [ ] funds-recoveries: create/consult/update/cancel/tracking-graph/refund/refunds/infraction-reports?
- [ ] status CREATED->TRACKED->AWAITING_ANALYSIS->ANALYSED->REFUNDING->COMPLETED/CANCELLED?
- [ ] polling de event-notifications por cursor (FUNDS_RECOVERY_ANALYSED/COMPLETED/CANCELLED/INFORMATION_UPDATED)?
- [ ] TRCK002 (grafo/cautelar de bloqueio) e camt.025 (retorno de status) persistidos e correlacionados?
- [ ] validacao da transacao raiz: 32 chars, inicia E/D, nao anterior a 80 dias?
- [ ] grafo de rastreamento (Pessoa/Conta/Transacao) armazenado localmente?
