# Módulo SupportConfigs — Suporte Técnico & Preferências do Portal

> **Namespace raiz:** `V2\Modules\SupportConfigs`
> **Blade namespace:** `v2-supportconfigs::`
> **Restrição:** Painel de Suporte → `suporte@maxima.inf.br` | Preferências do Portal → qualquer usuário autenticado

---

## Sumário

1. [Visão Geral](#visão-geral)
2. [Estrutura de Diretórios](#estrutura-de-diretórios)
3. [Arquitetura do Módulo](#arquitetura-do-módulo)
4. [Painel de Suporte — 5 Abas](#painel-de-suporte--5-abas)
   - [Aba 1: Módulos (Feature Flags)](#aba-1-módulos-feature-flags)
   - [Aba 2: Personalização do CMS (White Label)](#aba-2-personalização-do-cms-white-label)
   - [Aba 3: Sistema & Manutenção](#aba-3-sistema--manutenção)
   - [Aba 4: Suporte de Usuários (Helpdesk)](#aba-4-suporte-de-usuários-helpdesk)
   - [Aba 5: Visualizador de Logs](#aba-5-visualizador-de-logs)
5. [Preferências do Portal — 4 Abas](#preferências-do-portal--4-abas)
6. [Migrações](#migrações)
7. [Rotas](#rotas)
8. [Auditoria e Activity Log](#auditoria-e-activity-log)
9. [Fluxo de Dados](#fluxo-de-dados)
10. [Guia de Manutenção](#guia-de-manutenção)

---

## Visão Geral

O módulo **SupportConfigs** reúne duas áreas administrativas distintas dentro do CMS V2:

| Área | Acesso | Finalidade |
|------|--------|------------|
| **Painel de Suporte** | Restrito a `suporte@maxima.inf.br` | Diagnóstico do sistema, feature flags, personalização do CMS, manutenção, helpdesk e logs |
| **Preferências do Portal** | Qualquer usuário autenticado | Configurações visuais e funcionais do portal público (Temas, SEO, E-mail SMTP, Metadados) |

Ambas as áreas operam **dentro do mesmo módulo** por compartilharem o mesmo domínio de dados (tabela `configurations`, service de auditoria, etc.).

---

## Estrutura de Diretórios

```
app/V2/Modules/SupportConfigs/
├── Controllers/
│   ├── SupportConfigsCmsController.php      # Painel de Suporte (5 abas)
│   └── UserConfigsCmsController.php         # Preferências do Portal (4 abas)
├── Migrations/
│   ├── 2026_06_30_000001_create_v2_system_mail_configs_table.php
│   ├── 2026_06_30_000002_create_v2_module_flags_table.php
│   └── 2026_06_30_000003_create_v2_system_controls_table.php
├── ModuleProvider.php                        # Registro + ViewComposer do tema do portal
├── Routes/
│   └── cms.php                              # Rotas administrativas (CMS)
├── Services/
│   ├── SupportConfigsService.php            # Lógica do Painel de Suporte
│   └── UserConfigsService.php               # Lógica das Preferências do Portal
└── Views/cms/
    ├── supportConfigs/                       # Views do Painel de Suporte
    │   ├── index.blade.php
    │   └── tabs/
    │       ├── modulos.blade.php
    │       ├── personalizacao.blade.php
    │       ├── manutencao.blade.php
    │       ├── suporte.blade.php
    │       └── logs.blade.php
    └── userConfigs/                          # Views das Preferências do Portal
        ├── index.blade.php
        ├── components/
        │   └── config-history.blade.php
        └── tabs/
            ├── temas.blade.php
            ├── seo.blade.php
            ├── email.blade.php
            └── metadados.blade.php
```

---

## Arquitetura do Módulo

### ModuleProvider

O `ModuleProvider.php` registra o módulo no sistema de navegação dinâmica da V2 e também injeta as configurações de tema do portal em todas as views do portal via `View::composer`.

```php
// Registro no Sidebar
'group' => 'SISTEMA',
'position' => 90,         // Último no grupo
'restricted' => 'suporte@maxima.inf.br'  // Oculto para não-autorizados

// ViewComposer global
View::composer('v2-portal::*', function ($view) {
    $view->with('portalTheme', [...]);
});
```

### Cadeia de Chamadas

```
Navegador → Rota CMS → Middleware CmsAuthenticate → Controller → Service → DB/Model → View
```

- **Controllers**: Chamam o service e passam dados para a view. Finos.
- **Services**: Toda a lógica de negócio, persistência e auditoria.
- **Views**: Renderizam formulários e tabelas com Bootstrap 3 + FontAwesome 4.7.

---

## Painel de Suporte — 5 Abas

### Aba 1: Módulos (Feature Flags)

**Arquivo:** `Views/cms/supportConfigs/tabs/modulos.blade.php`
**Backend:** `SupportConfigsService::getModulesStatus()`, `toggleModule()`, `updateModulesBatch()`

#### Tabela: `v2_module_flags`

| Coluna | Tipo | Descrição |
|--------|------|-----------|
| `id` | UUID (PK) | Gerado pela aplicação |
| `module_key` | VARCHAR(100) UNIQUE | Chave do módulo (ex: `noticias`) |
| `module_title` | VARCHAR(255) | Nome amigável |
| `active` | BOOLEAN | `true` = visível, `false` = oculto |
| `module_group` | VARCHAR(50) | Grupo do sidebar (ex: `CONTEUDO`) |
| `transaction_snapshot_id` | UUID | Auditoria V2 |
| `created_at` / `updated_at` | TIMESTAMP | — |
| `deleted_at` | TIMESTAMP | Soft delete |

#### Como funciona

1. O método `getModulesStatus()` mescla módulos registrados no container `v2.modules.configs` com os registros da tabela `v2_module_flags`.
2. Módulos sem registro na tabela são considerados `active = true` por padrão (compatibilidade retroativa).
3. O formulário envia um POST para `v2.supportconfigs.modules.batch` com todos os checkboxes.
4. O service persiste cada flag individualmente com auditoria e invalida o cache `v2_module_flags`.

#### Seed automático

Na migration, os seguintes módulos são pré-cadastrados como ativos:

| Module Key | Título | Grupo |
|-----------|--------|-------|
| `noticias` | Módulo de Notícias | CONTEUDO |
| `licitacoes` | Módulo de Licitações | CONTEUDO |
| `diario` | Diário Oficial Eletrônico | CONTEUDO |
| `homepage` | Gerenciador da Home Page | CONTEUDO |
| `layoutbase` | Layout Base (Logos, Contato) | SISTEMA |
| `galeria` | Galeria de Mídias | CONTEUDO |
| `supportconfigs` | Suporte Técnico e Configs | SISTEMA |

---

### Aba 2: Personalização do CMS (White Label)

**Arquivo:** `Views/cms/supportConfigs/tabs/personalizacao.blade.php`
**Backend:** `SupportConfigsService::getCmsThemeConfigs()`, `saveCmsThemeConfigs()`, `resetCmsThemeToDefault()`

#### Chaves de configuração

Armazenadas na tabela dedicada **`v2_cms_theme_configs`** (sem FK, sem `type`, sem `category_configurations_id` — schema independente da V1):

| Coluna | Tipo | Descrição |
|--------|------|-----------|
| `id` | UUID (PK) | Gerado pela aplicação |
| `config_key` | VARCHAR(100) UNIQUE | Chave da configuração (ex: `cms_sidebar_bg`) |
| `config_value` | VARCHAR(20) | Valor hex da cor (ex: `#222d32`) |
| `config_title` | VARCHAR(255) | Descrição amigável |
| `transaction_snapshot_id` | UUID | Auditoria V2 |
| `created_at` / `updated_at` | TIMESTAMP | — |
| `deleted_at` | TIMESTAMP | Soft delete |

| Chave | Padrão | Descrição |
|-------|--------|-----------|
| `cms_sidebar_bg` | `#222d32` | Fundo da barra lateral |
| `cms_brand_primary` | `#3c8dbc` | Cor da header e botões |
| `cms_body_bg` | `#ecf0f5` | Fundo da área de conteúdo |
| `cms_text_color` | `#333333` | Cor do texto principal |

#### Como funciona

1. O painel carrega as configurações atuais da tabela `configurations`.
2. O formulário permite ajustar as 4 cores via `<input type="color">`.
3. Ao salvar, cada chave é persistida individualmente com auditoria `old`/`new`.
4. O botão **Restaurar Cores Padrões** chama `resetCmsThemeToDefault()` que restaura os valores padrão.

> **Nota:** Para aplicar as alterações no CMS, é necessário forçar `Ctrl+F5` no navegador (cache de CSS). Futuramente, será implementado um sistema de variáveis CSS dinâmicas no layout.

---

### Aba 3: Sistema & Manutenção

**Arquivo:** `Views/cms/supportConfigs/tabs/manutencao.blade.php`
**Backend:** `SupportConfigsService::getSystemControls()`, `updateSystemControlsBatch()`

#### Tabela: `v2_system_controls`

| Coluna | Tipo | Descrição |
|--------|------|-----------|
| `id` | UUID (PK) | Gerado pela aplicação |
| `control_key` | VARCHAR(100) UNIQUE | Chave do controle |
| `control_value` | TEXT | Valor armazenado (`"true"`/`"false"`) |
| `control_title` | VARCHAR(255) | Descrição amigável |
| `transaction_snapshot_id` | UUID | Auditoria V2 |
| `timestamps` + `softDeletes` | — | — |

#### Controles disponíveis

| Control Key | Padrão | Efeito |
|------------|--------|--------|
| `maintenance_mode` | `false` | Ativa banner no CMS + página de manutenção no portal |
| `app_debug` | ENV `APP_DEBUG` | Exibe stack traces de erros 500 |
| `debugbar_enabled` | `false` | Ativa a barra de profiling Laravel Debugbar |

#### Helper `isMaintenanceActive()`

A função global em `app/Helpers/functions.php` foi atualizada para verificar:

1. **Primeiro**: Tabela `v2_system_controls` (controle `maintenance_mode`)
2. **Fallback**: Tabela `configurations` (chave `pagina_em_manutencao`) — compatibilidade V1

O banner de manutenção é renderizado em `resources/V2/cms/layouts/maintenance-banner.blade.php` quando a função retorna `true`.

---

### Aba 4: Suporte de Usuários (Helpdesk)

**Arquivo:** `Views/cms/supportConfigs/tabs/suporte.blade.php`
**Backend:** `SupportConfigsService::searchUsers()`, `getUserDetail()`, `forcePasswordReset()`, `getUserActivityLog()`

#### Funcionalidades

| Funcionalidade | Endpoint | Descrição |
|---------------|----------|-----------|
| Busca de usuários | `GET /users/search?q=termo` | Busca por e-mail ou nome (ILIKE) via Sentinel |
| Detalhes do usuário | `GET /users/detail/{id}` | Dados + activity_log do usuário |
| Reset de senha forçado | `POST /users/reset-password` | Altera senha via `Sentinel::update()` + auditoria |

#### Busca de Usuários

- Utiliza `Sentinel::getUserRepository()` com filtro `ILIKE` em `email`, `first_name` e `last_name`.
- Retorna dados básicos: id, nome, e-mail, papéis (roles), último login.
- Limite de 20 resultados por busca.
- Aciona o modal de reset de senha ao clicar no ícone de chave.

#### Detalhes do Usuário (AJAX)

- Carregado via requisição `fetch()` assíncrona.
- Exibe: dados cadastrais, papéis, permissões, último login, data de criação.
- Lista as últimas 30 atividades do usuário no `activity_log` (com data, descrição, alvo e IP).

#### Reset de Senha

- Exige no mínimo 6 caracteres.
- Utiliza `Sentinel::update($user, ['password' => $newPassword])`.
- Registra auditoria via `ActivityLoggerService` com contexto `password_reset`.
- O usuário afetado precisa usar a nova senha no próximo login — não há notificação automática.

---

### Aba 5: Visualizador de Logs

**Arquivo:** `Views/cms/supportConfigs/tabs/logs.blade.php`
**Backend:** `SupportConfigsService::getLogTail()`, `clearLogFile()`

#### Como funciona

1. **Leitura**: O método `getLogTail()` lê as últimas 500 linhas do arquivo `storage/logs/laravel.log`.
2. **Método de leitura**: Utiliza `shell_exec('tail -n 500 ...')` se disponível (mais eficiente para logs grandes). Fallback para leitura manual com `fseek()` de trás para frente.
3. **Syntax highlighting**: O JavaScript cliente colore as linhas por nível de severidade:
   - `[ERROR]`, `[CRITICAL]` → vermelho
   - `[WARNING]` → laranja
   - `[INFO]` → verde
   - `[DEBUG]` → azul
   - Timestamps → azul claro
4. **Auto-carregamento**: Ao clicar na aba "Visualizador de Logs", o conteúdo é carregado automaticamente via AJAX.
5. **Limpeza**: O botão "Limpar Arquivo de Log" gera um backup em `storage/logs/laravel-{data}.log.bak` antes de truncar o arquivo.

#### Segurança

- Toda a aba é restrita ao e-mail `suporte@maxima.inf.br`.
- O botão de limpeza exige confirmação (`confirm()`).
- Backups automáticos são gerados antes de qualquer limpeza, preservando o histórico.

---

## Preferências do Portal — 4 Abas

Este sub-módulo gerencia as configurações do **portal público** e já estava funcional antes da integração. Abaixo um resumo:

### Aba Temas e Cores

**Arquivo:** `tabs/temas.blade.php`

Define o **Design System** do portal através das chaves `theme_*` na tabela `configurations`:

| Chave | Descrição | Padrão |
|-------|-----------|--------|
| `theme_primary_color` | Cor principal | `#1075ad` |
| `theme_accent_color` | Cor de destaque | `#fece50` |
| `theme_link_color` | Cor de links | `#1075ad` |
| `theme_bg_main` | Fundo principal | `#ffffff` |
| `theme_bg_canvas` | Fundo secundário | `#f8f9fa` |
| `theme_font_family` | Fonte principal | `'Nunito Sans', ...` |
| `theme_font_size_base` | Tamanho base | `16` |
| `theme_border_radius` | Arredondamento | `4px` |
| `theme_shadow_intensity` | Sombra | `none` |

**Cadeia de disseminação:**
```
formulário → UserConfigsService → configurations (tabela)
  → ModuleProvider (ViewComposer) → $portalTheme
    → base.struct/{colors,fonts,normalize}.blade.php
      → base.blade.php → TODAS as páginas do portal
```

### Aba SEO e Scripts

**Arquivo:** `tabs/seo.blade.php`

| Chave | Descrição |
|-------|-----------|
| `google_analytics_id` | Google Analytics G-Tag |
| `palavras_chaves` | Meta keywords |
| `global_meta_tokens` | Tokens de verificação (Google, Bing) |
| `header_scripts` | Scripts injetados no `<head>` |
| `footer_scripts` | Scripts injetados antes do `</body>` |

**Cadeia de disseminação:**
```
formulário → UserConfigsService → configurations
  → SEOServiceProvider (ViewComposer) → $seoTitle, $seoDescription, etc.
    → metadata/{seo,gtag,metaheader,metafooter}.blade.php
      → base.blade.php → TODAS as páginas
```

### Aba E-mail do Sistema

**Arquivo:** `tabs/email.blade.php`

Configurações SMTP armazenadas na tabela `v2_system_mail_configs`:

| Coluna | Descrição |
|--------|-----------|
| `profile` | Nome do perfil (atualmente apenas `default`) |
| `driver` | smtp, sendmail, mailgun, ses ou log |
| `host`, `port`, `encryption` | Servidor SMTP |
| `username`, `password` | Autenticação |
| `from_address`, `from_name` | Remetente padrão |

### Aba Metadados

**Arquivo:** `tabs/metadados.blade.php`

| Chave | Descrição |
|-------|-----------|
| `titulo_site` | Nome oficial da instituição |
| `descricao` | Meta description global (120-160 caracteres) |
| `categoria_governo` | Prefeitura, Câmara ou Autarquia |
| `cnpj_orgao` | CNPJ do órgão |

### Componente de Histórico

**Arquivo:** `components/config-history.blade.php`

Componente Blade reutilizável que exibe as últimas 10 alterações de uma aba específica. Utilizado em Temas, SEO e Metadados.

```blade
@include('v2-supportconfigs::cms.userConfigs.components.config-history', [
    'tabLabel' => 'Temas e Cores',
    'monitoredKeys' => ['theme_primary_color', 'theme_accent_color', ...]
])
```

---

## Migrações

| Migration | Tabela | Finalidade |
|-----------|--------|------------|
| `2026_06_30_000001_create_v2_system_mail_configs_table` | `v2_system_mail_configs` | Configurações SMTP isoladas |
| `2026_06_30_000002_create_v2_module_flags_table` | `v2_module_flags` | Feature flags dos módulos |
| `2026_06_30_000003_create_v2_system_controls_table` | `v2_system_controls` | Controles de sistema |

> **Rollback seguro:** Todas as migrations renomeiam a tabela para `backup_*` em vez de `DROP`, preservando dados.

Para executar:
```bash
php artisan migrate --path=app/V2/Modules/SupportConfigs/Migrations
```

---

## Rotas

Todas as rotas do Painel de Suporte são prefixadas com `cms/infra/support-configs/` e protegidas pelo middleware `CmsAuthenticate`.

### Painel de Suporte

| Método | Rota | Controller | Nome |
|--------|------|-----------|------|
| GET | `/` | `SupportConfigsCmsController@index` | `v2.supportconfigs.index` |
| POST | `/clear-cache` | `SupportConfigsCmsController@clearCache` | `v2.supportconfigs.clear_cache` |
| POST | `/modules/toggle` | `SupportConfigsCmsController@toggleModule` | `v2.supportconfigs.modules.toggle` |
| POST | `/modules/batch` | `SupportConfigsCmsController@updateModulesBatch` | `v2.supportconfigs.modules.batch` |
| POST | `/cms-theme/save` | `SupportConfigsCmsController@saveCmsTheme` | `v2.supportconfigs.cms_theme.save` |
| POST | `/cms-theme/reset` | `SupportConfigsCmsController@resetCmsTheme` | `v2.supportconfigs.cms_theme.reset` |
| POST | `/system-controls/save` | `SupportConfigsCmsController@saveSystemControls` | `v2.supportconfigs.system_controls.save` |
| GET | `/users/search` | `SupportConfigsCmsController@searchUsers` | `v2.supportconfigs.users.search` |
| GET | `/users/detail/{id}` | `SupportConfigsCmsController@getUserDetail` | `v2.supportconfigs.users.detail` |
| POST | `/users/reset-password` | `SupportConfigsCmsController@forcePasswordReset` | `v2.supportconfigs.users.reset_password` |
| GET | `/logs/tail` | `SupportConfigsCmsController@getLogTail` | `v2.supportconfigs.logs.tail` |
| POST | `/logs/clear` | `SupportConfigsCmsController@clearLogFile` | `v2.supportconfigs.logs.clear` |

### Preferências do Portal

| Método | Rota | Controller | Nome |
|--------|------|-----------|------|
| GET | `/cms/infra/user-configs` | `UserConfigsCmsController@index` | `v2.supportconfigs.user_configs` |
| POST | `/cms/infra/user-configs` | `UserConfigsCmsController@update` | `v2.supportconfigs.user_configs.post` |

---

## Auditoria e Activity Log

Todas as operações de escrita seguem o padrão **LayoutBase** — cada chave é persistida individualmente com valores `old`/`new` no `activity_log` via `ActivityLoggerService`.

### Operações auditadas

| Operação | Contexto | Dados registrados |
|----------|----------|-------------------|
| Ativação/desativação de módulo | `feature_flag` | `{ context, target: module_key, value: boolean }` |
| Alteração de tema CMS | Configurations | `{ old, new, config_key }` |
| Alteração de controle de sistema | `system_control` | `{ context, target: control_key, value: boolean }` |
| Reset de senha de usuário | `password_reset` | `{ context, target: 'user#id', value: 'forced_reset' }` |
| Limpeza de arquivo de log | `log_clear` | `{ context, target: 'laravel.log', value: 'backup filename' }` |
| Alteração de tema do portal | Configurations | `{ old, new, config_key }` |
| Alteração de SEO/Metadados | Configurations | `{ old, new, config_key }` |
| Alteração de e-mail SMTP | `system_mail_config` | `{ old: payload, new: payload, profile }` |

---

## Fluxo de Dados

### Painel de Suporte → Banco

```
Usuário (suporte@...) → Formulário HTML → Rota CMS POST
  → SupportConfigsCmsController → SupportConfigsService
    → DB (v2_module_flags / configurations / v2_system_controls)
    → ActivityLoggerService → activity_log
  → redirect()->back() com flash message
```

### Preferências do Portal → Portal Público

```
Usuário autenticado → Formulário → Rota CMS POST
  → UserConfigsCmsController → UserConfigsService
    → Configuration::firstOrNew() + save()
    → ActivityLoggerService → activity_log
  → redirect()->back() com flash message

[Leitura]
  → ModuleProvider (ViewComposer) / SEOServiceProvider
    → $portalTheme / $seoTitle / etc.
      → Layouts do portal (base.blade.php)
        → TODAS as páginas públicas
```

---

## Guia de Manutenção

### Adicionar novo módulo ao gerenciador de feature flags

1. Crie seu `ModuleProvider` com `getConfig()` implementado.
2. O sistema de auto-discovery da V2 o registrará automaticamente.
3. Adicione um seed na migration `v2_module_flags` se quiser que ele apareça pré-cadastrado.
4. Opcional: adicione ao `$titles` em `getDefaultModuleTitle()` no `SupportConfigsService.php`.

### Adicionar nova cor de personalização do CMS

1. Adicione a chave no array `$keys` de `getCmsThemeConfigs()` no `SupportConfigsService`.
2. Adicione o valor padrão no array `$defaults`.
3. Adicione o título no método `getCmsConfigTitle()`.
4. Adicione o `<input type="color">` na view `personalizacao.blade.php`.

### Adicionar novo controle de sistema

1. Adicione no array `$allowedKeys` do método `updateSystemControl()`.
2. Adicione um seed na migration `v2_system_controls`.
3. Adicione o checkbox na view `manutencao.blade.php`.

## Integração com o Core V2

O módulo SupportConfigs não opera isolado — ele alimenta **três subsistemas do Core V2** que dependem dos dados que ele gerencia.

### Feature Flags → Sidebar + Middleware

```
Painel de Suporte → v2_module_flags
  → ModuleFlagService (Core) → SidebarComposer (oculta módulos)
                             → ModuleAccessMiddleware (bloqueia rotas)
```

#### ModuleFlagService — `app/V2/Core/Services/ModuleFlagService.php`

Serviço singleton que provê acesso às flags da tabela `v2_module_flags`:

```php
$flagService = app(ModuleFlagService::class);
$flagService->isActive('Noticias');      // bool
$flagService->filterActive($modules);     // filtra array
$flagService->refresh();                  // recarrega cache
```

- Cache estático (1 query por request)
- Case-insensitive: aceita `PascalCase`, `snake_case`, `lowercase`
- Se não há flag, módulo é considerado **ativo** (compatibilidade)

#### ModuleAccessMiddleware — `app/V2/Core/Middleware/ModuleAccessMiddleware.php`

Registrado no Kernel como `module.active`. Aplicado automaticamente nas rotas CMS de **todos os módulos V2** pelo `V2ServiceProvider::mapModuleRoutes()`:

```php
Route::middleware(['web', 'module.active:Noticias'])->group($cmsRoutes);
```

| Cenário | Comportamento |
|---------|---------------|
| Módulo **ativo** | Passa |
| Módulo **desativado** + AJAX | JSON 404 |
| Módulo **desativado** + CMS | Redirect p/ dashboard com flash |
| Módulo **desativado** + Portal | HTTP 404 |

#### SidebarComposer — `app/V2/Core/ViewComposers/SidebarComposer.php`

Filtra os módulos ANTES da verificação de permissões:

```php
$moduleConfigs = $moduleFlagService->filterActive($moduleConfigs);
```

### Tema CMS → ViewComposer + CSS Injection

```
Painel de Suporte → v2_cms_theme_configs
  → CmsThemeComposer (ViewComposer)
    → <style> com variáveis CSS em todas as páginas do CMS
```

#### CmsThemeComposer — `app/V2/Modules/SupportConfigs/ViewComposers/CmsThemeComposer.php`

ViewComposer registrado no `ModuleProvider` para o layout `v2-cms::layouts.app`:

Lê `v2_cms_theme_configs` e gera um bloco `<style>` com **variáveis CSS nativas** que sobrescrevem o AdminLTE:

```css
:root {
    --cms-sidebar-bg: #222d32;
    --cms-brand-primary: #3c8dbc;
    --cms-body-bg: #ecf0f5;
}
.skin-blue .main-sidebar { background-color: var(--cms-sidebar-bg); }
.skin-blue .main-header .navbar { background-color: var(--cms-brand-primary); }
.content-wrapper { background-color: var(--cms-body-bg); }
/* + botões, links, tabs, paginação, toggle — todos sobrescritos */
```

Renderizado no `<head>` do layout `app.blade.php`:

```blade
@isset($cmsThemeCss)
    {!! $cmsThemeCss !!}
@endisset
```

### Manutenção → Middleware + Banner + Helper Global

```
Painel de Suporte → v2_system_controls (maintenance_mode)
  → isMaintenanceActive() (helper global)
    → MaintenanceMiddleware (bloqueia portal V2)
    → maintenance-banner.blade.php (banner no CMS)
```

#### MaintenanceMiddleware — `app/V2/Core/Middleware/MaintenanceMiddleware.php`

| Cenário | Comportamento |
|---------|---------------|
| Manutenção **OFF** | Passa |
| Manutenção **ON** + usuário logado no CMS | Passa (vê banner) |
| Manutenção **ON** + visitante anônimo | 503 |
| Manutenção **ON** + AJAX | JSON `{ error: 503 }` |

Registrado como `maintenance.v2` no Kernel e aplicado em todas as rotas web do portal (Core + Módulos + Serviços).

#### Helper `isMaintenanceActive()` — `app/Helpers/functions.php`

Chamado pelo middleware e pelo banner. Lê da **V2 primeiro**:

```php
// 1. Tenta v2_system_controls (se a migration já rodou)
$v2Control = DB::table('v2_system_controls')->where('control_key', 'maintenance_mode')->first();
if ($v2Control !== null) {
    return $v2Control->control_value === 'true';  // Só V2 decide
}

// 2. Fallback V1 (se a migration V2 ainda não foi executada)
$maintenance = Configuration::where('key', 'pagina_em_manutencao')->first();
return $maintenance && $maintenance->value == '1';
```

### APP_DEBUG e Debugbar — Aplicação Runtime

```
Painel de Suporte → v2_system_controls (app_debug / debugbar_enabled)
  → SupportConfigsService::applySystemControl()
    → config(['app.debug' => true/false])
    → config(['debugbar.enabled' => true/false])
    → app('debugbar')->enable()/disable()
    → ini_set('display_errors', '1'/'0')
```

Os efeitos são **imediatos** — não precisam de reinício do PHP-FPM.

### Helper `v2_uuid()` — `app/V2/Core/Helpers/helpers.php`

O Laravel 5.5 **não** possui `Str::uuid()`. Para gerar UUIDs v4 em todo o ecossistema V2, foi criado o helper:

```php
function v2_uuid() {
    $data = random_bytes(16);
    $data[6] = chr(ord($data[6]) & 0x0f | 0x40);  // versão 4
    $data[8] = chr(ord($data[8]) & 0x3f | 0x80);  // RFC 4122
    return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
```

Utilizado em todos os Services do módulo SupportConfigs (toggleModule, updateSystemControl, saveCmsThemeConfig, persistMailConfig, PortalConfigsService::save).