# Unidades de Atendimento — Gaps, Dívidas e Comparativo v5 → v6

---

## 1. Mapa v5 → v6

**O módulo não existe na v5.**

```bash
grep -r "unidades-de-atendimento\|unidades_de_atendimento\|ServiceUnit" v5/
# → nenhum resultado
```

| Camada | v5 | v6 |
|---|---|---|
| Rotas do portal | — | `v6/routes/web.php:116-117` |
| Controller do portal | — | `v6/app/Http/Controllers/Portal/ServiceUnitsController.php` |
| Controller do CMS | — | `Prefecture\ContentController` (genérico) + `Prefecture\DatatableController` |
| Views do portal | — | `v6/resources/views/portal/layouts/modelo1..modelo6/unidades-de-atendimento/` |
| Views do CMS | — | `v6/resources/views/prefecture/contents/unidades-de-atendimento/` |
| Model | — | `App\Prefecture\Content` / `CategoryContent` / `Archive` (genéricos) |
| Migration | — | `v6/database/migrations/2024_11_30_102902_create_view_unidades_de_atendimento.php` |
| Seeds | — | `CategoryContentTableSeeder.php:243-247`, `ResourcesTableSeeder.php:576-582`, `MenuOrderSeeder.php:332-338` |
| Módulo em `modulos` | — | id 47 (`v6/database/migrations/2024_11_01_150206_create_modulos_table.php:305-310`) |
| JS | — | `v6/public/assets/js/custom/contents/unidades-de-atendimento/datatable.js` |

**Conclusão:** módulo **novo na v6** (funcionalidade adicionada após a v5), sem
migração de dados a planejar e sem regressão a preservar da v5. A carga de
conteúdo é feita exclusivamente pela operação do CMS.

## 2. Bugs e erros conhecidos

| # | Bug | Impacto | Evidência |
|---|---|---|---|
| B1 | Slug do `$category` acessado sem `firstOrFail()` → erro 500 se a categoria não existir. | Página pública fora do ar. | `ServiceUnitsController.php:26,30` |
| B2 | Link de exibição no CMS aponta para `/portal/unidades-de-atendimento/{slug}`, rota inexistente. | Link copiado pelo operador retorna 404. | `v6/resources/views/prefecture/contents/unidades-de-atendimento/form.blade.php:25` |
| B3 | A tela de "Atas e Pontos" é renderizada com o título "Unidades de Atendimento". | Copy-paste não corrigido no CMS. | `v6/app/Http/Controllers/Prefecture/ContentController.php:116` |
| B4 | `row_number()` na view SQL gera índice instável a cada consulta. | A coluna "ID" da DataTable não é um identificador real. | migration da view |
| B5 | Divergência de ordenação entre portal (`publication_date desc, id desc`) e view SQL (`publication_date desc`). | Ordens diferentes entre portal e CMS. | `ServiceUnitsController.php:31` vs migration |
| B6 | `$content->archives[0]` sem ordenação: a miniatura pode não ser a imagem de destaque. | Cartões podem exibir imagem aleatória. | `v6/resources/views/portal/layouts/modelo1/unidades-de-atendimento/index.blade.php:22` |
| B7 | Nomes de permissão inconsistentes (`unidades-de-atendimento.*` vs `unidades_de_atendimento.*`). | Perfis de permissão podem não casar com o botão esperado. | `index.blade.php:11` vs `DatatableController.php:477` |
| B8 | Texto do conteúdo renderizado sem escape (`{!! !!}`). | XSS Stored por usuário do CMS. | `v6/resources/views/portal/layouts/modelo1/unidades-de-atendimento/show.blade.php:29` |
| B9 | Layout `default` (e `newsbit`, `surveys`, `calendar-events`, `contratos`, `diario-oficial`, `dynamics-forms`, `busca-diarias`, `barra-privacidade`) **não possui** as views do módulo. | Erro de view inexistente; `getTemplateActived()` pode ativar a manutenção do portal. | `v6/resources/views/portal/layouts/`; `GetInformationsPrefectureTrait.php:95-99` |
| B10 | Código morto (`$current_date`) e código comentado no `show()`. | Ruído; induz leitura errada do comportamento real. | `ServiceUnitsController.php:27,43-48` |
| B11 | `contents.slug` não tem índice único. | Slugs duplicados possíveis fora do fluxo do controller. | Schema `contents` |
| B12 | `archives.contents_id` sem `ON DELETE CASCADE`. | Arquivos órfãos no storage após exclusão. | Schema `archives` |

## 3. Funcionalidades incompletas ou mortas

| Item | Situação |
|---|---|
| Coluna `data_e_hora` da view SQL | **Não é exibida** na DataTable (não consta no array de colunas do JS). Dados calculados e descartados. |
| `data_e_hora` na listagem do portal | O portal usa `date('d.m.Y', strtotime($content->publication_date))`, ignorando o formato `DD/MM/YYYY às HH24:MI` da view. |
| Filtro por `status` | O `contents.status` existe, mas nem o portal nem a view SQL filtram por ele — conteúdo "despublicado" continua visível. |
| Busca/filtro de unidades | Não há campo de busca; apenas paginação e ordenação. |
| Ordenação configurável | Não há; o `runDatatables('unidades-de-atendimento', collums, true, 'ASC', null, true)` fixa a ordenação inicial da tabela (`type_order = 'ASC'`, `order_column = null`). |
| Exportação pelo portal | Não há endpoint de exportação do portal (só no CMS). |
| Video no detalhe | O vídeo é gravado em `links` e usado no thumbnail (`ContentPresenter::getArchiveContentHighlightOrThumbnail`), mas as views de detalhe **não exibem** o player de vídeo. |
| `content->present()` | Só usado em `modelo3`/`modelo4`; `modelo1/2/5/6` usam `archives[0]->path` cru (sem `getMinFile`/`getMedFile`). |

## 4. Riscos de dados

| Risco | Descrição | Mitigação na v7 |
|---|---|---|
| Exclusão em cascata de arquivos | Arquivos permanecem no storage após exclusão do conteúdo. | Job de limpeza + `Storage::delete` transacional. |
| Slugs históricos | Unidades publicadas podem ter slugs gerados com o sufixo `-N`; renomear títulos cria novos slugs e quebra links externos. | Tabela de redirecionamento (slug antigo → novo). |
| `contents.text` com HTML de Summernote | Imagens do editor migradas para `summernote-files/content/{slug}/{id}/` via `Storage::move` no `store` — paths ficam dependentes do id do conteúdo. | Preservar o layout de pastas ou reescrever os paths no mesmo passo da migração. |
| `category_contents.slug` como chave lógica | Renomear o slug quebra controller, view SQL e seeds. | Slug imutável + constante de configuração. |
| View SQL fora do versionamento de schema | Ambientes sem a migration executada quebram o CMS (erro 500 no DataTable). | Verificar a existência da view no boot ou usar query Eloquent. |

## 5. Dívidas técnicas do módulo

1. Sem testes automatizados (nada em `v6/tests/` referencia o módulo).
2. Sem API JSON para o portal.
3. Sem validação de campos específicos de uma unidade de atendimento (telefone,
   endereço, horário de funcionamento) — hoje só título, texto, vídeo e imagens.
4. Sem ordenação/priorização manual das unidades (o campo `order` existe, mas o
   portal ordena por data).
5. Sem suporte a múltiplas unidades por página de detalhe.
6. Duplicação de 6 views de listagem e 6 de detalhe (uma por layout).
7. Duplicação de `getTemplateActived()` em trait e controller.
8. `ContentController` mixando CRUD genérico com regras específicas de slug
   (bloco `if` com ~20 slugs).

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

1. **O que é exatamente uma "Unidade de Atendimento"?** Toda unidade deveria ter
   endereço, telefone, horário e Secretaria vinculada? Hoje o módulo é apenas
   uma lista de conteúdos com texto livre.
2. **Existe uma relação oficial entre unidades e Secretarias/Órgãos?** O campo
   `contents.secretaria` e `contents.orgaos_id` existem, mas o formulário do
   módulo não os expõe.
3. **A ordenação deve ser por data de publicação ou manual?** O campo `order`
   existe e é ajustado no `store`, mas o portal não o utiliza.
4. **Deve existir filtro por status/publicação?** Hoje conteúdo despublicado
   continua visível ao cidadão.
5. **Qual o tamanho de página esperado?** 12 é o padrão herdado da v5/v6.
6. **Devem existir categorias de unidades** (ex.: Saúde, Educação)? O modelo
   atual não suporta (a categoria é única e raiz).
7. **O módulo deve migrar para tabela própria?** A decisão impacta o CMS
   genérico de conteúdos.
8. **O que fazer com o layout `default`?** Falta a pasta do módulo; é preciso
   criar ou bloquear a troca de layout.

## 7. Inventário de arquivos do módulo (v6)

| Tipo | Caminho |
|---|---|
| Controller (portal) | `v6/app/Http/Controllers/Portal/ServiceUnitsController.php` |
| Controller (CMS) | `v6/app/Http/Controllers/Prefecture/ContentController.php` |
| Controller (CMS, JSON) | `v6/app/Http/Controllers/Prefecture/DatatableController.php` |
| Request | `v6/app/Http/Requests/ContentRequest.php` |
| Models | `v6/app/Http/Model/Prefecture/Content.php`, `v6/app/Http/Model/Prefecture/CategoryContent.php`, `v6/app/Http/Model/Prefecture/Archive.php`, `v6/app/Http/Model/Prefecture/Link.php` |
| Views (portal) | `v6/resources/views/portal/layouts/modelo1..modelo6/unidades-de-atendimento/{index,show}.blade.php` |
| Views (CMS) | `v6/resources/views/prefecture/contents/unidades-de-atendimento/{index,create,edit,form}.blade.php` |
| JS | `v6/public/assets/js/custom/contents/unidades-de-atendimento/datatable.js` |
| Migration (view) | `v6/database/migrations/2024_11_30_102902_create_view_unidades_de_atendimento.php` |
| Migration (módulo) | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` |
| Seeds | `v6/database/seeds/CategoryContentTableSeeder.php`, `v6/database/seeds/ResourcesTableSeeder.php`, `v6/database/seeds/MenuOrderSeeder.php` |
| Rotas | `v6/routes/web.php:116-117`, `v6/routes/basepro.php:141,174,223,235-237,396,461` |
| Menu CMS | `v6/app/Providers/MenuServiceProvider.php:295-297` |

## 8. Estado atual no banco (consulta somente-leitura)

| Consulta | Resultado |
|---|---|
| `select * from unidades_de_atendimento` | 0 linhas |
| `select count(*) from contents where category_contents_id = 44` | 0 |
| `category_contents` id 44 | `Unidades de Atendimento`, `status_create = true`, sem pai |
| `configurations.key = 'layout'` | `modelo1` |
| `configurations.key = 'pagina_em_manutencao'` | `0` |

O módulo está **instalado e navegável, porém sem conteúdo cadastrado** — a
funcionalidade de listagem ainda não foi exercitada com dados reais na base v6.
