# Redes Sociais — Regras de Negócio e Portabilidade

## 1. Regras de negócio observáveis

| # | Regra | Onde está |
|---|---|---|
| R1 | Uma rede social é um `Content` da categoria `rede-social` (id 26) | `v6/database/seeds/CategoryContentTableSeeder.php:152` |
| R2 | A URL fica na tabela `links` (1:1 com `contents`), e não em `contents` | `v6/app/Http/Controllers/Prefecture/ContentController.php:717-733` |
| R3 | `title`, `icon`, `link` e `order` são obrigatórios; `link` no máximo 2999 caracteres | `v6/app/Http/Requests/ContentRequest.php:182-191` |
| R4 | Só redes com `status = true` aparecem no portal | todas as queries do portal |
| R5 | `position_id` decide a localização: 1 Cabeçalho, 2 Rodapé, 3 Ambos | `v6/database/migrations/2023_08_17_094440_position_table_with_data.php` |
| R6 | Cabeçalho mostra quem tem `position_id != 2`; rodapé mostra quem tem `position_id != 1` | views do portal |
| R7 | `isBlank` gera `target="_blank"` no link | `v6/app/Http/Model/Prefecture/Link.php` e views |
| R8 | URLs sem `http` são prefixadas com `http://` | `ContentPresenter::socialNetworkLink()` e cópia inline nas views |
| R9 | A ordem de exibição no CMS é `contents.order`, ajustável por drag-and-drop | `ContentController@ajustOrder` + `AppTrait::reorder` |
| R10 | O módulo do CMS está desativado (`modulos.status = false`) | tabela `modulos`, id 29 |
| R11 | A view SQL `rede_social` ordena por `created_at DESC` e traduz o status | migration `2023_04_10_161440` |

## 2. Acoplamentos

### Dependências de outros módulos

| Módulo | Dependência |
|---|---|
| Conteúdo genérico | `ContentController`, `ContentRequest`, `Content`, `Link` |
| Posições | tabela `positions` (compartilhada com banners, transparência fiscal e acesso rápido) |
| Layout do portal | as views do rodapé/cabeçalho de cada modelo |
| Configuração de layout | tabela `layouts` (blocos de rodapé do `modelo5`) |
| Dashboard/sidebar | `modulos.status` via `ModulosServiceProvider` e `WidgetRegistry` |
| Configurações da instituição | link de entrada `/cms/configuracoes/editar/configuracoes` |

### Dependências deste módulo em outros módulos

| Consumidor | Uso |
|---|---|
| Todos os layouts do portal | exibição de redes no cabeçalho e no rodapé |
| `v6/app/Providers/FooterServiceProvider.php` | composer que entrega `$socialNetworkFooter` |
| `v6/resources/views/components/footer.blade.php` | footer genérico |

## 3. Armadilhas e riscos técnicos

| # | Armadilha | Evidência | Impacto |
|---|---|---|---|
| A1 | A lógica de exibição está duplicada em ~11 arquivos de view, com a query repetida | `modelo1..6` + `default` | correção em um layout não corrige os outros |
| A2 | O `modelo6` não está no composer do `FooterServiceProvider` e consulta o banco por conta própria | `v6/app/Providers/FooterServiceProvider.php:89-95` | comportamento divergente entre modelos |
| A3 | A reordenação por drag-and-drop não funciona: as linhas não têm a classe `item-list` | `v6/resources/views/prefecture/contents/rede-social/index.blade.php` vs `v6/public/assets/js/custom/contents/banners/datatable.js` | `sortable_data` vazio -> `ajustOrder` não altera nada |
| A4 | As permissões do seed (`redes-sociais.*`) não são as avaliadas no código (`rede-social.*`) | `v6/database/seeds/RolesTableSeeder.php:84` vs `has_access(['rede-social.create'])` | botões podem aparecer/não aparecer de forma inesperada |
| A5 | `modulos.status = false` não impede a exibição no portal | nenhuma view do módulo consulta `$modulos` | o operador pode achar que desativou o módulo |
| A6 | A URL é sanitizada por `sanitizeLink(normalizeVideoLink($link))`, função genérica de vídeos | `ContentController@store` | `https://` sem ponto é convertido em caminho interno (linhas 600-607) |
| A7 | `Content::position()` é `hasOne` com chave não padrão | `v6/app/Http/Model/Prefecture/Content.php:77` | confusão para quem lê o código |
| A8 | O prefixo `http://` é forçado quando a URL não começa com `http` | presenter e views | URLs `https://` sem `http` no início não são geradas; `//dominio` vira `http:////dominio` |
| A9 | A view SQL `rede_social` não expõe `icon`, `order` nem `position_id` | migration `2023_04_10_161440` | o CMS não consegue filtrar por posição nem ordenar pela posição |
| A10 | O `status_name` traduzido impede filtro por status no backend do DataTable | idem | filtro só client-side |
| A11 | `isBlank` e `status` não possuem regra de validação | `ContentRequest` | booleanos aceitos sem validação |
| A12 | Não há índice em `contents.category_contents_id` para a consulta do portal | filtro `whereHas` | performance em tabelas grandes |
| A13 | A reordenação usa `AppTrait::reorder`, que faz `update()` item a item (N+1) | `v6/app/Http/Traits/AppTrait.php:741-750` | requisições excessivas em listagens longas |

## 4. Código duplicado entre v5 e v6

| Trecho | v5 | v6 | Observação |
|---|---|---|---|
| Views do CMS | `v5/resources/views/prefecture/contents/rede-social/` | `v6/resources/views/prefecture/contents/rede-social/` | mesma estrutura |
| DataTable do CMS | `v5/public/assets/js/custom/config/redes-sociais/datatable.js` | idem | idêntico |
| Rodapé do `modelo5` | `v5/resources/views/portal/layouts/modelo5/layout/footer/social.blade.php` | `v6/resources/views/portal/layouts/modelo5/layout/footer/social.blade.php` | idêntico (o conteúdo da v5 era o mesmo do modelo6 antigo) |
| Rodapé do `modelo6` | `v5/resources/views/portal/layouts/modelo6/layout/footer/social.blade.php` | `v6/resources/views/portal/layouts/modelo6/layout/footer/footer-social.blade.php` | **reescrito**: na v6 o modelo6 deixou de usar a partial compartilhada (que usa o composer) e passou a fazer a própria query inline, com o título “Redes sociais” |
| View SQL | `v5/database/migrations/2023_04_10_161440_create_view_to_rede-social.php` | idem | mesmo nome e mesmo SQL |
| `modulos` | inexistente na v5 | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` | **novo na v6** |

## 5. Onde a v6 divergiu da v5

- **Tabela `modulos`**: a v6 passou a registrar módulos com chave liga/desliga; `redes-sociais` foi criado já desativado (`status = false`), refletindo a decisão de não mostrar o módulo no dashboard/sidebar por padrão.
- **Resources renomeados**: `AjustesMigracao.php` renomeia o resource `rede-social` para `redes-sociais` (id de módulo 29), separando o slug da **categoria de conteúdo** (`rede-social`) do slug do **módulo do CMS** (`redes-sociais`).
- **Rodapé do `modelo6`**: arquivo `social.blade.php` renomeado para `footer-social.blade.php` e enriquecido com o título “Redes sociais”.
- **Footer composer**: na v6 o `FooterServiceProvider` passou a injetar `$socialNetworkFooter` para os layouts 1 a 5 e para `components.footer`; o `modelo6` ficou de fora.
- **Ícones**: o formulário passou a carregar o Font Awesome 5.15.4 por CDN (a v5 usava a biblioteca local `assets/vendor/adminlte/vendor/font-awesome`), reflexo da migração do Font Awesome 4 para 5 (classes `fab fa-*`).

## 5.1 Checklist de paridade v6 -> v7

| Verificação | Como conferir |
|---|---|
| Mesmo conjunto de redes ativas | comparar a API nova com a query antiga em `contents` |
| Mesma posição visual de cada rede | abrir o portal em cada layout antes e depois |
| Mesma ordem no rodapé | comparar `contents.order` com `sort_order` |
| Mesma normalização de URL | testar `facebook.com/x`, `http://x` e `https://x` |
| `isBlank` continua abrindo em nova aba | inspecionar o atributo `target` |
| Ícones com o mesmo visual | Font Awesome 5.15.4 na v7, com a mesma CDN ou versão local |

## 5.2 Riscos operacionais

| Risco | Cenário | Mitigação proposta na v7 |
|---|---|---|
| Link de rede quebrado | a prefeitura troca a URL da rede e esquece de atualizar | notificação de link inválido (checagem periódica) |
| Rede desativada por engano | o operador desmarca “Ativar” e esquece | log de atividade com quem desativou e quando |
| Ícone incompatível | classe `fab fa-*` inexistente no Font Awesome 5 | lista fechada de classes validada no servidor |
| Conteúdo duplicado | “Instagram” cadastrado duas vezes | unicidade por nome ou por URL |
| Posição inconsistente | registro com `position_id` nulo | `NOT NULL` com default `Ambos` na v7 |

## 6. Regras de equivalência funcional (o que não pode mudar na v7)

1. Uma rede = nome + ícone + URL + posição + estado.
2. A URL continua sendo armazenada separadamente do conteúdo (ou, na v7, em tabela própria — desde que a semântica seja preservada).
3. Redes inativas nunca aparecem no portal.
4. A escolha de posição (cabeçalho, rodapé, ambos) tem exatamente o mesmo efeito visual.
5. `isBlank` continua abrindo o link em nova aba.
6. A ordem definida no CMS é respeitada no rodapé.
