# Vereadores e Mandatos — Resumo Executivo

> **Versão analisada:** `v6`
> **Slug do módulo:** `vereadores` (tabela `modulos`, id 43)
> **Natureza:** CMS (painel administrativo) + Portal (público)
> **Estado:** **novo na v6** — não existe nenhum equivalente na `v5`

---

## 1. Objetivo

O módulo mantém o cadastro da **Câmara Municipal**: os **vereadores** (nome, partido,
biografia, foto) e os **mandatos** que eles ocupam (legislaturas, mesas diretoras,
comissões permanentes). No CMS o operador cadastra e mantém esses dados; no portal o
cidadão consulta a composição atual da Câmara, a composição histórica por mandato e o
perfil de cada vereador. O módulo existe para dar **publicidade à composição do
Legislativo** e para servir de cadastro-base a outros módulos (requerimentos, VIAP).

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Passa a poder consultar a lista de vereadores, o perfil individual (partido, biografia, mandatos e cargo) e a composição de cada mandato. No tema `modelo5` a home ganha um carrossel de vereadores. |
| Prefeitura (CMS) | Tela nova de "Vereadores", "Mandatos" e "Categorias de Mandato", com upload de foto, atribuição de mandato por vereador, ordenação por arrastar e soltar e registro de auditoria. |
| Transparência e legalidade | Publica a identidade dos agentes políticos e os cargos exercidos em cada legislatura — requisito de transparência do Legislativo. |
| Operação técnica | Quatro tabelas novas (`councilmen`, `mandates`, `mandate_categories`, `councilmen_mandates`) e três "resources" novos no CMS (`vereadores`, `mandatos`, `categorias-mandatos`), todos sob o módulo 43. |

## 3. Comportamento

- Um vereador só aparece no portal quando `councilmen.status = true`; o CMS lista
  todos (ativos e inativos) e permite filtrar visualmente pela coluna "Situação".
- Um mandato pertence a exatamente uma **categoria** de mandato
  (`mandate_categories`); o portal agrupa os mandatos por categoria numa lista lateral.
- A relação vereador↔mandato é **N:N** e carrega dois atributos no pivot:
  `role` (o cargo ocupado, ex.: "Presidente") e `order` (posição na ordenação do mandato).
- **Excluir um vereador com mandatos é recusado** pelo CMS com a mensagem
  "Esse vereador tem mandatos ativos, não pode ser excluído."
- A ordenação dos vereadores dentro de um mandato é feita por *drag-and-drop* (jQuery UI
  sortable) e persistida via `POST /cms/ajax/ajust-vereadores-mandato`.
- A atribuição de mandato a um vereador é feita na tela de detalhe do vereador
  (`vereadores.show`), informando o mandato e o cargo.
- O módulo está **desligado por padrão** (`modulos.status = false`) — o operador o ativa
  em `/cms/modulos`.

## 4. Como o Usuário Interage

**Operador (CMS, `/cms/vereadores`)**: lista em DataTable com nome, nº de mandatos e
situação; botões "Cadastrar Vereador", "Mandatos" (detalhe), "Editar" e "Excluir".
No formulário: checkbox "Ativar", nome, partido, foto (upload de imagem com preview) e
texto biográfico (Summernote). Na tela de detalhe: tabela de mandatos com botão de
exclusão por linha e formulário "Atribuir Mandato" (select de mandato + campo cargo).

**Cidadão (Portal)**: `/vereadores` lista cartões com foto, nome abreviado e partido;
clicar leva a `/vereadores/{id}` com foto, biografia e a lista de mandatos com o cargo
exercido. `/mandatos` exibe as categorias; ao escolher uma, `/mandatos/{slug}` mostra
um acordeão com um cartão por mandato e, dentro dele, os vereadores ordenados.

**Carrossel da home (`modelo5`)**: seção opcional da home com *lightSlider*, 5 itens
por vez em desktop (4/3/2/1 em breakpoints menores), botões `.btn-prev`/`.btn-next`
e link "Ver Todos".

## 5. Detalhes e Particularidades Técnicas

- Camadas: `Route` → `Controller` → `FormRequest` (parcial) → `Eloquent Model` → `DB`.
  Não há repository/service dedicado neste módulo (ao contrário de `conteudo` e `viap`).
- O tema do portal é resolvido em tempo de execução por `getTemplateActived()`
  (`v6/app/Http/Controllers/Admin/Controller.php:39`), o que obriga a manter **6 cópias**
  (modelo1..modelo6) das views públicas de vereadores e mandatos.
- A auditoria é feita com `activity()->performedOn(...)->causedBy(Sentinel::getUser())`.
- Permissões via `has_access()` (`v6/app/Library/Helper/appHelpers.php:22`), padrão
  `<módulo>.<ação>`; `super-admin` passa em tudo.
- Telemetria de menu: `menuClicks('vereadores')` no construtor dos controllers do CMS.
- Dependências: `laravel/framework` 5.5, `cartalyst/sentinel` 2.0, `intervention/image`
  2.7, PostgreSQL/PostGIS.

## 6. Estrutura de Dados

| Tabela | Papel | Chaves |
|---|---|---|
| `councilmen` | Vereadores | PK `id`; FK `archives_id` → `archives.id` |
| `mandate_categories` | Categorias de mandato (Legislaturas, Mesas Diretoras, Comissões) | PK `id` |
| `mandates` | Mandatos | PK `id`; FK `mandate_categories_id` → `mandate_categories.id` |
| `councilmen_mandates` | Pivot N:N | PK `id`; **sem FKs e sem índice único** |

Vinculações externas: `contents.councilmen_id` → `councilmen.id` (ON DELETE SET NULL),
usada como *requerente* na view SQL `requerimentos`; `viap.councilman_id` →
`councilmen.id` (ON DELETE CASCADE), para o vínculo de gabinete.

## 7. Como Testar

- Portal: cadastrar um vereador ativo e outro inativo, conferir que só o ativo aparece
  em `/vereadores`; atribuir mandato com cargo; conferir perfil e ordenação.
- CMS: tentar excluir vereador com mandato (deve recusar); arrastar a ordenação e
  recarregar (a ordem deve persistir); excluir a foto (deve sumir e cair no
  placeholder).
- Moderno: testes feature com `Laravel\Dusk` ou `PHPUnit` + `RefreshDatabase`,
  factories para `CityCouncilor`, `Mandate`, `MandateCategory`.

## 8. Migração para Laravel Moderno

Reescrever as quatro tabelas com migrations Laravel 11/12, **FKs reais e unique
composto** no pivot, `casts` de `status` para `boolean`, `enum`s `MandateRole` e
`Party`, Form Requests com `Rule::exists`, Policies (`CityCouncilorPolicy`,
`MandatePolicy`), API Resources JSON, rotas REST e ordenação por
`PATCH /mandatos/{id}/councilmen/order`. Fila para geração de thumbnails.

**O que não pode mudar**: a lista pública só mostra vereadores ativos; um vereador
com mandato não pode ser excluído; o `role` é o cargo exibido ao público; o `order`
define a ordenação dentro do mandato; o caminho da foto
(`/storage/content/vereadores/{id}/{nome}`) é consumido por views e pelo carrossel.

## 9. Resumo Geral

O módulo `vereadores` é **novo na v6**: a `v5` não possuía nenhuma rota, migration,
model, view ou seed relacionada a vereadores ou mandatos. Ele introduz quatro tabelas
(`councilmen`, `mandate_categories`, `mandates`, `councilmen_mandates`), três
controllers no CMS (`CityCouncilorController`, `MandateController`,
`MandateCategoryController`), dois no portal (`CityCouncilorController`,
`MandatesController`) e um carrossel opcional na home do tema `modelo5`. O portal
expõe a lista de vereadores, o perfil individual e a composição por mandato; o CMS
permite manter tudo isso, com upload de foto, atribuição de cargo e ordenação manual.
O módulo é registrado na tabela `modulos` com id 43 e nasce desligado. As principais
fragilidades a corrigir na v7 são as relações `hasOne` usadas onde caberia
`belongsTo`, a ausência de FK/unique no pivot, o `CouncilmenMandates` sem `SoftDeletes`
e o slug não regenerado na edição do vereador.

---

## Í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, permissões |
| `04-VIEWS-E-UX.md` | Telas, componentes, JS, assets |
| `05-REGRAS-E-PORTABILIDADE.md` | Regras de negócio 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 → v6 |
