# Transmissões — Resumo Executivo

> **Versão analisada:** `v6` (o módulo **não existe na v5**)
> **Slug do módulo:** `transmissoes` (tabela `modulos`, id 44)
> **Natureza:** Ambos (CMS para gerenciar, Portal para exibir)
> **Estado:** **novo na v6**

---

## 1. Objetivo

O módulo permite que a Prefeitura transmita, em tempo real, a sessão da Câmara
Municipal pelo portal, exibindo o vídeo do YouTube embedado na **barra lateral
de todas as páginas do portal**, em qualquer tema visual. Serve ao cidadão que
acessa o site durante o horário de sessão e ao operador do CMS que precisa
publicar o link do vídeo e ativar/desativar a transmissão.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Vê um card "Transmissão" com o player 16:9 no rodapé da coluna lateral de qualquer página do portal, enquanto houver uma transmissão ativa. |
| Prefeitura (CMS) | Dispõe de uma tela "Lista de Transmissões" para cadastrar título + link do vídeo e alternar o status (Ativado/Desativado) por AJAX. |
| Transparência e legalidade | Disponibiliza o acesso ao=live debate da Câmara, permitindo ao cidadão acompanhar a sessão sem sair do portal. |
| Operação técnica | Não há rota pública própria: o player é um widget de layout, repetido em 6 temas. A exclusividade de "uma transmissão ativa" é garantida por código genérico acoplado ao slug da categoria. |

## 3. Comportamento

Regras de negócio principais:

1. **Módulo desligado por padrão.** A migration `v6/database/migrations/2024_11_01_150206_create_modulos_table.php:288-292` insere `transmissoes` com `status = 0`. O operador liga o módulo em `/cms/modulos`.
2. **Chave de exibição.** O widget só aparece se `$modulos['transmissoes']` estiver presente e verdadeiro (`v6/app/Providers/ModulosServiceProvider.php` injeta `$modulos` em todas as views de sidebar).
3. **Zero ou uma transmissão ativa.** Ao salvar um conteúdo com `status = 1`, o `ContentController` desativa todos os demais conteúdos da mesma categoria (`v6/app/Http/Controllers/Prefecture/ContentController.php:678-680`, `:1000-1002`).
4. **O widget exibe o primeiro conteúdo ativo.** A consulta é `whereHas('categoryContents', slug = 'transmissoes')->where('status', true)->first()`, **sem ordenação**.
5. **O link aceita URL do YouTube ou ID.** O formulário (`v6/resources/views/prefecture/contents/transmissoes/form.blade.php`) informa que aceita `https://www.youtube.com/watch?v=...` ou o ID cru.
6. **Parser de URL inline.** O widget converte a URL do YouTube em `https://www.youtube.com/embed/<id>`; para hosts não-YouTube usa a URL original; para URLs irreconhecíveis exibe `Transmissão não disponível`.
7. **Telemetria.** Cada abertura da tela de listagem no CMS incrementa `menu_orders.clicks` para o slug `transmissoes` (`menuClicks('transmissoes')`).

## 4. Como o Usuário Interage

**Operador (CMS):**

- Menu lateral **Transmissões** (ícone `television`) → `/cms/conteudos/transmissoes`
  (`v6/app/Providers/MenuServiceProvider.php:64-66`).
- DataTable server-side com colunas `ID`, `Título`, `Status` e `Ações`; botão de
  status (toggle) por AJAX e botão de editar.
- Botão **Cadastrar Transmissão** (visível apenas com `transmissoes.create`).
- Formulário: checkbox `Ativar/Desativar`, `Título` (máx. 120) e
  `Video (Youtube)` (máx. 200).

**Cidadão (Portal):**

- Não há página dedicada. O player aparece na coluna lateral (modelo1/modelo2) ou
  no topo da barra de banners (modelo3..modelo6) de qualquer página do portal.
- Nenhum controle de play/pause próprio: o player é o *embed* do YouTube.

## 5. Detalhes e Particularidades Técnicas

- **Sem tabela própria:** o módulo reaproveita `contents` + `category_contents`
  (slug `transmissoes`, id 36) + `links` (relação `linksUnique`).
- **View SQL** `transmissoes` criada em
  `v6/database/migrations/2024_10_01_180234_create_view_transmissoes.php`,
  consumida por `Prefecture\DatatableController@get_transmissoes`
  (`v6/app/Http/Controllers/Prefecture/DatatableController.php:51-55`).
- **Sem controller dedicado:** CRUD genérico `Prefecture\ContentController`.
- **Parser de URL duplicado** em 6 arquivos Blade (lógica de apresentação com
  consultas Eloquent dentro da view).
- **Acoplamento:** a exclusividade de status está escrita dentro do controller
  genérico de conteúdo, condicionada ao literal `'transmissoes'`.

## 6. Estrutura de Dados

| Objeto | Tipo | Papel |
|---|---|---|
| `contents` | tabela | Um registro por transmissão candidata (título, status, ordem). |
| `category_contents` | tabela | Categoria `transmissoes` (id 36), filtro de todas as consultas. |
| `links` | tabela | Guarda o link do vídeo; relação `hasOne` `Content::linksUnique()`. |
| `transmissoes` | view SQL | Projeção para o DataTable do CMS (5 colunas). |
| `modulos` | tabela | Chave/flag do módulo (id 44, `status = 0` no seed). |
| `menu_orders` | tabela | Telemetria de cliques (slug `transmissoes`, `modulo_id = 44`). |
| `resources` | tabela | Recurso de permissão (slug `transmissoes`, `modulo_id = 44`). |

## 7. Como Testar

- Ativar o módulo em `/cms/modulos` e o `status` de um conteúdo.
- Cadastrar uma transmissão com URL `https://www.youtube.com/watch?v=YbJOTdZBX1g`
  e conferir o player na lateral do portal.
- Alternar o status via DataTable e confirmar a desativação do registro anterior.
- Detalhes em `07-TESTES.md`.

## 8. Migração para Laravel Moderno

Substituir o conteúdo genérico por um modelo `Transmission` dedicado
(`video_url`, `is_live`, `starts_at`, `channel`), extrair o parser de URL para um
serviço testável, transformar o widget em um componente Blade único
(`<x-portal.transmission-widget>`), criar `TransmissionPolicy`, expor API REST com
`JsonResource`, cachear a transmissão ativa e cobrir com testes feature/unit.

## 9. Resumo Geral

O módulo "Transmissões" é uma funcionalidade **nova na v6** que não existia na
v5: na versão anterior o portal não oferecia nenhum player de sessão ao vivo.
Ele é implementado de forma minimalista, reaproveitando o conteúdo genérico do
CMS: cada transmissão é um registro de `contents` na categoria `transmissoes`
(id 36), com o link do vídeo em `links`. O operador cadastra título e link,
marca "Ativado" e o portal passa a exibir, na barra lateral de todos os temas
(modelo1 a modelo6), um *iframe* do YouTube em formato 16:9 com o rótulo
piscante "Transmissão". A listagem do CMS é servida pela view SQL `transmissoes`
através de DataTables server-side, e o status pode ser alternado por AJAX. A
regra de "apenas uma transmissão ativa" é aplicada no `ContentController`
genérico, condicionada ao slug da categoria, e a lógica de conversão de URL está
duplicada como PHP inline dentro das views Blade — o principal passivo técnico
do módulo. Para a v7, o dossiê propõe um modelo dedicado, um componente Blade
único, uma Policy e uma API JSON, preservando o comportamento observável
atual: um único player, no lugar atual, alimentado por um link de vídeo.

---

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