# Avisos — Gaps, Dívidas e Mapa v5 → v6

> Inventário do que está quebrado, morto ou divergente no módulo Avisos da `v6`,
> com o comparativo v5 → v6.

---

## 1. Bugs / erros conhecidos

| # | Severidade | Descrição | Evidência |
|---|---|---|---|
| B1 | Alta | **Divergência de nomenclatura**: o módulo no CMS é `avisos` ("Avisos", `modulos` id 26), mas a categoria de conteúdo é `anuncios` ("Anúncios", `category_contents` id 28). Rotas, permissões, view SQL, seeds e menus usam `anuncios` | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php:178-183` vs `v6/database/seeds/CategoryContentTableSeeder.php:161-166` |
| B2 | Alta | **Erro 500 na home se o aviso ativo não tiver imagem de destaque**: `->first()->path` acessa `path` de `null` | `v6/resources/views/portal/layouts/modelo1/home/aviso.blade.php:12` (idem modelo3/4/5/6 e default) |
| B3 | Média | **Exclusividade de aviso ativo garantida só na aplicação** (sem constraint): uma importação ou um `UPDATE` manual deixa dois avisos ativos; o portal mostra só o primeiro | `v6/app/Http/Controllers/Prefecture/ContentController.php:672-674`, `:994-996`, `:1565-1567` |
| B4 | Média | **Sem página pública de avisos**: o comunicado só existe como modal na home; ao fechá-lo, o cidadão não tem como consultá-lo | `v6/routes/web.php` (nenhuma rota com `anuncio`) |
| B5 | Média | **Verificação de módulo inconsistente**: só modelo1/3/4 checam `$modulos['avisos']`; modelo5, modelo6 e default exibem o modal sempre que houver `$anuncio` | `v6/resources/views/portal/layouts/modelo1/home/aviso.blade.php:1` vs `v6/resources/views/portal/layouts/modelo6/home/index.blade.php:18` |
| B6 | Média | **`Cache::rememberForever('modulos')`**: alterar o status do módulo "Avisos" não surte efeito até o cache ser limpo | `v6/app/Providers/ModulosServiceProvider.php:22-24` |
| B7 | Baixa | **`maxlen` do link (200) no formulário x `max:2999` na validação** | `v6/resources/views/prefecture/contents/anuncios/form.blade.php:29` vs `v6/app/Http/Requests/ContentRequest.php:172` |
| B8 | Baixa | **`->geT()`** com grafia inconsistente no `DatatableController` | `v6/app/Http/Controllers/Prefecture/DatatableController.php:230` |
| B9 | Baixa | **URL absoluta `/cms/set-status`** no botão de status (quebra se o prefixo do CMS mudar) | `v6/public/assets/js/custom/utilities/table.js:373` |
| B10 | Baixa | **`catch (\Throwable $th) {}`** no `contentList` engole erros | `v6/app/Http/Controllers/Portal/PortalController.php:367` |

## 2. Funcionalidades incompletas ou mortas

| # | Item | Situação |
|---|---|---|
| M1 | Página/arquivo público de avisos | Não existe (apenas o modal da home) |
| M2 | Período de validade | Não há `starts_at`/`ends_at`: um aviso ativo fica no ar indefinidamente |
| M3 | Métricas | Não há registro de impressões nem cliques do aviso |
| M4 | Semântica de "Aviso" | O `text` do conteúdo não é usado no portal (o aviso é só imagem + link) |
| M5 | Link sem validação de URL | A validação é apenas `required|max:2999`; não há regra de formato |
| M6 |SEO / indexação | O aviso não entra na busca do portal (o slug `anuncios` não está na lista de slugs buscáveis) |
| M7 | Ordenação | O `order` do `contents` não é exposto no formulário; a home usa `first()` sem `orderBy` |

## 3. Itens existentes na v5 e removidos na v6 (ou o contrário)

| Item | v5 | v6 | Observação |
|---|---|---|---|
| `Prefecture/DatatableController::get_avisos` | presente | presente | Idêntico |
| Migration da view `anuncios` | `v5/database/migrations/2023_04_10_152724_create_view_to_anuncios.php` | `v6/database/migrations/2023_04_10_152724_create_view_to_anuncios.php` | Mesmo SQL |
| JS `assets/js/custom/contents/avisos/datatable.js` | presente | presente | Idêntico |
| Views do CMS `prefecture/contents/anuncios/*` | presentes | presentes | Equivalentes |
| Parcial `home/aviso.blade.php` | **não existia** (HTML inline na home de cada modelo) | `v6/resources/views/portal/layouts/modelo1/home/aviso.blade.php` (idem modelo3/modelo4) | Parcial nova; modelo2 passou a incluir a do modelo1 |
| Registry `modulos` / `resources` / `menu_orders` | inexistente | criado (módulo id 26) | Novo na v6 |
| Regra de "um aviso ativo" | já existia | idem | Sem alteração |

**Nenhuma funcionalidade de aviso foi removida na v6.** A v6 **extraiu parciais** do HTML
do modal (reduzindo a duplicação) e introduziu a camada de registry de módulos.

## 4. Riscos de dados

| Risco | Descrição | Mitigação na v7 |
|---|---|---|
| DR1 | Aviso precisa de 3 registros coerentes (`contents` + `links` + `archives` com `highlight = 1`) | Teste de integridade na migração |
| DR2 | Caminho da imagem em `storage/content/anuncios/{id}/destaque/{nome}` depende do disco `public` do Laravel 5.5 | Script de cópia do storage na migração |
| DR3 | A exclusividade depende do código: dados antigos podem ter 2+ ativos | Normalizar na migração (desativar todos, manter o mais recente) |
| DR4 | Permissões indexadas pelo slug `anuncios` | Preservar o slug |
| DR5 | Soft delete de `contents` não remove `links`/`archives` órfãos | Limpeza na migração (ou FK `ON DELETE CASCADE`) |
| DR6 | `links.isBlank` guarda "abrir em nova guia"; se o registro `links` faltar, `$anuncio->linksUnique->link` é `null` | Garantir `links` obrigatório na criação (já validado) e no seed |

## 5. Dívidas técnicas

| Dívida | Onde | Impacto |
|---|---|---|
| D1 | HTML do modal duplicado em 7 arquivos (parciais + inline), com Bootstrap 4 e 5 misturados e ids diferentes (`anuncio` x `modalAviso`) | Correções replicadas; inconsistência visual |
| D2 | Exclusividade na aplicação em três pontos distintos do controller | Fica fácil esquecer um ponto |
| D3 | Tabela `links` genérica usada para o destino do aviso | Acoplamento a um modelo pensado para vídeos |
| D4 | Sem cache do aviso ativo: a home faz a consulta a cada visita (com eager loading, mas sempre) | Custo desnecessário |
| D5 | Sem registro de impressões/cliques | Não há dados para avaliar a comunicação |
| D6 | Sem tratamento para imagem ausente | Erro 500 (B2) |
| D7 | `Cache::rememberForever` para a configuração de módulos | Mudança de status não surte efeito |

## 6. Perguntas em aberto para o negócio

1. Deve haver **mais de um aviso ativo** ao mesmo tempo (fila de comunicados)? Hoje o modelo é "um só".
2. O aviso deve ter **período de vigência** (início/fim) e expirar sozinho?
3. Deve existir uma **página de arquivo** dos avisos publicados (para consulta posterior e indexação)?
4. O aviso pode ser **vídeo** ou apenas imagem?
5. Quantos avisos podem ter o mesmo destino (link)?
6. Deve haver **métricas de clique** no comunicado para avaliar a campanha?
7. A nomenclatura oficial deve ser "Aviso" ou "Anúncio"? A decisão precisa ser propagada a `modulos`, `category_contents`, permissões e rotas.

## 7. Mapa v5 → v6

```mermaid
graph LR
  subgraph V5["v5"]
    A1["DatatableController::get_avisos<br/>(DB::table('anuncios'))"]
    A2["view SQL anuncios"]
    A3["CMS: prefecture/contents/anuncios/{index,create,edit,form}"]
    A4["JS custom/contents/avisos/datatable.js"]
    A5["Home: HTML do modal INLINE em cada modelo"]
    A6["ContentController: 1 aviso ativo (regra no código)"]
  end
  subgraph V6["v6"]
    B1["DatatableController::get_avisos (idêntico)"]
    B2["view SQL anuncios (mesma SQL)"]
    B3["CMS: mesmas views"]
    B4["JS idêntico"]
    B5["NOVO: parciais home/aviso.blade.php (modelo1, modelo3, modelo4)<br/>modelo2 inclui a do modelo1"]
    B6["NOVO: modulos (id 26 'Avisos'), resources, menu_orders"]
    B7["NOVO: ModulosServiceProvider com $modulos['avisos']"]
  end
  A1 --> B1
  A2 --> B2
  A3 --> B3
  A4 --> B4
  A5 --> B5
  A6 --> B6
  B6 --> B7
```

**Resumo do mapa:** o módulo Avisos é **funcionalmente equivalente** entre v5 e v6. A v6
(1) extraiu o HTML do modal para parciais em três layouts (reduzindo a duplicação, mas
mantendo cópias inline em modelo5/modelo6/default), (2) introduziu o registry de módulos
(`modulos` id 26 "Avisos", `resources`, `menu_orders`) e (3) passou a controlar a exibição
via `$modulos['avisos']` em parte dos layouts. A regra de "um aviso ativo" e a view SQL
`anuncios` são idênticas nas duas versões.

### Detalhamento das diferenças

| Dimensão | v5 | v6 |
|---|---|---|
| Controller | `Prefecture\ContentController` (genérico) | idem |
| Exibição no portal | `PortalController@index` -> `$anuncio` | idem |
| Modal | HTML inline em `home/index.blade.php` de modelo1..6 e default | parciais `home/aviso.blade.php` (modelo1, modelo3, modelo4) + inline (modelo5, modelo6, default) |
| Controle por módulo | inexistente | `$modulos['avisos']` (cache "para sempre") |
| Permissões | por conteúdo | recurso `anuncios` -> modulo 26 |
| Menu do CMS | por categoria | `MenuServiceProvider` case `anuncios` -> "Avisos" (`/cms/conteudos/anuncios`) |
| View SQL | `anuncios` | idem |
| Rotas públicas | nenhuma para avisos | idem |
| API | inexistente | inexistente |
| Testes | inexistentes | inexistentes |
