# Outras Configurações — Resumo Executivo

> **Versão analisada:** `v6` (existe também na `v5`, com o mesmo comportamento observável)
> **Slug do módulo:** `outras-configuracoes` (tabela `modulos`, id 4, nome "Outras Configurações", `status = 1`)
> **Natureza:** CMS (painel administrativo) — sem contraparte no portal público
> **Estado:** migrado v5 -> v6 (sem controller, model ou tabela próprios)

---

## 1. Objetivo

O módulo "Outras Configurações" é o ponto de entrada do CMS para a gestão de
**chaves de configuração genéricas** do portal (pares `key`/`value` gravados em
`configurations`). Ele existe para permitir que o super-administrador crie,
edite e remova configurações avulsas — e não apenas as configurações de
categoria fechadas ("Site", "Temas", "LGPD"). Na prática, o módulo é a
**listagem genérica de configurações** (`/cms/configuracoes`), com um formulário
universal que aceita categoria, tipo, obrigatoriedade e limites de tamanho.

Detalhe estrutural decisivo: o módulo **não possui controller, model, tabela,
form request ou view exclusivos**. Tudo é reutilizado de
`v6/app/Http/Controllers/Prefecture/ConfigurationController.php`, do model
`App\Prefecture\Configuration` e da tabela `configurations`.

## 2. Efeito / Impacto

| Faixa | Efeito |
|---|---|
| Cidadão | Nenhum efeito direto. As chaves técnicas editadas aqui (e-mail, recaptcha, chaves de API) afetam o portal apenas como consequência indireta de mudanças no ambiente. |
| Prefeitura (CMS) | Fornece a listagem e o CRUD de configurações genéricas; é o único caminho do CMS para cadastrar uma configuração com categoria `outros` (categoria 4, hoje vazia). |
| Transparência e legalidade | Nenhum. O módulo não trata de dados públicos, LGPD ou transparência; é infraestrutura de parametrização. |
| Operação técnica | Alto risco operacional: é por aqui que se tocam credenciais de e-mail, recaptcha e API Gemini — que hoje **não** estão na categoria `outros`, e sim em `site` e `dashboard`. |

## 3. Comportamento

- O item de menu "Outras Configurações" (sidebar do CMS) exige **duas** condições
  simultâneas: `has_access(['outros.index'])` **e** `$modulos['outras-configuracoes']`
  (`v6/resources/views/vendor/adminlte/page.blade.php`, linhas 254-262).
- O clique no menu leva a `GET /cms/configuracoes/editar/outros`
  (`edit.configuracoes.by.category`), que exige `has_access(['outros.edit'])`.
- `ConfigurationController::editByCategory('outros')` cai no `case 'outros':` e
  devolve `$this->index()` — **não existe formulário por categoria** para
  `outros`; o operador volta à mesma tela de listagem.
- A listagem é uma DataTable (Yajra) preenchida por AJAX em
  `GET /cms/datatable/configuracoes`, que lê a **view SQL `configuracoes`**. Essa
  view expõe **todas** as configurações de **todas** as categorias: a tela
  "Outras Configurações" mostra na prática as 87 configurações ativas do
  sistema inteiro, e não apenas as da categoria `outros`.
- O controller carrega `$configurations = $this->getConfiguration('outros')`
  (coleção vazia no banco) e o entrega à view — mas a view **não usa** essa
  variável: o corpo da tabela é preenchido só por AJAX. O que o operador vê
  e o que o controller carrega divergem.
- Criar/editar/excluir configuração é restrito ao papel `super-admin`
  (`Sentinel::inRole('super-admin')`).
- A listagem oferece exportação Excel/PDF/CSV/TXT (botões do helper
  `runDatatables`), e os botões de ação por linha aparecem conforme as
  permissões devolvidas por `DatatableController::struct_views()`.

## 4. Como o Usuário Interage

1. No menu lateral do CMS, o operador clica em "Outras Configurações".
2. A tela "Lista de Configurações" mostra colunas ID, Título, Tipo, Categoria
   e Ações, preenchidas por AJAX.
3. O operador pode exportar a listagem (Excel, PDF, CSV, TXT) ou usar o botão
   "Cadastrar Configuração" (visível na tela, mas o `create()` só abre para
   `super-admin`).
4. No formulário, escolhe **Categoria** (default: 4 = `outros`), **Tipo**
   (`text`, `textarea`, `file`, `checkbox`), Título, limites de caracteres,
   descrições, placeholder, Posição, Obrigatório, Chave e Valor.
5. Ao salvar, a `key` é normalizada por `str_slug($request->get('key'), '_')`.
6. Na edição, se `status_create` for verdadeiro, a `key` fica `disabled`
   (imutável); para `type = file` há upload para o diretório `configuracoes/`.

## 5. Detalhes e Particularidades Técnicas

| Camada | Classe / arquivo | Papel |
|---|---|---|
| Rota | `v6/routes/basepro.php:175`, `:241`, `:246`, `:451` | Resource `configuracoes`, edição por categoria, atualização por categoria, datatable |
| Controller | `v6/app/Http/Controllers/Prefecture/ConfigurationController.php` | `index`, `create`, `store`, `edit`, `update`, `destroy`, `editByCategory`, `updateByCategory` |
| Validação | `v6/app/Http/Requests/ConfigurationRequest.php` | Regras estáticas no CRUD; regras dinâmicas na rota `update.configurations.by.category` |
| Model | `v6/app/Http/Model/Prefecture/Configuration.php` (classe `App\Prefecture\Configuration`) | Tabela `configurations`, `SoftDeletes` |
| Model auxiliar | `v6/app/Http/Model/Prefecture/CategoryConfiguration.php` | Tabela `category_configurations` |
| Trait | `v6/app/Http/Traits/GetInformationsPrefectureTrait.php` | `getConfiguration($reference)` |
| Trait | `v6/app/Http/Traits/FileTrait.php` | `getFileName()` para uploads |
| DataTable | `v6/app/Http/Controllers/Prefecture/DatatableController.php:384` | `get_configuracoes()` lê a view SQL `configuracoes` |
| JS | `v6/public/assets/js/custom/config/configuracoes/datatable.js` | Colunas e helper `runDatatables('configuracoes', collums)` |

- A listagem **não** aplica o filtro de categoria: `get_configuracoes()` faz
  `DB::table("configuracoes")->get()` sobre a view SQL, sem `where`.
- `configurations.key` **não possui índice único**; `updateByCategory` usa
  `Configuration::where('key', $key)->first()`, logo chaves duplicadas gravam
  apenas a primeira ocorrência.
- O módulo depende da view SQL `configuracoes`, criada em
  `v6/database/migrations/2023_04_17_144615_create_view_to_configuracoes.php`.

## 6. Estrutura de Dados

| Objeto | Descrição |
|---|---|
| `configurations` | Tabela real das configurações (`id`, `key`, `value`, `type`, `title`, `category_configurations_id`, `notnull`, `max_input`, `min_input`, `order`, `description`, `placeholder`, `small_description`, `status_create`, `deleted_at`) |
| `category_configurations` | Categorias; a categoria `outros` (id 4) existe mas está **vazia** (0 configurações ativas) |
| view SQL `configuracoes` | Projeção `value`, `titulo`, `categoria`, `id`, `tipo` de **todas** as categorias; fonte da DataTable |
| `modulos` | Registro do módulo (`id = 4`, `slug = 'outras-configuracoes'`, `status = 1`) |
| `resources` | Recurso `slug = 'outros'`, `modulo_id = 4` (permissões `outros.index` / `outros.edit`) |

Categoria `outros` — situação real no banco `prefeituras_v5`:

| id | slug | nome | configurações ativas |
|---|---|---|---|
| 4 | `outros` | Outros | **0** |

Total de configurações ativas no banco: 87 (`site` 57, `temas` 9, `covid` 11,
`barra-privacidade` 4, `dashboard` 6).

## 7. Como Testar

- `GET /cms/configuracoes/editar/outros` com usuário sem `outros.edit` → redirect
  para o dashboard com flash "Você não tem permissão para acessar este conteúdo".
- `GET /cms/configuracoes/editar/outros` com `outros.edit` → renderiza a listagem
  (não um formulário de categoria).
- `GET /cms/datatable/configuracoes` → JSON com **todas** as 87+ configurações,
  incluindo as de categoria `site`, `temas`, `covid`, `barra-privacidade` e
  `dashboard`.
- Criar uma configuração com Categoria = 4 (`outros`) → a linha aparece na
  listagem com `categoria = 'outros'`.
- `DELETE /cms/configuracoes/{id}` → `200` com `{"success": "Configuração deletada com sucesso."}`;
  a linha some da listagem (soft delete).

## 8. Migração para Laravel Moderno

Reconstruir como um **recurso REST de chaves de configuração**, com
`Configuracao`/`ConfiguracaoCategoria` em Eloquent enxuto, `FormRequest` com
regras dinâmicas pré-computadas (eliminar o N+1 do legado), `Policy` por
papel/permissão (`viewAny` = `outros.index`, `create/update/delete` =
`super-admin` ou `configuracoes.edit`), API Resource para a listagem paginada
com filtro real por categoria (corrigindo a divergência registrada em
`08-GAPS-E-DIVIDAS.md`) e tela Blade com componente de tabela.

## 9. Resumo Geral

"Outras Configurações" não é um módulo autônomo: é um **atalho de menu** para a
listagem genérica de configurações do CMS. O único recurso que lhe é próprio é
o par `modulos`/`resources` que habilita a entrada no menu, e o único
comportamento exclusivo é a categoria `outros` da tabela `configurations` —
que, no seed e no banco, **está vazia**. A tela que o operador vê é preenchida
por AJAX a partir da view SQL `configuracoes`, que agrega todas as categorias;
portanto o rótulo não corresponde ao conteúdo. As configurações que o nome
sugere (servidor, e-mail, API keys, Gemini) vivem hoje na categoria `site` e na
categoria `dashboard`, editadas pelo módulo `configuracoes-da-instituicao`
(`../configuracoes-da-instituicao/`). Para a v7, o caminho natural é
transformar o módulo em um CRUD de chaves realmente filtrável por categoria,
com testes que congelem a semântica atual de permissões e a lista de campos.

---

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