# TV Câmara — Resumo Executivo

> **Versão analisada:** `v6` (Laravel 5.5.50 / PHP 7.2.34)
> **Slug do módulo:** `tv-camara` (tabela `modulos`, id 45) — `v6/database/migrations/2024_11_01_150206_create_modulos_table.php:293-297`
> **Natureza:** Ambos (CMS AdminLTE + Portal público Bootstrap 4)
> **Estado:** **NOVO na v6** — nenhum artefato equivalente existe na `v5`

---

## 1. Objetivo

A TV Câmara é o canal institucional que publica, no portal da prefeitura, os
vídeos das sessões e eventos da Câmara de Vereadores. O módulo permite ao
operador cadastrar cada vídeo com **título**, **texto descritivo**, **data de
publicação**, **imagem de destaque** e o **link do vídeo** (YouTube, Vimeo,
Facebook ou Instagram), publicá-lo no portal em `/tv-camara` e destacá-lo no
bloco "TV Câmara" da home. Serve ao servidor da Câmara como vitrine de
transparência audiovisual e ao cidadão como canal de acesso às sessões.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Lista paginada de vídeos em `/tv-camara` e página de detalhes com o player embutido; até 3 vídeos em destaque na home. |
| Prefeitura (CMS) | Tela "Lista de TV Câmara" com DataTable server-side, cadastro/edição com upload de imagem de destaque, alternância de status, exclusão individual e em lote. |
| Transparência e legalidade | Publicação de conteúdo audiovisual com data, título e responsável; a coluna `status` e a data de publicação controlam a exposição. |
| Operação técnica | Módulo **desligado por padrão** (`modulos.status = 0`); o bloco da home só aparece depois de habilitá-lo em `/cms/modulos`. |

## 3. Comportamento

- Só aparecem no portal os vídeos com `status = true`, `deleted_at IS NULL` e
  `publication_date <= now()`, ordenados por `publication_date` desc, paginados
  de 12 em 12 (`v6/app/Http/Controllers/Portal/TvCamaraController.php:23-30`).
- A listagem da home é limitada a 3 itens por `publication_date` desc
  (`v6/app/Http/Controllers/Portal/PortalController.php:161-163`).
- A página de detalhes resolve o vídeo pelo `slug` e converte o link com o
  helper `embedVideo()` (`v6/app/Helpers/functions.php:607`), devolvendo a URL de
  embed do provedor (YouTube, Vimeo, Facebook, Instagram).
- `title`, `publication_date` e `link` são obrigatórios; `text` é opcional no
  banco, mas o formulário do CMS o trata como obrigatório
  (`v6/app/Http/Requests/TvCamaraFormRequest.php:24-30`).
- A exclusão é **soft delete** (`deleted_at`), com a coluna `archives.tv_camara_id`
  em `ON DELETE CASCADE`.
- Regra informal de "3 ativos": ao cadastrar, se já existem 3 vídeos ativos, o
  terceiro mais antigo é desativado (`v6/app/Http/Controllers/Prefecture/TvCamaraController.php:36-40`).

## 4. Como o Usuário Interage

**Operador (CMS `/cms/tv-camara`)**: vê a lista em DataTable (ID, Título, Data,
Status, Ações), exporta para Excel/PDF pelos botões padrão do DataTable,
clica em "Cadastrar TV Câmara" (visível apenas com `tv-camara.create`), preenche
o formulário (título, data com hora, imagem principal, texto com Summernote e
link do vídeo), marca "Exibir na página inicial" e salva. Na listagem, alterna
o status pelo ícone de toggle (POST `tv-camara/set-status`), edita via
`tv-camara/{id}/edit` e exclui via `tv-camara/delete/{id}` ou pelo botão de
exclusão em lote.

**Cidadão (portal)**: acessa `/tv-camara`, navega pelos cards (imagem, data,
título), abre `/tv-camara/{slug}` e assiste ao vídeo em iframe 16:9. Na home,
o bloco "TV Câmara" mostra os 3 vídeos mais recentes com miniatura.

## 5. Detalhes e Particularidades Técnicas

- Camadas: `Route` (portal em `v6/routes/web.php`; CMS em `v6/routes/basepro.php`)
  → `Controller` (`Portal\TvCamaraController`, `Prefecture\TvCamaraController`)
  → `TvCamaraFormRequest` → Model `App\Prefecture\TvCamara` → tabela `tv_camaras`.
- O CMS consome a **view SQL `tv_camara`** (`v6/app/Http/Controllers/Prefecture/DatatableController.php:469-473`).
- O modelo `TvCamara` usa o namespace `App\Prefecture` (não `App\Http\Model\Prefecture`),
  enquanto o controller importa `App\Prefecture\Archive`.
- O embed de vídeo depende de `embedVideo()`; **não** funciona com o ID cru do
  YouTube, embora o placeholder do formulário sugira esse formato.
- Permissões: `has_access(['tv-camara.create'])` e `has_access(['tv-camara.delete'])`
  no restante do código, mas a view usa `has_access(['tv-camaras.delete'])` (com "s"),
  deixando o botão de exclusão em lote invisível para quem não é `super-admin`.
- Dependências: `laracasts/presenter`, `yajra/laravel-datatables`, `cartalyst/sentinel`,
  `laravel/framework` 5.5.

## 6. Estrutura de Dados

| Objeto | Tipo | Observação |
|---|---|---|
| `tv_camaras` | tabela | dados do vídeo; FK referenciada por `archives.tv_camara_id` |
| `archives` | tabela (compartilhada) | imagem de destaque via `tv_camara_id` + `highlight = 1` |
| `tv_camara` | view SQL | listagem do DataTable do CMS |
| `modulos` / `resources` / `menu_orders` | tabelas | módulo id 45, recurso `tv-camara`, menu id 39 |

## 7. Como Testar

1. Habilite o módulo em `/cms/modulos` (o bloco da home depende disso).
2. Cadastre um vídeo com link `https://www.youtube.com/watch?v=YbJOTdZBX1g` e
   imagem de destaque; confirme a mensagem "Cadastrado com sucesso".
3. Verifique em `/tv-camara` e em `/tv-camara/{slug}` (player embutido).
4. Alterne o status pela listagem e confirme o sumiço/desaparecimento no portal.
5. Detalhe dos casos: `07-TESTES.md`.

## 8. Migração para Laravel Moderno

Reescrever como módulo Laravel 11/12 com Model `TvCamara` (casts `is_active`,
`published_at`, `provider`, `video_id`), migration com `softDeletes`, Form
Request validando a URL por provedor, Policy por ação, API Resource JSON,
rotas REST em `routes/api.php`, thumbnails em `storage/app/public/tv-camara` e
testes Pest/PHPUnit. **Não podem mudar**: o limite de 3 itens na home, o
comportamento de embed e a ordenação/paginação da listagem pública.

## 9. Resumo Geral

O módulo TV Câmara é **novo na v6**: na `v5` não existia nenhuma rota, migration,
model, view ou seed com esse nome, o que significa que a versão anterior do
portal **não oferecia canal de vídeo das sessões** ao cidadão. Na v6 o módulo
ganhou tabela própria (`tv_camaras`), uma imagem de destaque reaproveitando
`archives`, uma view SQL para o DataTable do CMS e integração com a home do
portal. A exibição do vídeo é feita por `embedVideo()`, que converte links de
YouTube, Vimeo, Facebook e Instagram em URLs de embed; URLs desconhecidas
caem no fallback e não reproduzem. O módulo nasce **desligado** no seed
(`modulos.status = 0`) e precisa ser habilitado pelo operador. O
comportamento observável — 3 vídeos na home, paginação de 12, filtro por status
e data — é o contrato funcional que a reconstrução em Laravel moderno deve
preservar.

---

## Í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, embed de vídeo |
| `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 |
