# Revisões — Resumo Executivo

> **Versão analisada:** `v6` (e `v5` para o comparativo)
> **Slug do módulo:** `revisoes` (tabela `modulos`, id 34) — `v6/database/migrations/2024_11_01_150206_create_modulos_table.php:227-232`
> **Natureza:** CMS (painel administrativo) exclusivamente — **não há rota pública no portal**
> **Estado:** OK v6 (funcionalmente equivalente à v5, com uma retificação de respostas removida)

---

## 0. Identificação — cuidado com o falso amigo

O módulo **não** é um changelog de versões do portal. O nome "Revisões" no CMS designa o
**sistema de avaliação (quality assessment) da qualidade dos sites institucionais** —
Prefeitura e Câmara Municipal. Ele é o mesmo motor conceitual de:

- `ratings` (o **formulário de avaliação**),
- `questions` / `question_categories` / `question_types` (as **perguntas**),
- `options` / `option_categories` (as **alternativas de resposta**),
- `send_ratings` (os **envios/avaliações**),
- `answer_forms` (as **respostas**),
- `email_revisoes` (os **destinatários de e-mail** do resultado).

A pista `PrefeituraRevSeeder` / `CamaraRevSeeder` do enunciado refere-se exatamente a este
sistema: os dois seeders criam a avaliação "Prefeitura" e a avaliação "Câmara", cada uma com
suas categorias e perguntas.

O changelog do portal é outra coisa (`v6/database/seeds/ChangeLogTableSeeder.php`), sem
relação com este módulo.

### Distinção crítica: "Revisões" × "Formulários Dinâmicos"

| Subsistema | Tabelas | Objetivo |
|---|---|---|
| **Revisões** (este módulo) | `ratings`, `questions`, `send_ratings`, `answer_forms`, `email_revisoes`, `question_types`, `question_categories`, `options`, `option_categories`, `option_category_has_options` | Avaliação da qualidade do site institucional (Prefeitura/Câmara), com pontuação e PDF |
| **Formulários Dinâmicos** (módulo `formularios-dinamicos`, id 52) | `questionnaires`, `filled_questionnaires` | Formulários de atendimento ao cidadão, sem cálculo de pontuação |

Ambos usam a palavra "formulário" e as telas do CMS ficam em
`v6/resources/views/prefecture/configurations/revisoes/formularios/`, mas são
implementações totalmente separadas. Ver `../formularios-dinamicos/`.

---

## 1. Objetivo

O módulo permite que a prefeitura **monte um formulário de avaliação da qualidade do seu
próprio site institucional** (e o da Câmara), com perguntas ponderadas agrupadas em
categorias, e depois registre o resultado dessa avaliação. Cada questionamento aplicado a um
avaliador gera um **envio** com protocolo, pontuação final, PDF assinado e envio por e-mail.
O objetivo é produzir evidência documental auditável sobre o estado do site (licitações,
contratos, transparência, LGPD,_series histórica) para fins de controle interno, resposta ao
Tribunal de Contas e transparência ativa.

Serve ao **operador do CMS** (prefeitura), que monta o questionário, aplica a avaliação e
distribui o PDF; e ao **público interno**, que recebe o PDF por e-mail. O cidadão **não**
interage com o módulo: não há rota em `v6/routes/web.php` nem em `v6/routes/api.php`.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Nenhum efeito direto: nenhuma tela pública. O impacto é indireto, pela pressão de conformidade que o relatório gera |
| Prefeitura (CMS) | Ferramenta de autoauditoria: cria questionário, aplica avaliação, obtém nota por categoria, PDF e gráficos anuais |
| Transparência e legalidade | O PDF e os gráficos evidenciam o cumprimento de LAI, licitações, contratos, LGPD e transparency fiscal — insumo de controle do TCE |
| Operação técnica | Motor genérico de questionário reaproveitado de v5 para v6 sem reescrita; 100% concentrado no CMS, sem exposição pública |

## 3. Comportamento

1. **Exclusividade de revisão ativa**: só pode existir **uma** avaliação com `status = true`
   (a "revisão vigente"). `RatingsController::reverseAllStates()` desativa todas as outras
   antes de ativar uma nova. `store`, `update` e `setStatus` aplicam essa regra.
2. **Hierarquia de categorias**: `question_categories` é uma árvore (auto-FK
   `question_categories_id`) com campo `order` para ordenação manual.
3. **Perguntas ponderadas**: cada `questions` tem `value` (peso) e aponta para um
   `question_types` (apenas "Resposta única" está ativo) e para uma `option_categories`
   (grupo de alternativas: "Comum" = Sim/Não/Parcial, "Satisfação" = escala).
4. **Aplicação da avaliação**: o operador preenche o formulário em `respostas/create/{id}`;
   o sistema cria um `send_ratings` (protocolo, revisor, data), grava um `answer_forms` por
   pergunta (opção + observação), calcula `pts_finais` / `pts_totais` e gera o PDF.
5. **Escore**: só a opção cuja `description` é exatamente **"Sim"** soma peso
   (`QuestionAnswersController::pontuacao()` e `EnviosRepository::returnResults()`).
   "Não" e "Parcial" valem zero.
6. **Envio por e-mail**: `enviar_email` grava os destinatários em `email_revisoes`, envia o
   PDF anexado (via `Storage::path($send->path)`) e marca o envio como `status = true`
   (passando a aparecer em "Lista de Envios").
7. **Retificação**: um novo envio pode referenciar o anterior por `send_id` (auto-FK),
   herdando o `protocol`; a view `envios` mostra "Retificado de <protocolo>".
8. **Relatórios**: gráficos por categoria (doughnut) e evolução mensal/anual (line),
   gerados com `barryvdh/laravel-dompdf` + `ImageMagick` (`createIMGraph`).

## 4. Como o Usuário Interage

**Operador (CMS, prefixo `/cms`)**

| Tela | Rota | O que faz |
|---|---|---|
| Lista de Revisões | `GET /cms/revisoes` (`revisoes.index`) | DataTable sobre a view SQL `formulario`; botões: cadastrar, importar (JSON), excluir em lote, ativar/desativar, iniciar revisão, copiar, baixar JSON, editar, excluir |
| Criar/Editar avaliação | `GET /cms/revisoes/create`, `GET /cms/revisoes/{id}/edit` | Formulário com título/subtítulo/descrição + editor de perguntas, categorias e opções (`revisoesv2.js`, modais) |
| Responder avaliação | `GET /cms/respostas/create/{id}` | Formulário de preenchimento com data do envio, revisor e uma resposta por pergunta |
| Respostas pendentes | `GET /cms/respostas` (`respostas.index`) | DataTable sobre a view SQL `respostas` (envios com `status = false`); botão "Enviar" abre o modal de e-mail |
| Envios concluídos | `GET /cms/resposta/enviadas` (`resposta_enviada.index`) | DataTable sobre a view SQL `envios`; ações: relatório, PDF, editar |
| Relatório de uma avaliação | `GET /cms/resposta/enviadas/{id}` (`relatorio.show`) | Gráficos por categoria + linha do tempo |
| Relatórios anuais | `GET /cms/respostas/enviadas/anuais` (`relatorio.anuais`) | Evolução mensal por ano |
| Listagem do cliente | `GET /cms/revisoes/relatorios` | DataTable sobre a view `listagem_clientes`; link para o PDF |
| Relatórios (gráficos) | `GET /cms/listagem/revisoes/graficos/{id}` | Tela de estatísticas do envio |

**Cidadão**: nada. Não existe rota de portal para revisões (verificado em `v6/routes/web.php`,
`v6/routes/api.php`, `v6/routes/prefecture.php`, `v6/routes/service_letter.php`).

## 5. Detalhes e Particularidades Técnicas

- **Camadas**: rota → `check.logged` / `check.route.permission` → controller → (Form Request
  em dois casos) → model Eloquent direto (sem service layer) → repository apenas para
  relatórios/PDF → view Blade AdminLTE.
- **Endpoints JSON cru**: `QuestionController` devolve o model Eloquent serializado
  diretamente (sem API Resource); `OptionsController` devolve strings `"true"`/`"false"`.
- **Views SQL**: `formulario`, `envios`, `respostas`, `listagem_clientes` — o módulo depende
  delas para as DataTables.
- **PDF**: `EnviosRepository::generatePDF()` renderiza
  `prefecture.configurations.revisoes.pdf.index` com Dompdf e grava em
  `storage/app/public/content/revisoes/{id}/pdf/revisoes_{data}.pdf` (campo `path`).
- **Importação/exportação de questionário**: JSON exportado por `baixar_revisao`
  (`cache/revisao_{slug}.json` em `public/`) e importado por `importar_revisao`.
- **Dependências**: `barryvdh/laravel-dompdf`, `intervention/image` (gráficos), `laracasts/presenter`,
  `cartalyst/sentinel`, `spatie/laravel-activitylog`, `yajra/laravel-datatables`.

## 6. Estrutura de Dados

| Tabela | Papel | Chave |
|---|---|---|
| `ratings` | avaliação (formulário) | `id` PK; `status` marca a ativa; `version` existe mas nunca é gravada |
| `questions` | perguntas da avaliação | `ratings_id` → `ratings`; `value` = peso; `order` |
| `question_categories` | categorias hierárquicas | auto-FK `question_categories_id`; `order`; `ratings_id` |
| `question_types` | tipo da pergunta | só "Resposta única" em uso |
| `option_categories` | grupos de alternativas | `title` ("Comum", "Satisfação") |
| `options` | alternativas | `description` ("Sim", "Não", "Parcial") e `value` |
| `option_category_has_options` | N:N entre alternativas e grupos | sem `SoftDeletes` |
| `send_ratings` | aplicação da avaliação | `protocol`, `revisor`, `data`, `pts_finais`, `pts_totais`, `path`, auto-FK `send_id` |
| `answer_forms` | resposta a uma pergunta | `questions_id`, `option_id`, `observation`, `send_id` |
| `email_revisoes` | destinatários de e-mail do resultado | `title` (e-mail), `ratings_id` |

Views SQL: `formulario`, `envios`, `respostas`, `listagem_clientes`.

## 7. Como Testar

1. `GET /cms/revisoes` (logado) — deve listar as avaliações com status Ativo/Inativo.
2. `POST /cms/revisoes` — cria avaliação e redireciona para `revisoes.edit`.
3. `POST /cms/questions/saveQuestion` — cria pergunta; deve aparecer na tela de edição.
4. `GET /cms/respostas/create/{ratings_id}` — abre o formulário de resposta.
5. `POST /cms/respostas` — grava envio + respostas, calcula `pts_finais`/`pts_totais` e gera PDF.
6. `POST /cms/resposta/enviar_email` — envia o PDF e muda o envio para `status = true`.
7. `GET /cms/resposta/enviadas/{id}` — exibe os gráficos por categoria.
8. `GET /cms/download_revisao/{id}` e `POST /cms/import_revisao` — ida e volta do JSON.

Detalhe de casos automatizados em `07-TESTES.md`.

## 8. Migração para Laravel Moderno

- Eloquent enxuto com `casts` (`status` → bool, `data` → datetime, `value` → float), `enum`
  para `QuestionType` e para o eixo de pontuação (Sim/Não/Parcial).
- `FormRequest` real para avaliação, pergunta, resposta e envio de e-mail (hoje quase tudo
  recebe `Request` cru, sem validação).
- **Policy** `RatingPolicy` no lugar do `check.route.permission` por nome de rota.
- `API Resource` para `Rating`, `Question`, `SendRating` (hoje o model vaza direto no JSON).
- Tabelas `send_ratings`/`answer_forms` mantêm a semântica atual, mas com
  `ScoreService` dedicado (hoje a pontuação está duplicada em dois lugares).
- Views Blade com componentes de classe; PDF mantendo Dompdf (ou PDFKHR) com o mesmo layout.
- Filas para o envio de e-mail e a geração do PDF (hoje síncrono no request).

## 9. Resumo Geral

"Revisões" é o módulo de autoavaliação da qualidade do site institucional: o operador monta
um questionário ponderado, aplica-o a si mesmo (ou à Câmara), registra as respostas, obtém uma
nota por categoria, um PDF protocolado e gráficos de evolução. Todo o módulo vive no CMS
(`/cms/revisoes*`), sem qualquer exposição no portal público. O núcleo técnico é o par
`ratings` → `send_ratings`/`answer_forms`, apoiado por um pequeno motor de questionário
(`questions`, `question_categories`, `question_types`, `options`, `option_categories`) que é
compartilhado, no mesmo estilo, com o subsistema de Formulários Dinâmicos — mas sem
compartilhar tabelas. Os principais riscos a resolver na reconstrução são: a divergência de
namespace dos models (`App\Http\Model\Prefecture` vs `App\Prefecture`), a coluna `version`
morta em `ratings`, a rota de resource `respostas.update` apontando para método inexistente
na v6, a duplicação da lógica de pontuação e a dependência de views SQL para as listagens.

---

## Índice do dossiê

| Arquivo | Conteúdo |
|---|---|
| `00-RESUMO.md` | Este documento |
| `01-ARQUITETURA.md` | Camadas, classes e o diagrama de fluxo |
| `02-MODELAGEM.md` | Estrutura de dados detalhada |
| `03-ROTAS-E-CONTROLADORES.md` | Rotas, controllers, requests, resources |
| `04-VIEWS-E-UX.md` | Telas, componentes, JS, assets |
| `05-REGRAS-E-PORTABILIDADE.md` | Particularidades e armadilhas |
| `06-MIGRACAO-MODERNA.md` | Plano de reconstrução em Laravel moderno |
| `07-TESTES.md` | Estratégia e casos de teste |
| `08-GAPS-E-DIVIDAS.md` | Pendências, riscos, comparativo v5 vs v6 |
