# Ouvidoria (Ombudsman) — Resumo Executivo

> **Versão analisada:** `v6` (referência atual) e `v5` (versão anterior, para o comparativo)
> **Slug do módulo:** `ouvidoria` — registrado em `modulos` (id 56) e `resources` (id 76)
> **Natureza:** CMS (painel administrativo) + Portal (público)
> **Estado:** migrado v5 → v6 (com **regressão**: o módulo de Relatório Estatístico de Ouvidoria do CMS existia na v5 e **não existe** na v6)

---

## 1. Objetivo

A Ouvidoria é o canal formal de manifestação da população. O módulo permite ao cidadão protocolar uma **manifestação** (reclamação, denúncia, solicitação, sugestão, elogio ou pedido de informação), classificando-a por tipo, assunto, forma de resposta e origem, com três modalidades de anonimato — **identificado**, **sigiloso** e **anônimo**. O operador do CMS recebe a manifestação, registra o histórico de tramitação, responde (com texto e anexos) ou indefere, prorroga o prazo, ou encaminha o chamado para outro setor/assunto. O cidadão acompanha o andamento pelo número de protocolo e pode **contestar** a resposta recebida. Publicamente, o portal exibe um **relatório estatístico** com indicadores de prazo e permite exportar a lista de manifestações.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Protocola manifestação com protocolo automático, acompanha o status por protocolo e contesta a resposta; consulta o relatório estatístico público e baixa a lista exportável. |
| Prefeitura (CMS) | Triagem de chamados por tipo/assunto/setor, resposta ou indeferimento com e-mail e anexos, prorrogação de prazo, encaminhamento entre setores com trilha de auditoria e cadastro das tabelas de apoio (assuntos, setores, origens, tipos, formas de resposta, respostas prontas). |
| Transparência e legalidade | Publica o relatório estatístico de atendimento (prazos cumpridos/estourados, por status), atende à Lei de Acesso à Informação e à LGPD (mascaramento de dados pessoais em texto livre e no relatório público). |
| Operação técnica | 8 controllers CMS + 1 controller de portal, 9 models, 8 Form Requests, 18 migrations + 1 de view, 6 seeds, ~90 views Blade (CMS, e-mails e 6 modelos de portal), 12 arquivos JS. |

## 3. Comportamento

### 3.1 Ciclo de vida do chamado

| Etapa | Gatilho | Status resultante | Efeito colateral |
|---|---|---|---|
| Protocolar | Cidadão envia o formulário do portal | 1 = Em Tramitação | Grava `ombudsman_requests` com protocolo único, token de contestação hasheado e `mask_description`; envia 2 e-mails (cidadão e setor) |
| Responder | Operador no CMS, `type=1` | 2 = Atendido | Grava `ombudsman_answers` + `mask_answer`; envia e-mail ao cidadão |
| Indeferir | Operador no CMS, `type=0` | 3 = Indeferido | idem, com template de indeferimento |
| Prorrogar | Operador no CMS | 4 = Prorrogado | Envia e-mail "PRORROGADO" ao cidadão |
| Encaminhar | Operador no CMS | (inalterado) | Troca o assunto, grava log `forward`, reenvia por e-mail |
| Contestar | Cidadão, com o token | (inalterado) | Grava `answer_contestation` ou `answer_contestation_2` |

### 3.2 Regras de negócio

- **Protocolo**: gerado no ato do envio como `'OUV-' . now()->format('dmY-His')` — único (constraint UNIQUE). **Risco de colisão** em dois chamados no mesmo segundo.
- **Status** (tabela `statuses`): 1 = Em Tramitação, 2 = Atendido, 3 = Indeferido, 4 = Prorrogado, 5 = Aberta, 6 = Finalizada, 7 = Cancelada. O módulo usa ativamente 1, 2, 3 e 4; os demais ficam sem uso.
- **Modalidades**: `identificado`, `sigiloso`, `anonimo`. O portal desabilita os campos pessoais quando a modalidade é anônima.
- **Resposta**: `OmbudsmanAnswerController@store` grava em `ombudsman_answers` e muda o status para 2 (atendido, `type=1`) ou 3 (indeferido, `type=0`).
- **Prorrogação**: `OmbudsmanRequestController@prorrogar_chamado` muda o status para 4 e envia e-mail "PRORROGADO".
- **Encaminhamento**: `enviar_chamado` troca o assunto do chamado (por título), grava um `ombudsman_request_logs` do tipo `forward` com setor/assunto de origem e destino, e reenvia o chamado por e-mail.
- **Contestação**: o cidadão recebe um `token` no ato do envio; `Portal\OmbudsmanController@newMessage` valida o token por `Hash::check` e grava até **duas** contestações (`answer_contestation` e `answer_contestation_2`).
- **LGPD**: toda descrição e toda resposta têm uma versão mascarada (`mask_description`, `mask_answer`) gerada por `DataMaskTrait`; o relatório público usa `masked_protocol` e `masked_name`.
- **Relatório estatístico**: agrega por ano e status, comparando a data da resposta com a data do pedido para classificar em "no prazo" (≤ 20 dias) ou "após o prazo" (> 20 dias). O limite de 20 dias é **hardcoded** no `whereRaw` do model e **não** vem de `configurations.response_time`, que é a fonte usada para informar o prazo ao cidadão.
- **Bloqueio de exclusão**: um setor/órgão com assuntos vinculados não pode ser excluído — nem individualmente, nem em lote (resposta 422 com a lista dos bloqueados).
- **Roteamento**: o e-mail do novo chamado vai para o `email` do **assunto** selecionado, e não para a secretaria.

## 4. Como o Usuário Interage

**Portal** (`/ouvidoria`):
- Página institucional da Ouvidoria (conteúdo de página estática) com o formulário de manifestação: modalidade, tipo, assunto (agrupado por setor), forma de resposta, origem, dados de contato, endereço, mensagem, token de contestação e captcha.
- Após o envio, mostra a página "Ouvidoria Solicitada" com o protocolo e o prazo de resposta (`configurations.response_time`).
- "Consultar Solicitação de Ouvidoria" (acesso rápido): busca por protocolo, mostra status, solicitante, data, descrição, respostas e contestações.
- "Relatório Estatístico da Ouvidoria": gráficos, tabela e exportações em **xls**, **csv**, **pdf** e **txt**.

**CMS** (`/cms/chamados-da-ouvidoria`):
- Listagem de chamados com colunas: protocolo, tipo, assunto, setor, modalidade, status, data e ações (visualizar, enviar, responder, prorrogar).
- Modais de visualização e de reenvio; tela de resposta (Bootstrap-WYSIHTML5 + respostas prontas + anexos) e tela de indeferimento.
- CRUDs de apoio: Assuntos, Setores/Órgãos, Tipos de Chamado, Formas de Resposta, Origens de Chamado, Respostas Prontas.

## 5. Detalhes e Particularidades Técnicas

- **Namespaces divergentes**: os models vivem em `v6/app/Http/Model/Prefecture/Ombudsman*.php` mas declaram `namespace App\Models` (exceto `OmbudsmanAnswer`, que declara `App\Prefecture`). O autoload funciona por `classmap`.
- **Sem repositories**: controllers usam Eloquent direto.
- **Validação**: Form Requests no CMS (`OmbudsmanSubjectRequest`, `OmbudsmanSectorRequest`, `OmbudsmanOriginRequest`, `OmbudsmanResponseMethodRequest`, `OmbudsmanManifestationTypeRequest`, `OmbudsmanCannedResponseRequest`, `OmbudsmanAnswerRequest`); no portal, um método `validated()` próprio do controller.
- **Listagens**: 7 views SQL (`chamados_ouvidoria`, `assuntos_ouvidoria`, `ouvidoria_setores_orgaos`, `ouvidoria_tipos_chamado`, `ouvidoria_formas_resposta`, `ouvidoria_origens_chamado`, `ouvidoria_respostas_prontas`) consumidas por `Prefecture\DatatableController`.
- **E-mail**: 9 templates Blade em `v6/resources/views/prefecture/emails/ombudsman-*`.
- **Risco verificado**: 7 dos 8 controllers CMS sobrescrevem `__construct` sem chamar `parent::__construct()`, o que impede o registro do middleware `check.route.permission`.

## 6. Estrutura de Dados

9 tabelas (`ombudsman_requests`, `ombudsman_answers`, `ombudsman_subjects`, `ombudsman_sectors`, `ombudsman_origins`, `ombudsman_response_methods`, `ombudsman_manifestation_types`, `ombudsman_canned_responses`, `ombudsman_request_logs`), 7 views SQL e a tabela de apoio `statuses`. Detalhe em `02-MODELAGEM.md`.

## 7. Como Testar

Cenários manuais e automatizados propostos em `07-TESTES.md` — cobrem o ciclo completo do chamado (criação → resposta → contestação), as regras de prazo do relatório estatístico, o mascaramento LGPD e as permissões.

## 8. Migração para Laravel Moderno

Reescrever com Form Requests tipados, Policies por verbo, Resources JSON (com **exposição condicional** do token de contestação), enums para status/modalidade/tipo, `spatie/laravel-activitylog` para a trilha de tramitação (hoje há uma tabela própria `ombudsman_request_logs` com uso parcial) e uma fila para o envio de e-mails. Detalhe em `06-MIGRACAO-MODERNA.md`.

## 9. Resumo Geral

A Ouvidoria é um dos módulos mais maduros da plataforma: existe nas duas versões, com CRUDs de apoio, e-mail transacional, relatório estatístico público e mascaramento de dados pessoais alinhado à LGPD. A v6 introduziu **setores/órgãos** como entidade de primeira classe (substituindo o vínculo direto com `contents`), a tabela de histórico de tramitação e o mascaramento por IA de descrições e respostas. Em contrapartida, a v6 **perdeu** o módulo de Relatório Estatístico de Ouvidoria que existia na v5 — aquele permitia ao operador cadastrar relatórios anuais em PDF (ano, descrição, arquivo), listá-los no CMS e exibi-los no portal; hoje só resta o relatório **dinâmico**, calculado a partir de `ombudsman_requests`, sem cadastro nem PDF institucional. Há ainda lacunas estruturais: sete controllers sem o middleware de permissão, models com relações apontando para classes inexistentes (`App\Ombudsman`, `App\OmbudsmanRequest`), o método `archives()` comentado enquanto o controller chama `attach()` numa tabela pivô que **não existe** na v6, e o `update()` de chamado que altera **sempre o primeiro registro** da tabela. Todos esses pontos estão catalogados em `08-GAPS-E-DIVIDAS.md`, e o mapa v5 → v6 em `09-MAPA-V5-V6.md`.

---

## Índice do dossiê

| Arquivo | Conteúdo |
|---|---|
| `00-RESUMO.md` | Este documento |
| `01-ARQUITETURA.md` | Camadas, classes, diagrama de fluxo e dependências |
| `02-MODELAGEM.md` | Tabelas, colunas, FKs, relacionamentos e views SQL |
| `03-ROTAS-E-CONTROLADORES.md` | Rotas CMS/Portal, controllers, Form Requests, permissões |
| `04-VIEWS-E-UX.md` | Blades do CMS, e-mails, portal, JS/Ajax e exportações |
| `05-REGRAS-E-PORTABILIDADE.md` | Regras de negócio, acoplamentos e armadilhas |
| `06-MIGRACAO-MODERNA.md` | Schema Laravel 11/12, models, Requests, Policies, Resources |
| `07-TESTES.md` | Estratégia, fixtures e casos de teste concretos |
| `08-GAPS-E-DIVIDAS.md` | Bugs, funcionalidades mortas, riscos e prioridades |
| `09-MAPA-V5-V6.md` | **Comparativo v5 → v6 e a regressão do Relatório Estatístico** |
| `10-FLUXO-DO-CHAMADO.md` | **Ciclo de vida do chamado ponta a ponta (foco do módulo)** |
| `11-PLANO-DE-IMPLANTACAO.md` | Fases 2 e 3: Policies, endpoints, Resources, views modernas, fila, riscos |

## 10. Como este dossiê está organizado

A leitura mínima para entender o módulo é `00-RESUMO.md` → `01-ARQUITETURA.md` → `10-FLUXO-DO-CHAMADO.md`. Quem vai **reconstruir** o módulo deve ler, nesta ordem: `02-MODELAGEM.md` (o que existe hoje), `05-REGRAS-E-PORTABILIDADE.md` (o que não pode ser quebrado), `08-GAPS-E-DIVIDAS.md` e `09-MAPA-V5-V6.md` (o que precisa ser consertado e o que foi perdido), e por fim `06-MIGRACAO-MODERNA.md` + `11-PLANO-DE-IMPLANTACAO.md` (o plano). `03-ROTAS-E-CONTROLADORES.md` e `04-VIEWS-E-UX.md` servem de referência de contrato para quem for reescrever as rotas e as telas; `07-TESTES.md` é o contrato de qualidade.

Os documentos distinguem explicitamente o que foi **verificado no código/banco** do que é **[INFERÊNCIA]** ou **[NÃO VERIFICADO]**. Três pontos exigem teste em ambiente real e estão sinalizados: o **middleware de permissão** dos 7 controllers (seção 2.2 dos gaps), a **validação de `modality`** no portal (seção 2.4 dos gaps) e o **`EXTRACT(DAY …)`** do relatório — este último já foi verificado no banco e está correto na contagem de dias, com as ressalvas registradas.
