# Redes Sociais — Arquitetura

## 1. Visão geral

O módulo é um **caso particular do CRUD genérico de conteúdos**, com duas peculiarities:

1. A URL da rede não fica em `contents`, e sim na tabela `links` (relação `linksUnique`).
2. O módulo possui a noção de **posição de exibição** (`position_id`), que decide se a rede aparece no cabeçalho, no rodapé ou nos dois.

O CMS é único (controller genérico + DataTable). O portal é fragmentado: cada layout do portal
consulta a tabela `contents` por conta própria.

## 2. Fluxo de requisição

### 2.1 CMS — listagem

```
GET /cms/conteudos/rede-social
  -> routes/basepro.php:235  Route::get('conteudos/{slug}') name=listar-conteudo
  -> Prefecture\ContentController@genericIndex('rede-social')
       -> if ($slug === 'rede-social') return $this->returnIndex('Redes Sociais', $slug);
       -> view prefecture.contents.rede-social.index
```

### 2.2 CMS — DataTable

```
GET /cms/datatable/redes_sociais
  -> routes/basepro.php (prefixo 'datatable')
  -> Prefecture\DatatableController@get_redes_sociais
       -> DB::table('rede_social')->get()      // view SQL
       -> struct_views($data, 'rede-social')
       -> DataTables::of($rede_social)->make(true)
```

### 2.3 CMS — criação/edição

```
GET  /cms/conteudos/cadastrar/rede-social  -> genericCreate -> genericGenerate
GET  /cms/conteudos/editar/rede-social/{id} -> genericEdit    -> genericGenerate
POST /cms/conteudo    -> ContentController@store(ContentRequest)   -> Content::create + Link::create
PUT  /cms/conteudo/{id} -> ContentController@update(ContentRequest, $id) -> Content::update + Link::update
```

Em `returnData` (`v6/app/Http/Controllers/Prefecture/ContentController.php:305-308`) o slug
`rede-social` recebe um tratamento especial: além dos dados padrão, é entregue o array
`position` (todas as linhas de `positions`) e a coleção `rede` (as redes já cadastradas, usada
para calcular `max` da posição e o valor default do campo “Posição”).

### 2.4 Portal — cabeçalho e rodapé

Não existe rota pública. O módulo é renderizado dentro de outras páginas:

```
Qualquer página do portal
  -> layout do modelo ativo
       -> header/nav: query inline em `contents` (position_id != 2)
       -> footer: query inline em `contents` (position_id != 1)
          ou coleção `$socialNetworkFooter` injetada por view composer
```

Trecho real do rodapé do `modelo6` (`v6/resources/views/portal/layouts/modelo6/layout/footer/footer-social.blade.php`):

```php
@inject('redes', 'App\Prefecture\Content')
@php
    $redes = $redes
        ->whereHas('categoryContents', function ($query) {
            $query->where('slug', 'rede-social');
        })
        ->where('status', true)
        ->get();
@endphp
```

## 3. Classes envolvidas

| Classe | Caminho | Papel |
|---|---|---|
| `Prefecture\ContentController` | `v6/app/Http/Controllers/Prefecture/ContentController.php` | CRUD genérico; trata `rede-social` em `genericIndex` e `genericGenerate` |
| `Prefecture\DatatableController` | `v6/app/Http/Controllers/Prefecture/DatatableController.php` | `get_redes_sociais()` (linha 240) |
| `App\Http\Requests\ContentRequest` | `v6/app/Http/Requests/ContentRequest.php` | caso `rede-social` (linhas 182-191) |
| `App\Prefecture\Content` | `v6/app/Http/Model/Prefecture/Content.php` | dados da rede |
| `App\Prefecture\Link` | `v6/app/Http/Model/Prefecture/Link.php` | URL e `isBlank` |
| `App\Http\Model\Prefecture\Position` | `v6/app/Http/Model/Prefecture/Position.php` | catálogo de posições |
| `App\Http\Presenters\ContentPresenter` | `v6/app/Http/Presenters/ContentPresenter.php` | `socialNetworkLink()` (linha 140) |
| `App\Providers\FooterServiceProvider` | `v6/app/Providers/FooterServiceProvider.php` | view composer que entrega `$socialNetworkFooter` |
| `App\Providers\ModulosServiceProvider` | `v6/app/Providers/ModulosServiceProvider.php` | entrega `$modulos` (slug -> status) às views do dashboard/sidebar |
| `App\Admin\Modulos` | `v6/app/Http/Model/Admin/Modulos.php` | tabela `modulos` (chave liga/desliga) |

## 4. Diagrama de fluxo

```mermaid
flowchart TD
    A[Operador: Informações da Instituição] --> B[GET /cms/conteudos/rede-social]
    B --> C[ContentController@genericIndex]
    C --> D[View rede-social/index + DataTable JS]
    D --> E[GET /cms/datatable/redes_sociais]
    E --> F[(view rede_social)]
    G[Operador: POST /cms/conteudo] --> H[ContentRequest: case rede-social]
    H --> I[(contents)]
    H --> J[(links)]
    I --> K[Portal: query inline por layout]
    J --> K
    K --> L[Header: position_id != 2]
    K --> M[Footer: position_id != 1]
```

## 5. Dependências externas

| Pacote | Uso |
|---|---|
| `laravel/framework` 5.5 | Eloquent, views, eventos de view |
| `yajra/laravel-datatables` | DataTable do CMS |
| `cartalyst/sentinel` | permissões (`has_access('redes-sociais.edit')`) |
| `diglactic/laravel-breadcrumbs` | não usado neste módulo (não há página pública) |
| `jeroennoten/laravel-adminlte` | menu do CMS (o módulo **não** tem item no menu lateral) |
| jQuery + jQuery UI (`jquery-ui-sortable`) | reordenação por drag-and-drop no CMS |
| `fontawesome-iconpicker` (plugin local) | seleção do ícone da rede |

## 6. Onde o módulo é registrado

| Camada | Arquivo | Trecho |
|---|---|---|
| Categoria | `v6/database/seeds/CategoryContentTableSeeder.php:152` | `CategoryContent::updateOrCreate(['slug' => 'rede-social'], ['name' => 'Rede Social', 'status_create' => 1])` |
| Recurso/permissões | `v6/database/seeds/ResourcesTableSeeder.php:279` | resource `redes-sociais` (id do módulo 29) |
| Renomeação de resource | `v6/database/seeds/AjustesMigracao.php:103-112` | `rede-social` -> `redes-sociais` |
| Ordem de menu | `v6/database/seeds/MenuOrderSeeder.php:166-172` | `menu_orders.slug = rede-social`, `modulo_id = 29` |
| Módulo do CMS | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` | `modulos` id 29, slug `redes-sociais`, `status = false` |
| Papéis | `v6/database/seeds/RolesTableSeeder.php:84` | `redes-sociais.*` = `true` |

> Observação: `modulos.status = false` para `redes-sociais` (confirmado no banco). O status é
> consumido por `ModulosServiceProvider` (cache `modulos`) e por
> `App\Services\Dashboard\WidgetRegistry::moduleAllows()`, e afeta o dashboard e os sidebars.
> Nenhuma das views do módulo consulta `$modulos`, portanto **desativar o módulo não remove as
> redes sociais do portal**.

## 7. Permissões (guard)

Permissões usadas pelo módulo (do seed `v6/database/seeds/RolesTableSeeder.php:84`):

`redes-sociais.index`, `redes-sociais.create`, `redes-sociais.edit`, `redes-sociais.delete`,
`redes-sociais.inactive`, `redes-sociais.inactivate`, `redes-sociais.restore`, `redes-sociais.show`.

A view do CMS verifica `has_access(['rede-social.create'])` — **no singular**, divergente do slug
do recurso (`redes-sociais`). O botão de edição/exclusão no DataTable usa `struct_views($data, 'rede-social')`,
também no singular. Resultado: as permissões do DataTable são avaliadas com o prefixo `rede-social.*`,
enquanto o seed define `redes-sociais.*` — divergência registrada em `08-GAPS-E-DIVIDAS.md`.
