# Páginas Estáticas — Gaps, Bugs e Dívidas

## 1. Bugs e erros conhecidos

| # | Severidade | Descrição | Evidência |
|---|---|---|---|
| S-B01 | **Alta** | Duas rotas com o **mesmo nome** `static.show` (`/pagina/{slug}` e `/{slug}`). A segunda sobrescreve o nome: `route('static.show', $slug)` gera `http://localhost/{slug}`. | `v6/routes/web.php:227` e `v6/routes/basepro.php:548`; confirmado com `php artisan route:list --name=static.show` e execução de `route('static.show','contato')` |
| S-B02 | **Alta** | Página inexistente devolve **HTTP 200** com a mensagem "PÁGINA NÃO ENCONTRADA", mascarando 404 e prejudicando SEO/monitoração. | `v6/app/Http/Controllers/Portal/PortalController.php:307-309` + `v6/resources/views/portal/statics/show.blade.php` |
| S-B03 | **Alta** | Rota `GET /cms/pagina-estatica/{id}` (nome `pagina-estatica.show`) aponta para `StaticPageController@show`, **método inexistente** -> erro 500. | `v6/routes/basepro.php:176`; `v6/app/Http/Controllers/Prefecture/StaticPageController.php` não define `show()` |
| S-B04 | **Alta** | A view SQL `paginas_estaticas` **não expõe** a coluna `galery`, mas o JS do CMS usa `data.galery` -> o botão de galeria da listagem fica **sempre desabilitado**. | `v6/database/migrations/2024_10_10_120559_update_view_static_pages.php` vs `v6/public/assets/js/custom/contents/paginas-estaticas/datatable.js` e `v6/public/assets/js/custom/utilities/table.js:310-318` |
| S-B05 | Média | Slugs duplicados no banco: `manual-de-navegacao` existe nas páginas id 6 (sistema) e id 8 (17 cliques). `staticShow` usa `->first()` e devolve sempre a id 6 — a id 8 é inalcançável. | `select id, title, slug, clicks from static_pages order by id;` |
| S-B06 | Média | `$_SERVER['REQUEST_URI']` é usado para descobrir o id da página, tanto no `StaticPageRepository::structureUpInsert` quanto em `ConditionalRequiredSlug::passes`. Na rota de criação o último segmento é `pagina-estatica`, não um id. | `v6/app/Repositories/Eloquent/Prefecture/StaticPage/StaticPageRepository.php:33-38` e `v6/app/Rules/ConditionalRequiredSlug.php:41-45` |
| S-B07 | Média | O `StaticPageRepository` passa o **Request inteiro** ao `updateOrCreate()`; a gravação de `is_external` na criação depende apenas de ele estar no `$fillable` (o `store` não faz `merge` explícito, ao contrário do `update`). | `v6/app/Repositories/Eloquent/Prefecture/StaticPage/StaticPageRepository.php:44-51` e `v6/app/Http/Controllers/Prefecture/StaticPageController.php:290-292` |
| S-B08 | Média | O JS da galeria chama `POST /cms/galeria/delete/{id}` (`ArchiveController@deleteArchives`), e não a rota do `StaticPageController` (`ajax.delete.static.files.gallery`), que fica sem uso. | `v6/public/assets/js/custom/contents/paginas-estaticas/archives-pages.js` vs `v6/routes/basepro.php:135` e `:384-390` |
| S-B09 | Média | A rota `/{slug}` (basepro) **não** tem o middleware `check.site.manutention`: páginas estáticas continuam acessíveis com o portal em manutenção. | `v6/app/Providers/RouteServiceProvider.php:85-89` |
| S-B10 | Média | O `catch-all` `/{slug}` compete com o resto do portal: qualquer URL não mapeada (inclusive erro de digitação) devolve a página "não encontrada" com HTTP 200. | `v6/routes/basepro.php:548` |
| S-B11 | Baixa | `updateOrCreate(['id' => null], $data)` na criação: funciona apenas porque `id` não está no `$fillable`. | `v6/app/Repositories/Eloquent/Prefecture/StaticPage/StaticPageRepository.php:49` |
| S-B12 | Baixa | `is_external = true` **sem** `links.link` provoca acesso a `pluck('link')[0]` inexistente. A validação `ConditionalRequiredLink` cobre o formulário do CMS, mas não dados importados. | `v6/app/Http/Controllers/Portal/PortalController.php:289-292` |
| S-B13 | Baixa | O `clicks` é incrementado **antes** do `switch` de slugs reservados e antes do redirecionamento externo: visitas que não exibem nada também são contadas. | `v6/app/Http/Controllers/Portal/PortalController.php:286` |
| S-B14 | Baixa | O upload da galeria não grava título nem descrição do arquivo (só `name`, `title` = nome gerado, `extension`). | `v6/app/Http/Controllers/Prefecture/StaticPageController.php:202-232` |
| S-B15 | Baixa | A datatable do CMS não tem paginação server-side: `DB::table('paginas_estaticas')->get()` carrega todas as páginas. | `v6/app/Http/Controllers/Prefecture/DatatableController.php:440-444` |
| S-B16 | Baixa | `StaticPage::all()` é usado na tela `index` do CMS **apesar** de a listagem ser montada por datatable — carga desnecessária. | `v6/app/Http/Controllers/Prefecture/StaticPageController.php:67-83` |

## 2. Funcionalidades incompletas ou mortas

| Item | Situação |
|---|---|
| `static_pages.key` | Coluna nunca lida pelo código do módulo |
| `static_pages.access` | Coluna nunca lida pelo código do módulo |
| `StaticPage::menusItems()` | Definido como `belongsTo` (relação 1:1) para uma FK que é 1:N — relação invertida e sem uso |
| Relações `archives()` e `links()` do `StaticPage` | **Comentadas** no modelo (`v6/app/Http/Model/Prefecture/StaticPage.php:30-38`) |
| `pagina-estatica.show` (rota) | Registrada, mas sem método correspondente |
| `ajax.delete.static.files.gallery` | Registrada, mas o JS usa outra rota |
| `paginas_estaticas.galeria` (coluna da view) | Removida em 2024-10-10, mas ainda referenciada pelo JS |
| `StaticPagesTableSeeder` / `RestoreDefaultStaticPagesSeeder` | O segundo restaura texto com placeholders `xxx` (texto de modelo não revisado) |
| API de páginas estáticas | Inexistente |

## 3. Itens da v5 que mudaram na v6

| Item | v5 | v6 | Efeito |
|---|---|---|---|
| Link externo | gravado cru | `sanitizeLink()` em `store` e `update` | Evita `https:///rota-interna` |
| `is_external` | **Já existia** (mesma migration `2023_09_08_093924`, mesma coluna no banco v5) | idem | **Sem mudança** — o recurso não foi introduzido na v6 |
| Demais métodos | — | — | Sem alteração funcional relevante |

Nenhum item de Páginas Estáticas foi removido na v6.

## 4. Mapa v5 -> v6

| Camada | v5 | v6 | Observação |
|---|---|---|---|
| Modelo | `v5/app/Http/Model/Prefecture/StaticPage.php` | `v6/app/Http/Model/Prefecture/StaticPage.php` | **Idêntico** (0 linhas de diferença) |
| Controller CMS | `v5/app/Http/Controllers/Prefecture/StaticPageController.php` | `v6/app/Http/Controllers/Prefecture/StaticPageController.php` | 40 linhas de diferença: `sanitizeLink()` novo e aplicado em `store`/`update` |
| Form Request | `v5/app/Http/Requests/StaticPageRequest.php` | `v6/app/Http/Requests/StaticPageRequest.php` | **Idêntico** |
| Repository | `v5/app/Repositories/Eloquent/Prefecture/StaticPage/StaticPageRepository.php` | `v6/app/Repositories/Eloquent/Prefecture/StaticPage/StaticPageRepository.php` | 3 linhas: na v5 o conflito de slug era verificado só com categorias **raiz** (`whereNull('category_contents_id')`); na v6 com **qualquer** `category_contents` |
| Regras | `v5/app/Rules/ConditionalRequiredSlug.php` | `v6/app/Rules/ConditionalRequiredSlug.php` | **Idênticas** |
| Regras | `v5/app/Rules/ConditionalRequiredLink.php` | `v6/app/Rules/ConditionalRequiredLink.php` | **Idênticas** |
| Controller portal | `v5/app/Http/Controllers/Portal/PortalController.php` | `v6/app/Http/Controllers/Portal/PortalController.php` | Arquivo inteiro difere (~280 linhas), mas `staticShow()` é equivalente |
| Rotas CMS | `v5/routes/basepro.php:162` (`Route::resource`), `:137`, `:201` | `v6/routes/basepro.php:176`, `:148`, `:229` | Mesmas URIs e nomes |
| Rota portal | `v5/routes/web.php:196` (`/pagina/{slug}`) | `v6/routes/web.php:227` + `v6/routes/basepro.php:548` (`/{slug}`) | A v6 **acrescentou** a rota da raiz com o mesmo nome |
| Views CMS | `v5/resources/views/prefecture/static-pages/` | `v6/resources/views/prefecture/static-pages/` | mesma estrutura |
| Views portal | `v5/resources/views/portal/statics/` | `v6/resources/views/portal/statics/` | mesma estrutura (`show`, `contact`, `form-contact`, `video`) |
| JS do CMS | `v5/public/assets/js/custom/contents/paginas-estaticas/` | `v6/public/assets/js/custom/contents/paginas-estaticas/` | mesma estrutura (`datatable.js`, `archives-pages.js`) |
| Migrations | idem | idem | as mesmas migrations de `static_pages` e da view existem nas duas versões |
| Seeds | `v5/database/seeds/StaticPagesTableSeeder.php` | `v6/database/seeds/StaticPagesTableSeeder.php` | idem |

### Rota acrescentada na v6

| Rota | Efeito |
|---|---|
| `GET /{slug}` -> `static.show` (`v6/routes/basepro.php:548`) | Torna a página acessível pela raiz do domínio; **duplica** o nome de rota e cria o `catch-all` na raiz |

## 5. Riscos de dados (migração de schema)

| Risco | Detalhe | Mitigação |
|---|---|---|
| Slug duplicada (ids 6 e 8) | Bloqueia índice único | Desambiguar antes da migração; a página id 8 tem 17 cliques e nunca foi exibida |
| `clicks` NULL | 3 das 8 páginas do banco têm `clicks` NULL | `COALESCE(clicks, 0)` |
| `is_external = true` sem link | Redirecionamento quebrado | Validar antes de migrar |
| `galery = true` sem arquivos | Botão "Ir para galeria" leva a uma galeria vazia | Normalizar para `false` |
| Páginas de sistema (`status_create = 1`) | 7 das 8 páginas atuais são de sistema | Preservar a regra de não exclusão |
| Colunas `key` e `access` sem uso | Risco de perda se removidas | Deprecar com aviso; não remover sem aval do negócio |
| Slugs publicados (URLs na raiz) | Indexados por buscadores e enviados por e-mail | Manter `/{slug}` (alias permanente) |
| `menu_items.static_pages_id` | Apagamento em cascata feito no controller | Ao migrar, garantir que o mesmo acontece (ou usar `ON DELETE CASCADE`) |

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

1. As páginas devem continuar na **raiz** do domínio (`/{slug}`) ou podem
   migrar para `/paginas/{slug}`?
2. O "Link Permanente" editável deve continuar editável? Hoje a validação
   reserva slugs de outros módulos, o que é frágil.
3. Páginas de sistema (`status_create = 1`) devem poder ser **editadas**?
   Hoje podem (o `update` não bloqueia), mas não podem ser excluídas.
4. O contador de cliques deve contar redirecionamentos e slugs reservados?
5. A galeria precisa de título/descrição por imagem?
6. `key` e `access` podem ser deprecados?
7. Qual o tratamento correto para página inexistente: 404 ou 200?
8. As páginas de sistema devem ser migradas para um pacote de "seeds" ou
   mantidas no banco?

## 7. Checklist de pendências

- [ ] Unificar as rotas `static.show` (uma só) e registrar `/{slug}` como
      alias com 301.
- [ ] Devolver 404 para página inexistente.
- [ ] Remover a rota `pagina-estatica.show` ou implementar `show()`.
- [ ] Repor `galery` na view `paginas_estaticas` (ou alimentar o botão por
      outro canal).
- [ ] Resolver a slug duplicada `manual-de-navegacao` (ids 6 e 8).
- [ ] Criar índice único em `static_pages.slug`.
- [ ] Trocar `$_SERVER['REQUEST_URI']` por parâmetro explícito no
      repository e na regra.
- [ ] Listar campos explicitamente no `structureUpInsert`.
- [ ] Unificar a rota de exclusão de arquivo da galeria.
- [ ] Corrigir o `menusItems()` (belongsTo -> hasMany) e reativar
      `archives()`/`links()` no modelo.
- [ ] Decidir o tratamento de páginas de sistema editáveis.
