L-3 — Validação e Qualidade
Parte das Colônias de Lugares — subconjunto no MVP; Fase 2 completa
Propósito
Seção intitulada “Propósito”A L-3 determina se um lugar é confiável o suficiente para entrar no mapa como confirmado. No modelo completo, opera por três métodos em ordem de custo crescente: confirmação automática por confiança, reincidência temporal de cadastros e validação social presencial sorteada.
O MVP implementa o subconjunto social e automático: confirmação automática pela tipificação da L-2, confirmação por cidadãos presentes (3 confirmações de cidadãos distintos em 700 m), denúncia com motivo em lista fechada (3 denúncias levam o lugar a disputado), retirada pelo autor e reativação por operador. Reincidência temporal, validação presencial sorteada e revalidação periódica ficam para a Fase 2.
Consome lugar.cadastrado da L-1 e lugar.georreferenciado da L-2. Produz lugar.validado e lugar.desativado, consumidos pela D-7. Não valida demandas. Não analisa cobertura. A análise de cobertura é da L-4.
A L-3 é uma colônia de escrita com face REST no MVP. Os endpoints das ações sociais recebem o header X-Cidadao-Id e respondem às ações do app. A L-3 não importa código de outras colônias; a única dependência externa é o núcleo (EventBus e Registry) e o helper compartilhado de distância.
1. Estrutura do Módulo NestJS
Seção intitulada “1. Estrutura do Módulo NestJS”1.1 Árvore de diretórios
Seção intitulada “1.1 Árvore de diretórios”src/lugar/l-3-validacao-qualidade/├── l3.module.ts # Module definition — OnModuleInit chama iniciar()├── l3.service.ts # Lógica de negócio: validação, confirmação, denúncia, retirada├── l3.repository.ts # Acesso a l3.status_lugares, l3.confirmacoes e l3.denuncias├── l3.controller.ts # Endpoints REST das ações sociais├── l3.constants.ts # Constantes: raio, mínimos, status, motivos e eventos└── dto/ ├── criar-confirmacao-lugar.dto.ts ├── criar-denuncia-lugar.dto.ts └── lugar-validacao-resposta.dto.ts1.2 Module definition
Seção intitulada “1.2 Module definition”@Module({ imports: [], controllers: [L3Controller], providers: [L3Service, L3Repository, PapelOperadorGuard], exports: [],})export class L3Module implements OnModuleInit { constructor(private readonly l3Service: L3Service) {}
async onModuleInit(): Promise<void> { await this.l3Service.iniciar(); }}O L3Module é registrado no app.module.ts ao lado de L1Module e L2Module.
1.3 Pontos de atenção
Seção intitulada “1.3 Pontos de atenção”- A colônia escreve somente no schema
l3. Nenhum acesso a schema de outra colônia. - O
PapelOperadorGuardprotege apenas a reativação. As ações sociais usam o headerX-Cidadao-Id. - A L-3 importa o helper
distanciaHaversineMetrosdesrc/duplicidade/haversine.ts. O helper é aritmética pura compartilhada, sem estado de outra colônia. - O
iniciar()segue a ordem do protocolo da N-0a: seed do cursor, replay e inscrição.
1.4 Serviço — responsabilidades e contrato
Seção intitulada “1.4 Serviço — responsabilidades e contrato”O L3Service concentra o consumo de eventos, as regras de validação e a publicação de saída. Os métodos públicos:
| Método | Responsabilidade |
|---|---|
iniciar() |
Seed do cursor, replay de eventos perdidos e registro dos consumidores |
processarLugarCadastrado(evento) |
Cria o registro provisorio com autor e coordenadas |
processarLugarGeorreferenciado(evento) |
Aplica a confirmação automática por confiança |
registrarConfirmacao(lugarId, cidadaoId, localizacao) |
Registra confirmação com presença e atualiza o total |
registrarDenuncia(lugarId, cidadaoId, motivo, localizacao) |
Registra denúncia com presença e atualiza o total |
retirar(lugarId, cidadaoId) |
Desativa o lugar pelo autor |
reativar(lugarId) |
Devolve o lugar disputado ou desativado a provisório |
1.5 Face REST no MVP
Seção intitulada “1.5 Face REST no MVP”A L-3 expõe endpoints das ações sociais. A face REST existe porque as ações são síncronas e iniciadas pelo app. O padrão de autenticação segue a D-12: header X-Cidadao-Id com UUID v4, sem token.
1.6 Protocolo de consumo com replay
Seção intitulada “1.6 Protocolo de consumo com replay”O iniciar() executa, nesta ordem:
- Seed do cursor:
seedOffsets(TIPOS_EVENTO_CONSUMIDOS, obterMaiorSequence()). O cursor nasce na maior sequência do log e não sobrescreve cursor existente. - Replay:
replayDeSequence(cursor, [tipo])para cada tipo consumido, despachado pelos handlers existentes. - Inscrição:
eventBus.inscrever(tipo, 'L-3', handler)só depois do replay.
O cursor avança em todo caminho terminal, inclusive nos descartes por validação, por escopo ou por idempotência. Handler que lança exceção não avança o cursor; o evento vai para a DLQ e o replay do boot seguinte retenta.
2. Banco de Dados — Schema e Entidades
Seção intitulada “2. Banco de Dados — Schema e Entidades”2.1 Schema l3
Seção intitulada “2.1 Schema l3”Quatro tabelas próprias. Nenhuma referência a schemas de outras colônias.
2.2 Tabela l3.status_lugares
Seção intitulada “2.2 Tabela l3.status_lugares”model l3_status_lugares { lugar_id String @id @db.Uuid cidadao_id String @db.Uuid localizacao_lat Float localizacao_lng Float status_confianca String @default("provisorio") @db.VarChar(20) metodo_validacao String? @db.VarChar(30) total_confirmacoes Int @default(0) total_denuncias Int @default(0) versao_dados Int @default(1) event_id String @db.Uuid correlacao_id String @db.Uuid publicacao_pendente Boolean @default(false) criado_em DateTime @default(now()) @db.Timestamptz(2) atualizado_em DateTime @default(now()) @updatedAt @db.Timestamptz(2)
@@map("status_lugares") @@schema("l3") @@index([status_confianca]) @@index([cidadao_id])}| Coluna | Descrição |
|---|---|
lugar_id |
Identificador do lugar. Chave primária e idempotência do cadastro. |
cidadao_id |
Autor do registro. Usado para excluir o autor das ações sociais. |
localizacao_lat/lng |
Coordenada do lugar, preservada para a checagem de presença de 700 m. |
status_confianca |
provisorio, confirmado, disputado ou desativado. |
metodo_validacao |
automatico, social, operador ou retirado_pelo_autor. Ausente enquanto provisório sem ação. |
total_confirmacoes |
Contador de confirmações de cidadãos distintos. |
total_denuncias |
Contador de denúncias de cidadãos distintos. |
versao_dados |
Incrementa a cada transição. Compõe o event_id determinístico da saída. |
event_id |
Evento de lugar.cadastrado que originou o registro. |
correlacao_id |
Correlação herdada do evento de origem. |
publicacao_pendente |
Marca que a última transição ainda não teve o evento publicado. A varredura do boot republica os pendentes com o mesmo event_id determinístico e limpa a marca. |
2.3 Tabela l3.confirmacoes
Seção intitulada “2.3 Tabela l3.confirmacoes”model l3_confirmacoes { confirmacao_id String @id @db.Uuid lugar_id String @db.Uuid cidadao_id String @db.Uuid localizacao_lat Float localizacao_lng Float distancia_metros Float criado_em DateTime @default(now()) @db.Timestamptz(2) evento_id String @unique @db.Uuid
@@map("confirmacoes") @@schema("l3") @@unique([lugar_id, cidadao_id]) @@index([lugar_id])}A chave única (lugar_id, cidadao_id) garante uma confirmação por cidadão e por lugar. A coluna evento_id é derivada do confirmacao_id e torna a projeção idempotente.
2.4 Tabela l3.denuncias
Seção intitulada “2.4 Tabela l3.denuncias”model l3_denuncias { denuncia_id String @id @db.Uuid lugar_id String @db.Uuid cidadao_id String @db.Uuid motivo String @db.VarChar(30) localizacao_lat Float localizacao_lng Float distancia_metros Float criado_em DateTime @default(now()) @db.Timestamptz(2) evento_id String @unique @db.Uuid
@@map("denuncias") @@schema("l3") @@unique([lugar_id, cidadao_id]) @@index([lugar_id])}Mesma estrutura da confirmação, com motivo em lista fechada: nao_existe, dados_incorretos, duplicado e inadequado.
2.5 Tabela l3.consumer_offset
Seção intitulada “2.5 Tabela l3.consumer_offset”model l3_consumer_offset { tipo_evento String @id @db.VarChar(255) last_sequence BigInt @default(0) updated_at DateTime @default(now()) @db.Timestamptz(2)
@@map("consumer_offset") @@schema("l3")}2.6 Migrations
Seção intitulada “2.6 Migrations”20260914120000_l3_validacao_lugares cria o schema l3 e as quatro tabelas. 20260918190000_l3_publicacao_pendente adiciona a coluna publicacao_pendente a l3.status_lugares. Aplicadas com migrate deploy no container e prisma generate no host e no container.
2.7 Relações internas
Seção intitulada “2.7 Relações internas”l3.status_lugares é a raiz por lugar_id. l3.confirmacoes e l3.denuncias apontam para o lugar por lugar_id, sem chave estrangeira declarada entre schemas. Os totais ficam desnormalizados no status para a leitura rápida.
2.8 Decisões de schema
Seção intitulada “2.8 Decisões de schema”- Totais desnormalizados em
status_lugaresevitam contagem a cada leitura e tornam o payload delugar.validadouma leitura de linha única. versao_dadoscompõe oevent_iddeterminístico. O retry inline, a varredura de pendentes e o replay republicam a mesma versão sem duplicar o evento no barramento.- A marca
publicacao_pendenteé gravada na mesma atualização que incrementaversao_dadose limpa após a publicação. A varredura do boot recupera a saída perdida sem consultar o log de eventos. - A coordenada do autor da confirmação e da denúncia é privada. Nenhum endpoint público devolve a linha individual.
3. Eventos — Contratos Detalhados
Seção intitulada “3. Eventos — Contratos Detalhados”3.1 Evento consumido: lugar.cadastrado
Seção intitulada “3.1 Evento consumido: lugar.cadastrado”| Propriedade | Valor |
|---|---|
| Tipo | lugar.cadastrado |
| Schema version | 1.2.0 (versões 1.0.0 e 1.1.0 continuam aceitas) |
| Produtor | L-1 |
| Consumidor | L-3 (validação) e D-7 (projeção) |
| Descrição | Lugar registrado com status pendente_georreferenciamento. |
Campos usados pela L-3: lugar_id, tipo_lugar, coordenadas_brutas e cidadao_id. O campo descricao da versão 1.2.0 não é usado pela L-3.
Regras do handler:
- Payload inválido (sem
lugar_id,tipo_lugar,cidadao_idou coordenadas): descarta e avança o cursor. - Tipo
residenciaoupoligono_uc: descarta por LGPD e por escopo, com cursor avançado. - Lugar já registrado: idempotente, avança o cursor sem sobrescrever o estado.
- Caminho normal: insere
l3.status_lugarescomoprovisorio, comversao_dados = 1.
3.2 Evento consumido: lugar.georreferenciado
Seção intitulada “3.2 Evento consumido: lugar.georreferenciado”| Propriedade | Valor |
|---|---|
| Tipo | lugar.georreferenciado |
| Schema version | 1.0.0 |
| Produtor | L-2 |
| Consumidor | L-3, L-1 e E-1 |
| Descrição | Lugar com UC resolvida e tipificação enriquecida. |
Campos usados pela L-3: lugar_id, confianca_geo, confianca_tipificacao e enriquecimento.divergencia.
Regras do handler:
- Lugar sem registro na L-3: descarta com aviso e avança o cursor.
- Lugar com status diferente de
provisorio: ignora a validação automática e avança o cursor. - Confiança
altaem geo e tipificação e sem divergência: confirma commetodo_validacao = 'automatico'e publicalugar.validado. - Fora do limiar: mantém
provisoriosem publicar.
3.3 Evento produzido: lugar.validado
Seção intitulada “3.3 Evento produzido: lugar.validado”| Propriedade | Valor |
|---|---|
| Tipo | lugar.validado |
| Schema version | 1.0.0 |
| Produtor | L-3 |
| Consumidor | D-7 |
| Descrição | Status de confiança do lugar atualizado. |
{ "lugar_id": "uuid", "status_confianca": "provisorio | confirmado | disputado", "metodo_validacao": "automatico | social | operador", "total_confirmacoes": 0, "total_denuncias": 0, "versao_dados": 1}Obrigatórios: lugar_id, status_confianca, total_confirmacoes, total_denuncias e versao_dados. metodo_validacao é opcional e ausente enquanto o lugar é provisório sem ação. O status desativado não circula neste evento; a desativação usa lugar.desativado.
O evento é publicado em toda confirmação e denúncia aceitas, mesmo quando o status não muda. O total atualizado chega à D-7 sem consulta adicional.
3.4 Evento produzido: lugar.desativado
Seção intitulada “3.4 Evento produzido: lugar.desativado”| Propriedade | Valor |
|---|---|
| Tipo | lugar.desativado |
| Schema version | 1.0.0 |
| Produtor | L-3 |
| Consumidor | D-7 |
| Descrição | Lugar retirado do mapa público. |
{ "lugar_id": "uuid", "motivo": "denuncias | retirado_pelo_autor | operador"}No MVP, apenas retirado_pelo_autor é publicado. Os motivos denuncias e operador ficam para a Fase 2, quando a disputa tiver revisão manual.
3.5 Redação na persistência
Seção intitulada “3.5 Redação na persistência”lugar.cadastrado:descricaoentra empermitidos. O campo é conteúdo público do lugar, exposto no painel de detalhes, e não é dado pessoal do titular.lugar.validado:permitidoscom todos os campos do schema. Sem dado pessoal e sem coordenada.lugar.desativado:permitidoscomlugar_idemotivo.lugar.georreferenciadopermanece sem regra. O payload não tem campo pessoal.
3.6 Tratamento de erro e idempotência
Seção intitulada “3.6 Tratamento de erro e idempotência”- Handlers de consumo são idempotentes por
lugar_ide porevent_id. Replay e reentrega não duplicam registros. - A unicidade
(lugar_id, cidadao_id)em confirmações e denúncias protege contra corrida. A violaçãoP2002vira 409 com o identificador existente. - O
event_iddos eventos publicados é derivado deuuidv5com namespace fixo:lugar.validado:{lugar_id}:{versao_dados}elugar.desativado:{lugar_id}:{versao_dados}. O retry republica o mesmo evento. - A coluna
evento_iddel3.confirmacoesel3.denunciastambém é derivada poruuidv5:lugar.confirmacao:{confirmacao_id}elugar.denuncia:{denuncia_id}. A unicidade da coluna torna as projeções idempotentes. - A publicação usa
publicarComRetry(4 tentativas com backoff exponencial a partir de 500 ms). A falha definitiva propaga o erro e o status já está persistido compublicacao_pendente = true. A varredurarepublicarPublicacoesPendentesdo boot republicalugar.validadoelugar.desativadocom o mesmoevent_iddeterminístico e limpa a marca. O barramento descarta a duplicata quando a publicação original chegou.
4. Lógica de Negócio — Algoritmos e Fluxos
Seção intitulada “4. Lógica de Negócio — Algoritmos e Fluxos”4.1 processarLugarCadastrado()
Seção intitulada “4.1 processarLugarCadastrado()”lugar.cadastrado recebido→ extrai lugar_id, tipo_lugar, cidadao_id e coordenadas_brutas→ payload inválido: descarta e avança o cursor→ tipo_lugar fora de [organizacao, equipamento_publico]: descarta e avança o cursor→ lugar já existe em l3.status_lugares: avança o cursor (idempotente)→ insere status provisorio com autor, coordenadas, versao_dados = 1→ avança o cursor4.2 processarLugarGeorreferenciado() — confirmação automática
Seção intitulada “4.2 processarLugarGeorreferenciado() — confirmação automática”lugar.georreferenciado recebido→ extrai lugar_id→ lugar sem registro na L-3: descarta com aviso e avança o cursor→ status diferente de provisorio: ignora e avança o cursor→ confianca_geo = alta e confianca_tipificacao = alta e sem enriquecimento.divergencia: → status = confirmado, metodo_validacao = automatico, versao_dados += 1 → publica lugar.validado→ caso contrário: mantém provisorio, sem publicar→ avança o cursor4.3 registrarConfirmacao()
Seção intitulada “4.3 registrarConfirmacao()”registrarConfirmacao(lugarId, cidadaoId, localizacao)→ valida UUIDs e coordenadas→ lugar inexistente: 404→ status terminal (disputado ou desativado): 409→ autor do lugar: 400→ distância Haversine acima de 700 m: 400→ confirmação existente do mesmo cidadão: 409 com o identificador→ insere confirmação com distancia_metros→ total = contagem de confirmações do lugar→ total >= 3 e status = provisorio: status = confirmado, metodo_validacao = social→ atualiza status com o total e versao_dados += 1→ publica lugar.validado→ resposta: confirmacao_id, total_confirmacoes, status_confianca4.4 registrarDenuncia()
Seção intitulada “4.4 registrarDenuncia()”registrarDenuncia(lugarId, cidadaoId, motivo, localizacao)→ valida UUIDs, coordenadas e motivo em lista fechada→ lugar inexistente: 404→ status terminal: 409→ autor do lugar: 400→ distância acima de 700 m: 400→ denúncia existente do mesmo cidadão: 409 com o identificador→ insere denúncia com motivo e distancia_metros→ total = contagem de denúncias do lugar→ total >= 3: status = disputado, metodo_validacao = social→ atualiza status com o total e versao_dados += 1→ publica lugar.validado→ resposta: denuncia_id, total_denuncias, status_confiancaA denúncia não publica lugar.desativado. O lugar disputado sai do mapa público pelo filtro da D-7 e aguarda reativação por operador.
4.5 retirar()
Seção intitulada “4.5 retirar()”retirar(lugarId, cidadaoId)→ valida UUIDs→ lugar inexistente: 404→ cidadão diferente do autor: 403 sem revelar a autoria→ status terminal: 409→ status = desativado, metodo_validacao = retirado_pelo_autor, versao_dados += 1→ publica lugar.desativado com motivo retirado_pelo_autor→ resposta: lugar_id, status_confianca = desativado4.6 reativar()
Seção intitulada “4.6 reativar()”reativar(lugarId)→ valida UUID→ lugar inexistente: 404→ status não terminal: 409→ status = provisorio, metodo_validacao = operador, versao_dados += 1→ publica lugar.validado→ resposta: lugar_id, status_confianca = provisorioA reativação preserva os totais e o histórico. O lugar volta ao mapa público para nova validação social.
4.7 iniciar() — protocolo de inicialização
Seção intitulada “4.7 iniciar() — protocolo de inicialização”iniciar()→ guarda de idempotência (iniciado)→ maiorSequence = eventBus.obterMaiorSequence()→ seedOffsets([lugar.cadastrado, lugar.georreferenciado], maiorSequence)→ para cada tipo: replayDeSequence(cursor, [tipo]) e despacho pelo handler→ inscreve lugar.cadastrado e lugar.georreferenciado→ republicaPublicacoesPendentes(): busca até 100 status com publicacao_pendente, republica lugar.validado ou lugar.desativado com o mesmo event_id e limpa a marca4.8 Casos de borda
Seção intitulada “4.8 Casos de borda”| Caso | Comportamento |
|---|---|
| Evento de lugar residência ou polígono de UC | Descarte com cursor avançado. |
lugar.georreferenciado sem registro na L-3 |
Descarte com aviso e cursor avançado. |
Lugar já confirmado recebe lugar.georreferenciado |
Validação automática ignorada. |
| Coordenada degradada pelo replay | A redação arredonda a coordenada no log para cerca de 1 km. Eventos processados ao vivo preservam a coordenada exata. A presença de 700 m pode degradar no replay. |
| Duas confirmações simultâneas do mesmo cidadão | A unicidade do banco resolve; uma vira 409. |
| Confirmação e denúncia do autor | 400. |
4.9 Decisões de design
Seção intitulada “4.9 Decisões de design”- O status
provisorioé o estado inicial e o estado de retorno da reativação. O lugar provisório fica visível no mapa com marcação distinta. - A confirmação automática é conservadora: exige
altanas duas confianças e ausência de divergência. - A denúncia dispara disputa, não desativação. A reativação é manual, por operador.
- A retirada é exclusiva do autor e não revela a autoria para terceiros.
- A publicação é recuperável: a transição grava
publicacao_pendente, a publicação bem-sucedida limpa a marca e a varredura do boot republica o que ficou pendente com oevent_iddeterminístico.
5. Endpoints REST
Seção intitulada “5. Endpoints REST”Todos com @ApiTags, @ApiOperation e @ApiResponse completos, no padrão da D-12. Header X-Cidadao-Id obrigatório nas ações sociais.
5.1 POST /api/l3/lugares/:lugar_id/confirmacoes
Seção intitulada “5.1 POST /api/l3/lugares/:lugar_id/confirmacoes”| Propriedade | Valor |
|---|---|
| Status | 201 |
| Rate limit | 5/min |
| Corpo | { localizacao_lat, localizacao_lng } |
| Resposta | { confirmacao_id, total_confirmacoes, status_confianca } |
| Erros | 400 header ausente, DTO inválido, autor ou fora do raio; 404 lugar inexistente; 409 repetida ou status terminal; 429 rate limit |
5.2 POST /api/l3/lugares/:lugar_id/denuncias
Seção intitulada “5.2 POST /api/l3/lugares/:lugar_id/denuncias”| Propriedade | Valor |
|---|---|
| Status | 201 |
| Rate limit | 5/min |
| Corpo | { motivo, localizacao_lat, localizacao_lng } |
| Resposta | { denuncia_id, total_denuncias, status_confianca } |
| Erros | 400 header ausente, motivo inválido, autor ou fora do raio; 404 lugar inexistente; 409 repetida ou status terminal; 429 rate limit |
5.3 POST /api/l3/lugares/:lugar_id/retirada
Seção intitulada “5.3 POST /api/l3/lugares/:lugar_id/retirada”| Propriedade | Valor |
|---|---|
| Status | 200 |
| Rate limit | 5/min |
| Corpo | vazio |
| Resposta | { lugar_id, status_confianca: 'desativado' } |
| Erros | 400 header ausente; 403 terceiro; 404 lugar inexistente; 409 status terminal; 429 rate limit |
5.4 POST /api/l3/lugares/:lugar_id/reativar
Seção intitulada “5.4 POST /api/l3/lugares/:lugar_id/reativar”| Propriedade | Valor |
|---|---|
| Status | 200 |
| Rate limit | 60/min |
| Guard | PapelOperadorGuard |
| Resposta | { lugar_id, status_confianca: 'provisorio' } |
| Erros | 401 token ausente; 403 sem papel; 404 lugar inexistente; 409 status não terminal; 429 rate limit |
6. Integração com o Barramento e Outras Colônias
Seção intitulada “6. Integração com o Barramento e Outras Colônias”6.1 Cadeia completa
Seção intitulada “6.1 Cadeia completa”D-1a → lugar.recebido → L-1 → lugar.cadastrado 1.2.0 → L-2 → lugar.georreferenciado → L-3 → lugar.validado / lugar.desativado → D-7 → d7.lugares_geo (status_confianca, metodo_validacao, total_confirmacoes)6.2 Consumidores a jusante
Seção intitulada “6.2 Consumidores a jusante”A D-7 consome lugar.validado e lugar.desativado e mantém a projeção d7.lugares_geo. O GET /api/d7/lugares filtra disputado e desativado e devolve status_confianca. O GET /api/d7/lugar/:lugar_id/resumo devolve 404 para lugar disputado ou desativado.
6.3 Chamadas síncronas
Seção intitulada “6.3 Chamadas síncronas”A L-3 não chama outras colônias. A face REST responde ao app e publica eventos. A comunicação com as demais colônias é exclusivamente via barramento.
7. Performance e Limites
Seção intitulada “7. Performance e Limites”- A checagem de presença usa Haversine em memória, pela função compartilhada
distanciaHaversineMetrosdesrc/duplicidade/haversine.ts. Sem PostGIS no MVP. - O status é leitura de linha única por
lugar_id; as contagens usam índice porlugar_id. - O replay do boot é paginado em lotes de 1000 pelo EventBus. A varredura de publicações pendentes cobre até 100 linhas por boot.
- A unicidade
(lugar_id, cidadao_id)resolve a corrida de confirmações e denúncias sem lock de aplicação.
8. Testes
Seção intitulada “8. Testes”Cobertura do subconjunto no MVP:
- Serviço: criação provisória, confirmação automática, 3 confirmações, autor excluído, fora do raio, 3 denúncias, retirada, reativação, repetição, replay sem duplicata e republicação de publicação pendente no boot.
- Controller: 400 sem header, 400 autor, 400 fora do raio, 404, 409 terminal, 409 repetido, 403 na retirada de terceiro, 401/403 na reativação e 429.
- Isolamento: nenhum import de outra colônia e nenhum acesso a schema de outra colônia.
9. Parâmetros públicos
Seção intitulada “9. Parâmetros públicos”| Parâmetro | Valor | Domínio | Fonte | Revisão |
|---|---|---|---|---|
| Raio de presença da validação de lugar | 700 m | L-3 | l3.constants.ts |
fixo_mvp |
| Confirmações para confirmar lugar | 3 de cidadãos distintos | L-3 | l3.constants.ts |
fixo_mvp |
| Denúncias para disputar lugar | 3 de cidadãos distintos | L-3 | l3.constants.ts |
fixo_mvp |
| Confirmação automática de lugar | confianca_geo='alta' e confianca_tipificacao='alta' sem divergência |
L-3 | l3.constants.ts |
fixo_mvp |
| Rate limit de confirmações de lugar | 5/min | L-3 | l3.controller.ts |
fixo |
| Rate limit de denúncias de lugar | 5/min | L-3 | l3.controller.ts |
fixo |
| Rate limit de retirada de lugar | 5/min | L-3 | l3.controller.ts |
fixo |
| Rate limit de reativação de lugar | 60/min | L-3 | l3.controller.ts |
fixo |
10. LGPD
Seção intitulada “10. LGPD”- A L-3 guarda o
cidadao_iddo autor e das ações sociais para impedir repetição e excluir o autor. Nenhum identificador de confirmador ou denunciante entra em evento público ou endpoint de leitura. - A coordenada de presença é guardada apenas no schema
l3, com a distância calculada. Nenhum endpoint público devolve a linha individual. - A N-0d anonimiza
l3.status_lugares.cidadao_id,l3.confirmacoes.cidadao_idel3.denuncias.cidadao_idna eliminação do titular. - A redação do log de eventos remove
cidadao_iddos payloads persistidos e arredonda coordenadas ao nível da UC.
11. Pendências para a Fase 2
Seção intitulada “11. Pendências para a Fase 2”- Reincidência temporal: múltiplos cidadãos cadastrando o mesmo lugar em janela de tempo. Agrupamento por proximidade com DBSCAN e Haversine.
- Validação social presencial sorteada: sorteio auditável de cidadãos com vínculo validado na UC, no padrão da D-6a, com foto e geolocalização no raio.
- Evento
lugar.validação_social_solicitadae evento consumidolugar.validação_social_concluída. - Revalidação periódica de lugares confirmados a cada 24 meses.
- Deduplicação definitiva de lugares, substituindo o alerta de proximidade da L-1.
- Revisão manual do operador para disputas por denúncia, com tela própria. No MVP existe apenas a reativação por endpoint.
- Foto de validação processada pela D-1c, com hash SHA-256 e metadados EXIF.