# Feriados Municipais — Gaps, Bugs e Dívidas

## 1. Bugs e erros conhecidos

| # | Severidade | Local | Descrição | Impacto |
|---|---|---|---|---|
| B1 | **Alto** | `v6/app/Repositories/Repository.php` (`upInsert`) | `catch (\Throwable $th) { dd($th); }` | Vazamento de stack trace em produção; o `catch` do controller nunca roda; falha de banco devolve HTTP 200 com HTML de depuração |
| B2 | **Alto** | `v6/app/Repositories/Repository.php` (`destroyAll`) + `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:151` | `destroyAll` retorna `JsonResponse` (sempre truthy); o controller testa `if ($resultado)` | A API responde "deletado com sucesso" mesmo quando nada foi apagado ou houve exceção |
| B3 | **Alto** | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:151` | `$request->toDelete` — propriedade mágica, sem validação de tipo ou existência dos ids | Requests malformadas são aceitas; erros de banco viram sucesso |
| B4 | **Alto** | `v6/resources/views/prefecture/contents/feriados-municipais/index.blade.php` | `<script src="assets/js/custom/Utilities/deleteAll.js">` — capitalização divergente do arquivo real (`utilities`) | 404 em Linux; a **exclusão em lote não funciona** |
| B5 | Médio | `v6/resources/views/prefecture/contents/feriados-municipais/create.blade.php` | Link "Voltar" aponta para `route('servidor.index')` | O operador sai do módulo ao clicar em "Voltar" |
| B6 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:129` | Mensagem "O diário oficial deletado com sucesso!" | Texto do Diário Oficial em um módulo de feriados |
| B7 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:56-68` e `102-118` | `flash('Ocorreu um erro ao tentar cadastrar o registro.')` fora do `try/catch`; mensagem de sucesso do `update` diz "cadastrado" | Mensagens de erro/sucesso incorretas |
| B8 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:20` | `menuClicks('feriados-municipais')` no construtor | O contador de cliques do menu infla com operações administrativas |
| B9 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:23` | `new FeriadosMunicipaisRepository()` em vez do container | Quebra o padrão de injeção de dependência; impede mock em testes |
| B10 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:30-35` | `index()` carrega **todos** os registros em `$content`, que a view não usa | Consulta inútil em cada visita ao index |
| B11 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:79-82` | `show()` com corpo vazio | Rota `GET /cms/feriados-municipais/{id}` devolve 200 sem conteúdo |
| B12 | Médio | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:89-94` | `edit($id)` com id inexistente renderiza o formulário de criação | Salvar cria um registro novo em vez de editar |
| B13 | Baixo | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:63` | `route('painel.feriados-municipais.index', [$result->id])` — parâmetro extra | Rota sem placeholder; o parâmetro é ignorado |
| B14 | Baixo | `v6/app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php:64` | "Registro cadastro com sucesso" | Erro de digitação |
| B15 | Baixo | `v6/resources/views/portal/layouts/modelo6/feriados-municipais/index.blade.php` | Referência a `layouts/modelo6/css/feriados-municipais.css`, que não existe | 404 de CSS; página sem estilo no tema `modelo6` |
| B16 | Baixo | `v6/app/Http/Controllers/Portal/FeriadosMunicipaisController.php` | `use Illuminate\Http\Request;` não utilizado | Código morto |
| B17 | Baixo | `v6/app/Repositories/Eloquent/Prefecture/FeriadosMunicipais/FeriadosMunicipaisRepository.php` | Adiciona o campo `status`, inexistente na tabela | Campo descartado silenciosamente; confusão |
| B18 | Baixo | `v6/routes/basepro.php:335-342` | O array `names` não cobre `show` | A rota `show` fica com o nome `feriados-municipais.show` (sem `painel.`), quebrando o padrão |
| B19 | Baixo | migration `2023_05_29_144236` | `to_char(fm.date::timestamp with time zone, 'DD/MM/YYYY')` | Em fusos negativos, a data pode exibir o dia anterior |

## 2. Funcionalidades incompletas ou mortas

| Item | Situação |
|---|---|
| Rota `show` | Existe e responde 200 vazio — **sem função** |
| `content` passado ao `index()` do CMS | Calculado e nunca usado pela view |
| Campo `status` no `structureUpInsert` | Escrito e descartado |
| Campo `icon` na view SQL | A view do CMS **não expõe** o ícone; o operador não sabe qual ícone está gravado |
| Ordenação da listagem do CMS | Ordena por `created_at` (data de cadastro), não pela data do feriado |
| `active` / `inactivate` | Injetados por `struct_views`, mas não há ação de ativar/desativar no módulo (feriado não tem status) |
| Link permanente / URL individual | Não existe rota pública para um feriado específico |
| Feriados recorrentes | Não há conceito de feriado anual (ex.: "todo dia 25/12"); é preciso cadastrar um por ano |
| Exportação para o portal | Não há CSV/ICS (calendário importável) |
| Importação | Não há carga em lote de feriados |

## 3. Itens existentes na v5 e removidos na v6 (e vice-versa)

**Nenhum item de functionality foi removido.** O módulo é idêntico nas duas
versões, com uma única diferença — a **remoção do seed legacy** na migration.

| Elemento | v5 | v6 |
|---|---|---|
| `app/Http/Controllers/Portal/FeriadosMunicipaisController.php` | presente | **idêntico** |
| `app/Http/Controllers/Prefecture/FeriadosMunicipaisController.php` | presente | **idêntico** |
| `app/Http/Model/Prefecture/FeriadosMunicipais.php` | presente | **idêntico** |
| `app/Http/Requests/FeriadosMunicipaisRequest.php` | presente | **idêntico** |
| `app/Repositories/Contracts/IFeriadosMunicipaisRepository.php` | presente | **idêntico** (interface vazia) |
| `app/Repositories/Eloquent/Prefecture/FeriadosMunicipais/FeriadosMunicipaisRepository.php` | presente | **idêntico** |
| Migration da tabela | presente | **igual, menos o seed** de `resources`/`menu_orders`/`links`/`menu_items` |
| Migration da view | presente | **idêntica** |
| Views do CMS | presentes | **idênticas** |
| Views do portal (6 temas) | presentes | modelo1 e modelo3 com ajuste de CSS na coluna lateral; demais idênticas |
| Componentes do acordeão | presentes | **idênticos** |
| JS do DataTable | presente | `v6/public/assets/js/custom/contents/feriados-municipais/datatable.js` (idêntico) |
| CSS do portal | temas 1-5 | temas 1-5 (sem CSS para o `modelo6`, como na v5) |
| Rotas | `v5/routes/web.php:183`, `v5/routes/basepro.php:307-315,467` | `v6/routes/web.php:205`, `v6/routes/basepro.php:335-343,454` |
| Registro em `modulos` | inexistente | id 51 |
| `resources` / `menu_orders` / `links` / `menu_items` | semeados pela migration | criados fora da migration; `resources` id 70 e `menu_orders` id 37 ligados ao `modulo_id` 51 |

### 3.1 Mapa v5 → v6 (detalhado)

```mermaid
flowchart LR
    V5M["v5 migration create_feriados_municipais_table<br/>cria tabela + semeia resources/menu_orders/links/menu_items"]
    V6M["v6 migration create_feriados_municipais_table<br/>cria SOMENTE a tabela"]
    V5M -->|"mesma tabela"| V6M
    V5R["v5: linhas em resources / menu_orders / links / menu_items<br/>semeadas"]
    V6R["v6: modulos id 51 + resources id 70 + menu_orders id 37<br/>+ menu_items / links cadastrados pela operação"]
    V5R -->|"mesma semântica, nova forma"| V6R
```

O **nome da tabela não mudou** (`feriados_municipais`) e **o nome da view não
mudou** (`lista_feriados_municipais`). A **definição da view é byte a byte
igual**. A única mudança de schema entre v5 e v6 é a **remoção do seed legacy**
da migration de criação da tabela.

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

| Risco | Descrição | Mitigação |
|---|---|---|
| `description` de `text` para `varchar(200)` | A regra do request já limita a 200, mas dados inseridos por script podem exceder | Migration deve verificar e falhar ruidosamente |
| `icon` de `varchar(191)` para `varchar(60)` | Idem | Idem |
| Ausência de índice em `date` | O portal faz `whereYear` sobre a tabela inteira | Criar índice em `date` (e parcial em `(date) WHERE deleted_at IS NULL`) |
| Ausência de unicidade de data | Feriados duplicados são possíveis | Avaliar `UNIQUE (date)` — **exige** antes uma limpeza de duplicidades |
| Dependência da view SQL | `lista_feriados_municipais` é consumida pelo `DatatableController` e por relatórios externos | Manter a view em modo compatibilidade por 1 release |
| `resources.modulo_id` / `menu_orders.modulo_id` | O módulo id 51 é referenciado por essas tabelas | Preservar o id 51 e o slug na migração para a v7 |
| Soft delete sem política de expurgo | Feriados excluídos permanecem indefinidamente | Política de expurgo (ou `prunable`) definida com o negócio |
| Sem registro de auditoria por item | Não há log de quem criou/alterou/excluiu um feriado | Considerar `audits` ou o pacote de auditoria já usado no CMS |

## 5. Dívidas técnicas

| # | Dívida | Esforço na v7 |
|---|---|---|
| D1 | Remover o `dd()` do `catch` e propagating erros corretamente | Baixo |
| D2 | Fazer `destroyAll` retornar `bool` e validar `toDelete` | Baixo |
| D3 | Corrigir o caminho do `deleteAll.js` (404) | Baixo |
| D4 | Corrigir o link "Voltar" e a mensagem "diário oficial" | Baixo |
| D5 | Criar `FormRequest` com validação de data (`date`, `after_or_equal`) | Baixo |
| D6 | Substituir o middleware textual por Policy | Médio |
| D7 | Eliminar as 6 cópias da view do portal (componente único) | Médio |
| D8 | Unificar `card-accordion` e `accordion-item` (Bootstrap 4 e 5) | Médio |
| D9 | Trocar o DataTable client-side por paginação server-side | Médio |
| D10 | Adicionar cache do ano corrente | Baixo |
| D11 | Oferecer seletor de ano no portal (hoje fixo no ano corrente) | Médio — depende de decisão do negócio |
| D12 | Exibir o ícone na listagem do CMS (incluir `icon` na view) | Baixo |
| D13 | Remover a rota `show` inútil | Baixo |
| D14 | Criar testes automatizados (hoje zero cobertura) | Médio |
| D15 | internacionalizar os textos fixos ("Feriados Municipais", "Ícone", mensagens) | Médio |

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

1. O portal deve mostrar **só o ano corrente** (como hoje) ou todos os anos com
   um seletor? Feriados do ano passado são úteis para consulta.
2. Feriados são **anuais e recorrentes**? Se sim, o cadastro deveria ser por
   "data-base + repetição anual", e não por ano.
3. É preciso distinguir **feriado municipal**, **ponto facultativo** e
   **feriado nacional**? Hoje não há nenhum campo de tipo.
4. A ordenação da listagem do CMS deve ser pela data do feriado (hoje é pela
   data de cadastro)?
5. Os feriados devem ser **importáveis** (CSV) a partir do calendário oficial?
6. Deve haver **exportação ICS** (calendário importável) para o cidadão?
7. O ícone deve vir de um **catálogo controlado** (picker) ou aceitar qualquer
   classe CSS?
8. Datas duplicadas devem ser **bloqueadas**?
9. É necessário registrar **quem** cadastrou/alterou/excluiu cada feriado
   (auditoria)?
10. Feriados de **anos anteriores** devem poder ser editados ou apenas
   consultados?
11. O módulo deve continuar **desligável** (`modulos.status`)? Na v7 isso pode
    virar *feature flag*.

## 7. Resumo

Feriados Municipais é um módulo **mínimo e estável**: três campos úteis, um
CRUD no CMS, uma página pública por ano e uma view SQL para o DataTable. O
código é **idêntico na v5 e na v6** — a única mudança é a remoção do seed
legacy da migration. O principal valor da reconstrução está em **corrigir os
bugs de tratamento de erro** (`dd()`, sucesso falso em `destroyAll`,
propriedade mágica `toDelete`), **consertar o 404 do script de exclusão em
lote** e **substituir o middleware textual por Policies e Form Requests** —
mantendo intactos o agrupamento por mês, o formato do dado `icon` e o
comportamento de soft delete.
