# Telefones Úteis — Arquitetura

## 1. Visão geral

O módulo é um **caso particular do CRUD genérico de conteúdos** do CMS. Não existe controller, model ou tabela próprios: o telefone é um `Content` cuja `category_contents_id` aponta para a categoria `telefones-uteis`. O portal, por sua vez, tem um controller dedicado (`UsefulPhonesController`) que apenas filtra a mesma tabela pela categoria.

## 2. Fluxo de requisição

### 2.1 Portal (público)

```
GET /telefones-uteis
  -> routes/web.php:97 (Route::any, dentro do grupo com middleware check.site.manutention)
  -> Portal\UsefulPhonesController@getIndex
       -> GetInformationsPrefectureTrait::getContentByCategory('telefones-uteis')
            -> Content::whereHas('categoryContents', slug = 'telefones-uteis')->get()
       -> view portal.layouts.{layout}.informacoes-instituicao.telefones-uteis.index
```

Código real do controller (`v6/app/Http/Controllers/Portal/UsefulPhonesController.php`):

```php
public function getIndex()
{
    $contents = $this->getContentByCategory('telefones-uteis');

    return view('portal.layouts.'.$this->getTemplateActived().'.informacoes-instituicao.telefones-uteis.index',
        compact('contents'));
}
```

### 2.2 CMS — listagem

```
GET /cms/conteudos/telefones-uteis
  -> routes/basepro.php:235  Route::get('conteudos/{slug}') name=listar-conteudo
  -> Prefecture\ContentController@genericIndex($slug)
       -> if ($slug === 'telefones-uteis') return $this->returnIndex('Telefones Úteis', $slug);
       -> returnIndex(): generateLog($title); menuClicks($slug);
       -> view prefecture.contents.telefones-uteis.index
```

### 2.3 CMS — DataTable (fonte de dados da listagem)

```
GET /cms/datatable/telefones_uteis
  -> routes/basepro.php:436 (prefixo 'datatable', name datatable.telefones_uteis)
  -> Prefecture\DatatableController@get_telefones_uteis
       -> DB::table('telefones_uteis')->get()      // view SQL
       -> struct_views($data, 'telefones-uteis')   // injeta edit/delete/active/inactivate
       -> DataTables::of($data)->make(true)
```

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

```
GET  /cms/conteudos/cadastrar/telefones-uteis -> genericCreate -> genericGenerate -> returnData('Telefones Úteis', 'telefones-uteis')
GET  /cms/conteudos/editar/telefones-uteis/{id} -> genericEdit -> returnData($title, $slug, null, [], $id)
POST /cms/conteudo   -> ContentController@store(ContentRequest)
PUT  /cms/conteudo/{id} -> ContentController@update(ContentRequest, $id)
```

## 3. Classes envolvidas

| Classe | Caminho | Papel |
|---|---|---|
| `Portal\UsefulPhonesController` | `v6/app/Http/Controllers/Portal/UsefulPhonesController.php` | Controller público; monta a view do layout ativo |
| `Prefecture\ContentController` | `v6/app/Http/Controllers/Prefecture/ContentController.php` | CRUD genérico do CMS usado por telefones, glossário, perguntas frequentes etc. |
| `Prefecture\DatatableController` | `v6/app/Http/Controllers/Prefecture/DatatableController.php` | Serialização do DataTable (Yajra) |
| `App\Http\Requests\ContentRequest` | `v6/app/Http/Requests/ContentRequest.php` | Validação por `slug` da categoria (`case 'telefones-uteis':`) |
| `GetInformationsPrefectureTrait` | `v6/app/Http/Traits/GetInformationsPrefectureTrait.php` | `getContentByCategory()`, `getTemplateActived()` e afins |
| `App\Prefecture\Content` | `v6/app/Http/Model/Prefecture/Content.php` | Eloquent da tabela `contents` (SoftDeletes, `PresentableTrait`) |
| `App\Prefecture\CategoryContent` | `v6/app/Http/Model/Prefecture/CategoryContent.php` | Eloquent da tabela `category_contents` |
| `App\Http\Model\Admin\Phone` | `v6/app/Http/Model/Admin/Phone.php` | **Não usado** por este módulo (fluxo LAI) |
| `App\Admin\PhoneType` | `v6/app/Http/Model/Admin/PhoneType.php` | **Não usado** por este módulo (fluxo LAI) |
| `App\Admin\Person` | `v6/app/Http/Model/Admin/Person.php` | **Não usado** por este módulo (fluxo LAI) |

## 4. Diagrama de fluxo

```mermaid
flowchart TD
    A[Cidadão GET /telefones-uteis] --> B[UsefulPhonesController@getIndex]
    B --> C[getContentByCategory telefones-uteis]
    C --> D[(contents + category_contents)]
    D --> E[View do layout ativo]
    F[Operador GET /cms/conteudos/telefones-uteis] --> G[ContentController@genericIndex]
    G --> H[View index + DataTable JS]
    H --> I[GET /cms/datatable/telefones_uteis]
    I --> J[DatatableController@get_telefones_uteis]
    J --> K[(view telefones_uteis)]
    L[Operador POST /cms/conteudo] --> M[ContentRequest rules]
    M --> N[ContentController@store]
    N --> D
```

## 5. Dependências externas

| Pacote | Uso |
|---|---|
| `laravel/framework` 5.5 | roteamento, Eloquent, views |
| `yajra/laravel-datatables` | resposta JSON do DataTable do CMS |
| `cartalyst/sentinel` | sessão e permissões (`has_access`) |
| `jeroennoten/laravel-adminlte` | item de menu do CMS montado em `MenuServiceProvider` (evento `BuildingMenu`) |
| `diglactic/laravel-breadcrumbs` | breadcrumb `telefones-uteis` |

## 6. Onde o módulo é registrado

| Camada | Arquivo | Trecho |
|---|---|---|
| Módulo do CMS | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` | `modulos` id 27, slug `telefones-uteis`, `status = true` |
| Recurso/permissão | `v6/database/seeds/ResourcesTableSeeder.php` | resource `telefones-uteis` |
| Ordem de menu | `v6/database/seeds/MenuOrderSeeder.php` | `menu_orders.slug = telefones-uteis` |
| Item de menu | `v6/app/Providers/MenuServiceProvider.php` | `case 'telefones-uteis':` -> `/cms/conteudos/telefones-uteis`, ícone `phone` |
| Breadcrumb | `v6/routes/breadcrumbs.php:235-238` | `Breadcrumbs::register('telefones-uteis', function ($breadcrumbs) { $breadcrumbs->parent('home'); $breadcrumbs->push('Telefones Úteis'); });` |

Trecho real do menu (`v6/app/Providers/MenuServiceProvider.php`):

```php
case 'telefones-uteis':
    $event->menu->add(['text' => 'Telefones Úteis', 'url' => '/cms/conteudos/telefones-uteis', 'icon' => 'phone']);
    break;
```

## 7. Perfis de acesso (guard)

- O CMS usa `cartalyst/sentinel` com middleware `check.logged` aplicado ao grupo `/cms` em `v6/routes/basepro.php`.
- `ContentController` aplica ainda `$this->middleware('check.route.permission')` no construtor (`v6/app/Http/Controllers/Prefecture/ContentController.php:60`).
- As ações exibidas no DataTable dependem de `has_access('telefones-uteis.edit')`, `has_access('telefones-uteis.delete')`, `has_access('telefones-uteis.restore')` e `has_access('telefones-uteis.inactivate')`, calculados em `struct_views()`.
- O portal público usa apenas o middleware `check.site.manutention` do grupo em `v6/routes/web.php`.
