# Manual do Sistema — Arquitetura

> Módulo **novo na v6** (não existe na v5). Segue o padrão
> Controller -> Repository -> Model do restante do CMS, com uma camada de
> AJAX para as "áreas".

---

## 1. Fluxo da requisição

### 1.1 Manuais (CRUD)

```
Navegador
   ▼
routes/basepro.php:211  Route::resource('manual-usuario', 'Prefecture\ManualController')
   ▼
Middleware: check.route.permission   (registrado no construtor do controller)
   ▼
Prefecture\ManualController
   ├─ index()  →  $this->table->orderBy('created_at')->get(['id','titulo'])
   ├─ create() →  view 'prefecture.configurations.manual-usuario.create'
   ├─ store(ManualSistemaRequest)  →  IManualUsuarioRepository::upInsert()
   ├─ show($id) →  Manual + areas (with('areas'))
   ├─ edit($id) →  mesma view de create, com $data
   ├─ update(Request, $id)         →  IManualUsuarioRepository::upInsert($request, $id)
   └─ delete($id) →  Manual::destroy($id)
   ▼
App\Http\Model\Prefecture\Manual  →  tabela manuals
```

### 1.2 Áreas (AJAX)

```
JS (assets/js/custom/contents/manual-sistema/areas.js)
   │
   ├─ GET    /cms/manual/get/{manual_id}   → ManualAreaController@getAll
   ├─ POST   /cms/manual-area              → ManualAreaController@store
   ├─ PUT    /cms/manual-area/{id}         → ManualAreaController@update
   ├─ GET    /cms/manual-area/{id}/edit    → ManualAreaController@edit
   └─ DELETE /cms/manual-area/{id}         → ManualAreaController@destroy
   ▼
Prefecture\ManualAreaController
   ├─ index()  →  todas as áreas (JSON cru, sem view)
   ├─ store(Request)   →  IManualAreaRepository::upInsert()
   ├─ edit($id)        →  área com 'archive' (JSON cru)
   ├─ getAll($id)      →  áreas do manual (JSON cru)
   ├─ update(Request,$id) → IManualAreaRepository::upInsert($request,$id)
   └─ destroy($id)     →  ManualArea::destroy($id)
   ▼
IManualAreaRepository::upInsert
   ├─ App\Http\Model\Prefecture\ManualArea  →  tabela manual_areas
   └─ IArchiveRepository::upInsert           →  tabela archives + arquivo em disco
       └─ FileTrait::saveUpload
           → storage/app/public/manual-usuario/area/{id}/destaque/{nome}
```

---

## 2. Diagrama de classes

```
                        IManualUsuarioRepository            IManualAreaRepository
                        (Contracts)                        (Contracts)
                              │                                    │
                 ManualUsuarioRepository            ManualAreaRepository
                 (Eloquent/Prefecture/ManualUsuario)  (Eloquent/Prefecture/ManualArea)
                              │                                    │
                              ▼                                    ▼
                      App\Http\Model\                 App\Http\Model\Prefecture\
                        Prefecture\Manual                 ManualArea
                              │                            │        │
                              │ hasMany(ManualArea) ───────┘        │ hasOne(Archive)
                              ▼                                          ▼
                         manuals                                manual_areas ──── archives
```

---

## 3. Camadas e classes envolvidas

### 3.1 Controllers

| Classe | Caminho | Papel |
|---|---|---|
| `Prefecture\ManualController` | `v6/app/Http/Controllers/Prefecture/ManualController.php` | CRUD dos manuais + `delete()` avulso |
| `Prefecture\ManualAreaController` | `v6/app/Http/Controllers/Prefecture/ManualAreaController.php` | CRUD das áreas, respondendo JSON |

Ambos estendem `App\Http\Controllers\Admin\Controller` (importado
explicitamente) — e **não** `Prefecture\Controller`. Como a base do CMS não
registra middleware, ambos declaram explicitamente:

```php
$this->middleware('check.route.permission');
```

> Consequência: a autorização depende **inteiramente** do middleware, que
> (a) infere a permissão do nome da rota e (b) **libera incondicionalmente**
> as rotas cujo nome contenha `store`, `update` ou `destroy`.

### 3.2 Models

| Classe | Caminho | Papel |
|---|---|---|
| `App\Http\Model\Prefecture\Manual` | `v6/app/Http/Model/Prefecture/Manual.php` | `manuals`; `areas()` = hasMany |
| `App\Http\Model\Prefecture\ManualArea` | `v6/app/Http/Model/Prefecture/ManualArea.php` | `manual_areas`; `archive()` = hasOne |
| `App\Prefecture\Archive` | `v6/app/Http/Model/Prefecture/Archive.php` | `archives` (arquivo de destaque) |

### 3.3 Repositories

| Classe | Caminho | Papel |
|---|---|---|
| `IManualUsuarioRepository` | `v6/app/Repositories/Contracts/IManualUsuarioRepository.php` | contrato do CRUD de manuais |
| `ManualUsuarioRepository` | `v6/app/Repositories/Eloquent/Prefecture/ManualUsuario/ManualUsuarioRepository.php` | implementa o contrato sobre `App\Repositories\Repository` |
| `IManualAreaRepository` | `v6/app/Repositories/Contracts/IManualAreaRepository.php` | contrato do CRUD de áreas |
| `ManualAreaRepository` | `v6/app/Repositories/Eloquent/Prefecture/ManualArea/ManualAreaRepository.php` | CRUD + upload do arquivo de destaque |
| `Repository` (abstrata) | `v6/app/Repositories/Repository.php` | `upInsert()`, `destroy()`, `destroyAll()` |
| `AppTrait` | `v6/app/Http/Traits/AppTrait.php` | `filter_request()`, `traitRequest()`, `success()`, `error()`, `getType()` |
| `FileTrait` | `v6/app/Http/Traits/FileTrait.php` | `saveUpload()`, `getFileName()`, `compress()` |

### 3.4 Requests, helpers e assets

| Item | Caminho | Papel |
|---|---|---|
| `ManualSistemaRequest` | `v6/app/Http/Requests/ManualSistemaRequest.php` | valida `titulo` e `objetivo` (**apenas no `store`**) |
| `check.route.permission` | `v6/app/Http/Middleware/CheckRoutePermission.php` | autorização por nome de rota |
| JS de áreas | `v6/public/assets/js/custom/contents/manual-sistema/areas.js` | DataTable + CRUD AJAX das áreas |
| `myFetch` / `myXHR` | `v6/public/assets/js/custom/utilities/functions.js` | helpers de fetch/XHR usados pelo JS |

---

## 4. Dependências externas

| Pacote | Versão | Uso |
|---|---|---|
| `laravel/framework` | `5.5.*` | Eloquent, DI, Blade |
| `laravelcollective/html` | `^5.5` | `Form::` nos Blades |
| Summernote | (asset) | editor WYSIWYG da descrição da área |
| lightgallery | (asset) | zoom da imagem de destaque |
| `intervention/image` | (via `FileTrait`) | compressão/recorte da imagem enviada |

> O módulo **não** usa Yajra DataTables no servidor: a tabela de áreas é
> montada no cliente com a API do DataTables (sem AJAX).

---

## 5. Onde o módulo é consumido

| Consumidor | Dependência |
|---|---|
| Menu do AdminLTE | `route('manual-usuario.index')` (`v6/resources/views/vendor/adminlte/page.blade.php:295`) |
| Portal público | **Nenhum** — `manuals.url_portal` é gravado, mas nada no portal lê a tabela `manuals` (o "Manual de Navegação" do portal é uma **página estática**, não esta tabela) |
| Modelos do portal | `v6/resources/views/portal/**/manual-de-navegacao.blade.php` renderiza `$contents->text` de uma página estática — **conceito diferente** |

> **Atenção:** o slug `manual-de-navegacao` do portal **não** tem relação
> com a tabela `manuals`. São coisas distintas que compartilham o nome
> "manual".

---

## 6. Mapa de arquivos

```
app/Http/Controllers/Prefecture/
├── ManualController.php
└── ManualAreaController.php

app/Http/Model/Prefecture/
├── Manual.php
├── ManualArea.php
└── Archive.php

app/Http/Requests/ManualSistemaRequest.php

app/Repositories/Contracts/
├── IManualUsuarioRepository.php
└── IManualAreaRepository.php

app/Repositories/Eloquent/Prefecture/
├── ManualUsuario/ManualUsuarioRepository.php
└── ManualArea/ManualAreaRepository.php

app/Repositories/Repository.php
app/Http/Traits/AppTrait.php
app/Http/Traits/FileTrait.php

resources/views/prefecture/configurations/manual-usuario/
├── index.blade.php
├── create.blade.php
├── form.blade.php
├── show.blade.php
└── area/
    ├── index.blade.php
    └── modal.blade.php

public/assets/js/custom/contents/manual-sistema/areas.js
public/assets/js/custom/utilities/functions.js

database/migrations/2023_01_20_162623_create_manuals_table.php
database/migrations/2023_01_20_163012_create_manual_areas_table.php
database/migrations/2023_02_01_083626_add_itens_to_archives.php
database/seeds/UpdateManualAreas.php
database/seeds/UpdateManualAreasDiarioSeeder.php
database/seeds/ManuaisSinergiaSeeder.php
database/seeds/ManualDoSistemaResourceSeeder.php
```
