# Atas e Pontos de Frequência — Resumo Executivo

> **Versão analisada:** `v6` (Laravel 5.5.50, PHP 7.2.34, PostgreSQL 10 + PostGIS)
> **Slug do módulo:** `atas-e-pontos-de-frequencia` (tabela `modulos`, id 46)
> **Natureza:** Portal (público) + CMS (painel administrativo)
> **Estado:** **novo na v6** — não existe na v5

---

## 1. Objetivo

Publicar, de forma organizada e pesquisável, as **atas das sessões** da Câmara
Municipal e os **pontos de frequência** dos vereadores. O módulo serve ao
cidadão que quer consultar o que foi aprovado em sessão e como se deu a
presença dos vereadores, e serve ao servidor da Câmara que publica esses
documentos no painel administrativo.

**Ponto central e frequentemente mal entendido:** este módulo **não possui
estrutura de dados de presença**. Não existe tabela de frequência, não há
registro de presença por vereador, não há cálculo de quórum. O que existe é
um **repositório documental**: as atas e os pontos de frequência são
*conteúdos* (`contents`) com texto e anexos (PDF/imagem) publicados dentro de
categorias filhas da categoria raiz `atas-e-pontos`. A "frequência" é um
arquivo anexado, não um dado consultável.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Acesso público às atas e aos pontos de frequência, com filtro por ano, mês e texto, e download dos anexos. Não há como consultar "quem presenteou" de forma estruturada. |
| Prefeitura (CMS) | Publicação de documentos por categoria (Atas, Pontos de Frequência) via CRUD genérico de conteúdos, com listagem em DataTable e categorias filhas configuráveis. |
| Transparência e legalidade | Disponibiliza o registro de deliberações; a ausência de dados estruturados de frequência reduz a rastreabilidade de quórum e maioria. |
| Operação técnica | Módulo sem tabela própria: reaproveita `contents`, `category_contents` e `archives`. A view SQL `atas_e_pontos` é o único artefato específico do módulo. |

## 3. Comportamento

- A raiz do módulo é a categoria `atas-e-pontos` (id 41 no banco); as
  categorias de conteúdo são suas filhas — no seed: `atas` (id 42) e
  `pontos-de-frequencia` (id 43).
- `/atas-e-pontos` redireciona para a primeira categoria filha (ordenada por
  `order`).
- `/atas-e-pontos/{slug}` lista os conteúdos da categoria, paginados de 12 em
  12, ordenados por `publication_date` desc e `id` desc.
- Filtros: **ano**, **mês** e **texto livre** (busca em `title` e `text`,
  ignorando acentos via `translate(...)`).
- Conteúdos com `publication_date` futura **não** aparecem na listagem; ao
  acessar a URL direta de um conteúdo futuro, o usuário é redirecionado.
- Cada conteúdo tem contador `clicks`, incrementado a cada abertura.
- Anexos marcados com `view_pdf = true` são exibidos embutidos (`<iframe>`) ou
  como imagem; os demais aparecem na lista "Arquivos para Download".
- No CMS, a listagem usa a view SQL `atas_e_pontos` (DataTable server-side).

## 4. Como o Usuário Interage

**Cidadão (portal):** menu lateral com as categorias filhas; caixa de filtros
(Ano / Mês / busca textual) que recarrega a lista via Ajax; cada item da lista
mostra data, título e um resumo de 200 caracteres; ao clicar, abre a página do
documento com o texto completo e o bloco de arquivos para download.

**Operador (CMS):** em `/cms/conteudos/atas-e-pontos` vê a lista em DataTable
(título, categoria, data de publicação), com botões "Cadastrar Conteúdo",
"Categorias de Atas e Pontos de Frequência", exclusão em lote e, por linha, um
botão "Acessar conteúdo" que abre a URL pública do documento e o botão de
edição. O formulário exige categoria, título, data de publicação, texto e
permite anexar arquivos.

## 5. Detalhes e Particularidades Técnicas

- Camadas: `routes/web.php` → `Portal\AtasEPontosController` → Eloquent
  (`Content`, `CategoryContent`, `Archive`) → view Blade do portal; no CMS,
  `routes/basepro.php` → `Prefecture\ContentController` (genérico) e
  `Prefecture\DatatableController`.
- A view SQL `atas_e_pontos` (`v6/database/migrations/2025_01_20_122421_create_view_atas_e_pontos_table.php`)
  tem uma condição com precedência de `AND`/`OR` que pode expor conteúdo
  removido — ver `05-REGRAS-E-PORTABILIDADE.md`.
- Dois pontos de injeção SQL no portal: `$_GET['ano']` interpolado em SQL cru
  e `whereRaw` com texto do usuário concatenado.
- O tema do portal é resolvido em tempo de execução por
  `getTemplateActived()` (`v6/app/Http/Controllers/Admin/Controller.php`), com
  as telas replicadas em 6 variantes (`modelo1`..`modelo6`).
- Permissões CMS: `atas-e-pontos.create`, `atas-e-pontos.delete`, e as
  derivadas `.edit`, `.restore`, `.inactivate` montadas por
  `struct_views()`.
- Dependências: `laravel/framework` 5.5, `yajra/laravel-datatables-oracle`,
  `cartalyst/sentinel`, PostgreSQL.

## 6. Estrutura de Dados

| Objeto | Tipo | Papel |
|---|---|---|
| `contents` | tabela | Documento publicado (título, texto, data, slug, `clicks`, `category_contents_id`). |
| `category_contents` | tabela | Árvore de categorias; raiz `atas-e-pontos`, filhas `atas` e `pontos-de-frequencia`. |
| `archives` | tabela | Anexos; `view_pdf` indica o arquivo exibido embutido, `highlight` o destaque. |
| `atas_e_pontos` | **view SQL** | Lista unificada para o DataTable do CMS (`titulo`, `categoria`, `categoria_slug`, `slug`, `data_publicacao`, `value`, `id`). |
| `modulos` | tabela | Registro do módulo (id 46, `status = 0`, desligado por padrão). |

Não existe tabela própria de atas, de pontos de frequência ou de presença.

## 7. Como Testar

1. CMS: cadastrar categoria filha, publicar documento com anexo PDF e marcar
   `view_pdf`; conferir a linha no DataTable e o link "Acessar conteúdo".
2. Portal: abrir `/atas-e-pontos`, navegar por ano/mês/texto, abrir o
   documento, baixar o anexo.
3. Negativos: `/atas-e-pontos/ano=2024` deve filtrar; texto com aspas deve
   **não** gerar erro 500 (hoje gera — ver `08-GAPS-E-DIVIDAS.md`);
   `/atas-e-pontos/categoria-inexistente` deve redirecionar.
4. Automatizado: a strategy de testes proposed está em `07-TESTES.md`.

## 8. Migração para Laravel Moderno

Separar `Ata` e `PontoFrequencia` em tabelas próprias com `session_id`,
`document_type`, `published_at` e `file_id`; parametrizar todo SQL com
bindings; trocar `whereRaw` por `whereRaw` com placeholder ou busca full-text;
usar Form Requests e Policies; expor API JSON com Resources; e, se o negócio
exigir, criar o modelo `SessionAttendance` (`councilman_id`, `session_id`,
`status`) — que **hoje não existe** e é a lacuna funcional a decidir.

## 9. Resumo Geral

O módulo "Atas e Pontos de Frequência" é um **publicador documental** novo na
v6. O conteúdo vive em `contents`, dentro de categorias filhas de
`atas-e-pontos` (`atas` e `pontos-de-frequencia`), e os anexos em `archives`.
O portal oferece listagem paginada com filtros de ano, mês e texto, exibe o
documento e permite baixar os arquivos; o CMS publica os documentos pelo CRUD
genérico e lista-os por meio da view SQL `atas_e_pontos`. Não há qualquer
modelagem de presença por vereador nem de quórum: a frequência é apenas um
arquivo anexado, o que limita a transparência. O legado carrega problemas
reais de segurança (SQL cru interpolado), de robustez (acesso a categoria
inexistente gera erro 500) e de usabilidade (título do CMS copiado de outro
módulo), todos detalhados nos arquivos 05 e 08. A reconstrução em Laravel
moderno deve preservar URLs e nomes de rota públicos, mas eliminar as
consultas concatenadas e introduzir, se desejado, o modelo de presença
estruturada.

---

## Í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 |
