# TV Câmara — Arquitetura

> **Escopo:** módulo `tv-camara` (tabela `modulos` id 45) na versão `v6`.
> **Módulo novo na v6** — não há equivalente na `v5`.

---

## 1. Visão geral

O módulo é um CRUD simples com duas portas de entrada:

- **Portal público** (`v6/routes/web.php`): leitura de uma lista paginada e de
  uma página de detalhes.
- **CMS** (`v6/routes/basepro.php`, prefixo `/cms`): CRUD completo, listagem em
  DataTable server-side sobre uma **view SQL**, upload de imagem de destaque e
  ações em lote.

Não há Service, Repository ou Policy. A lógica está concentrada nos dois
controllers e no model `TvCamara`.

## 2. Fluxo da requisição

### 2.1 Portal (leitura)

```
GET /tv-camara  e  GET /tv-camara/{slug}
        │
        ▼
Route::middleware(['check.site.manutention'])      v6/routes/web.php:8
        │
        ▼
Portal\TvCamaraController@index | @show           v6/app/Http/Controllers/Portal/TvCamaraController.php
        │  index(): TvCamara::where(status,true)->whereNull(deleted_at)
        │           ->where(publication_date,'<=',now())->orderBy(...)->paginate(12)
        │  show():  TvCamara::where('slug',$slug)->firstOrFail()
        │           $linkVideo = embedVideo($content->link)
        ▼
view("portal.layouts.{$template}.tv-camara.index" | ".show")
        │   $template = getTemplateActived()  (Configuration key 'layout')
        ▼
Blade (Bootstrap 4) + partial portal.statics.video  (iframe com $linkVideo)
```

### 2.2 CMS (escrita)

```
POST /cms/tv-camara/store
        │
        ▼
Prefecture\TvCamaraController::__construct()  →  middleware('check.route.permission')
        │   v6/app/Http/Controllers/Prefecture/Controller.php:22-25
        ▼
TvCamaraFormRequest  (title, publication_date, link)
        │
        ▼
Prefecture\TvCamaraController@store
        │  1.TvCamara::where('status','true')->orderBy('publication_date','DESC')->get()
        │  2.regra dos 3 ativos  →  $contents[2]->status = 0
        │  3.$date = date('Y-m-d H:i', strtotime(str_replace('/','-',$request->publication_date)))
        │  4.slug = str_slug($request->title)
        │  5.TvCamara::create($data)
        │  6.Archive::create([... 'tv_camara_id' => $content->id, 'highlight' => 1])
        │  7.$request->file('archive_highlight')->storeAs("tv-camara/{id}/destaque", $name)
        ▼
redirect → route('tv-camara.index')  +  flash('Cadastrado com sucesso.')
```

### 2.3 CMS (listagem / DataTable)

```
GET /cms/datatable/tv-camara        (nome: datatable.tv-camara)
        ▼
Prefecture\DatatableController@get_tv_camara()
        │  DB::table("tv_camara")->get()          ← view SQL
        │  struct_views($data,'tv_camara')        → flags edit/delete/active/inactivate
        ▼
Yajra DataTables (JSON)  →  v6/public/assets/js/custom/contents/tv-camara/datatable.js
```

## 3. Classes envolvidas

| Classe / arquivo | Namespace | Papel |
|---|---|---|
| `v6/app/Http/Controllers/Portal/TvCamaraController.php` | `App\Http\Controllers\Portal` | Listagem pública e página de detalhes; calcula `embedVideo()`. |
| `v6/app/Http/Controllers/Prefecture/TvCamaraController.php` | `App\Http\Controllers\Prefecture` | CRUD do CMS, upload, `setStatus`, `destroy`, `deleteByLote`. |
| `v6/app/Http/Controllers/Prefecture/DatatableController.php` | `App\Http\Controllers\Prefecture` | `get_tv_camara()` (linha 469) e `struct_views()` (linha 504). |
| `v6/app/Http/Requests/TvCamaraFormRequest.php` | `App\Http\Requests` | Valida `title`, `publication_date`, `link` no `store`/`update`. |
| `v6/app/Http/Model/Prefecture/TvCamara.php` | `App\Prefecture` | Model Eloquent da tabela `tv_camaras` (SoftDeletes + PresentableTrait). |
| `v6/app/Http/Model/Prefecture/Archive.php` | `App\Prefecture` | Arquivos (imagem de destaque) ligados por `tv_camara_id`. |
| `v6/app/Http/Presenters/ContentPresenter.php` | `App\Http\Presenters` | Formatação de data e miniatura (`getArchiveContentHighlightOrThumbnail`). |
| `v6/app/Http/Middleware/CheckRoutePermission.php` | `App\Http\Middleware` | Autorização por rota/permissão no CMS. |
| `v6/app/Providers/ModulosServiceProvider.php` | `App\Providers` | Injeta `$modulos` (status por slug) nas views da home. |
| `v6/app/Providers/MenuServiceProvider.php` | `App\Providers` | Item de menu do CMS "TV Câmara" (linha 291). |
| `v6/app/Helpers/functions.php` | global | `embedVideo()` (linha 607), `getMinFile()` (linha 977). |
| `v6/app/Library/Helper/appHelpers.php` | global | `has_access()` (linha 22). |

## 4. Modelos de dados envolvidos

| Objeto | Papel no módulo |
|---|---|
| `tv_camaras` | Fonte da verdade: título, texto, slug, status, link, data de publicação. |
| `archives` | Imagem de destaque (`tv_camara_id`, `highlight = 1`, `path` em `storage/tv-camara/...`). |
| `tv_camara` (view SQL) | Projeção usada pelo DataTable do CMS (`value`, `titulo`, `id`, `data_publicacao`, `status_name`, `status`). |
| `modulos` | Chave do módulo (id 45, `status = 0` no seed → home oculta). |
| `resources` | Recurso `tv-camara` (id 64) → base das permissões `tv-camara.*`. |
| `menu_orders` | Item de menu do CMS (id 39, `modulo_id = 45`, `clicks`). |

## 5. Diagrama de fluxo (ASCII)

```
                      ┌──────────────────────────────────────────┐
  CIDADÃO ──GET──────►│ routes/web.php  (check.site.manutention) │
                      └───────────────────┬──────────────────────┘
                                          │
                        ┌─────────────────▼─────────────────────┐
                        │ Portal\TvCamaraController             │
                        │  index()  → paginate(12)              │
                        │  show()   → embedVideo(link)          │
                        └─────────────────┬─────────────────────┘
                                          │
              ┌───────────────────────────▼────────────────────────────┐
              │ portal/layouts/{modelo1..6}/tv-camara/{index,show}     │
              │      + portal/statics/video.blade.php  (iframe)        │
              └────────────────────────────────────────────────────────┘

                      ┌──────────────────────────────────────────┐
  OPERADOR ──GET/POST►│ routes/basepro.php  (prefix /cms)       │
                      └───────────────────┬──────────────────────┘
                                          │
              ┌───────────────────────────▼────────────────────────────┐
              │ middleware check.route.permission (no construtor)      │
              │  ├─ TvCamaraFormRequest  (store/update)                │
              │  └─ Prefecture\TvCamaraController                      │
              │        store | update | setStatus | destroy |         │
              │        deleteByLote                                   │
              └───────────────────────────┬────────────────────────────┘
                                          │
        ┌─────────────────────────────────┼──────────────────────────────┐
        ▼                                 ▼                              ▼
  TvCamara (model)              archives (imagem)              tv_camara (view SQL)
  tabela tv_camaras              archives.tv_camara_id         usada pelo DataTable
```

## 6. Dependências externas

| Pacote | Versão (em `v6/composer.json`) | Uso no módulo |
|---|---|---|
| `laravel/framework` | `5.5.*` | Eloquent, rotas, Blade, `Storage`, `FormRequest`. |
| `yajra/laravel-datatables` | `^1.5` | `DataTables::of(...)->make(true)` em `get_tv_camara()`. |
| `laracasts/presenter` | `^0.2.2` | `PresentableTrait` no model e `ContentPresenter`. |
| `cartalyst/sentinel` | `2.0.*` | `Sentinel::check()`, `hasAnyAccess`, papéis (`super-admin`). |
| `illuminate/support` | (via framework) | `str_slug()`, `str_random()`, `str_limit()`. |
| `laravel/framework` (helpers) | — | `str_slug` em `v6/vendor/laravel/framework/src/Illuminate/Support/helpers.php:991`. |

## 7. Onde o módulo se acopla a outros módulos

| Acoplamento | Onde | Natureza |
|---|---|---|
| `archives` (galeria genérica) | `TvCamara::archives()` e `archives.tv_camara_id` | Reaproveita a tabela de arquivos do módulo de conteúdos. |
| `Configuration` (chave `layout`) | `getTemplateActived()` | Define qual pasta `modelo1..modelo6` renderiza as views. |
| `modulos` / `resources` | `ModulosServiceProvider`, `MenuServiceProvider` | Controla a exibição do bloco da home e o item de menu. |
| Home do portal | `PortalController@index` | Alimenta `$tvCamaras` (3 itens). |
| Módulo `sessoes` | conceitual | A TV Câmara é o canal de vídeo das sessões; não há FK entre as tabelas. |
| `prefecture.components.*` | blades do CMS | Componentes de exclusão em lote compartilhados com os demais módulos. |
