# e-Vacina — Arquitetura

> Módulo de contador de vacinação. Tem **duas metades**: a edição da
> configuração (CMS) e a importação da planilha (comando artisan).

---

## 1. Fluxo de leitura

```
Navegador
   ▼
GET /cms/e-vacina        (rota 'e-vacina.index', SEM middleware)
   ▼
Prefecture\EvacinaController@index
   │  $data = $this->evacina_repo->getModel()->latest()->first();
   ▼
view 'prefecture.configurations.evacina.edit'  (com $data)
   │  @include('prefecture.configurations.evacina.form')
   ▼
form.blade.php  →  <form action="url('cms/e-vacina/1')" method="POST">
                     @isset($data) {{ method_field('PUT') }} @endisset
```

## 2. Fluxo de escrita

```
Navegador
   ▼
POST /cms/e-vacina            (store)   |   PUT /cms/e-vacina/{e_vacina}  (update)
   ▼
Prefecture\EvacinaController
   ├─ $request->merge(["status" => isset($request->status_evacina)])
   ├─ $this->evacina_repo->upInsert($request)          → EvacinaRepository
   └─ Artisan::call('reload:evacina')                   → comando
   ▼
EvacinaRepository (extends App\Repositories\Repository)
   ├─ structureUpInsert(): url, populacao, status
   ├─ upInsert(): parent::upInsert() + imagem
   │     $request->imagem_evacina->storeAs("evacina/images/{id}", 'banner.png')
   └─ parent::upInsert() → DB::transaction + updateOrCreate
   ▼
App\Http\Model\Prefecture\Evacina  →  tabela evacinas
```

## 3. Fluxo da importação (comando)

```
scheduler (mensal) — v6/app/Console/Kernel.php:26-28
   ▼
php artisan reload:evacina
   ▼
App\Console\Commands\ReloadEvacina@handle()
   ├─ $last_evacina = Evacina::latest()->first()
   ├─ extrai sheet_id e gid da URL:
   │     explode("spreadsheets/d/", $url)  →  explode("/", ...)  →  explode("gid=", ...)
   ├─ $csv = file_get_contents("https://docs.google.com/spreadsheets/d/{sheet}/export?format=csv&gid={gid}")
   ├─ Storage::put('evacina/evacina.csv', $csv)
   ├─ lê o CSV de storage_path('app/public/evacina/evacina.csv') e conta a COLUNA 28:
   │     'Dose'          → primeira_dose
   │     '1ª Dose'       → primeira_dose
   │     'Dose Adicional'→ primeira_dose_reforco
   │     '2ª Dose'       → segunda_dose
   │     'Reforço'       → primeira_dose_reforco
   │     '2ª Reforço'    → segunda_dose_reforco
   └─ se $last_evacina->status:
         Evacina::where('id', $last_evacina->id)->update([...4 contadores...])
   ▼
catch (\Throwable $th) { /* Ignorando Erro */ }
```

## 4. Diagrama de classes

```
                  IEvacinaRepository                App\Console\Commands\
                  (Contracts)                      ReloadEvacina
                        │                                 │
      EvacinaRepository  │                                 │ Evacina::latest()
      (Eloquent/Prefecture/Evacina) ──────┐                │
                        │                 │                │
                        ▼                 ▼                ▼
              App\Http\Model\Prefecture\Evacina  (tabela evacinas)
```

---

## 5. Classes envolvidas

| Classe | Caminho | Papel |
|---|---|---|
| `Prefecture\EvacinaController` | `v6/app/Http/Controllers/Prefecture/EvacinaController.php` | `index()`, `store()`, `update()` |
| `IEvacinaRepository` | `v6/app/Repositories/Contracts/IEvacinaRepository.php` | contrato do CRUD |
| `EvacinaRepository` | `v6/app/Repositories/Eloquent/Prefecture/Evacina/EvacinaRepository.php` | implementação (upload do banner) |
| `App\Http\Model\Prefecture\Evacina` | `v6/app/Http/Model/Prefecture/Evacina.php` | model da tabela `evacinas` |
| `App\Http\Requests\EvacinaRequest` | `v6/app/Http/Requests/EvacinaRequest.php` | validação |
| `ReloadEvacina` | `v6/app/Console/Commands/ReloadEvacina.php` | comando `reload:evacina` (importação) |
| `App\Console\Kernel` | `v6/app/Console/Kernel.php` | agenda o comando mensalmente |
| `App\Http\Model\Admin\Modulos` | `v6/app/Http/Model/Admin/Modulos.php` | registro do módulo (id 5) |
| `App\Http\Model\Admin\Resource` | `v6/app/Http/Model/Admin/Resource.php` | recurso `e-vacina` (id 46) |

---

## 6. Dependências externas

| Dependência | Tipo | Uso |
|---|---|---|
| **Google Sheets** (CSV público) | externa | fonte dos dados de vacinação |
| `laravel/framework` | `5.5.*` | Eloquent, Storage, Artisan, schedulers |
| `nesbot/carbon` | (via Laravel) | ordenação `latest()` |
| `laravelcollective/html` | `^5.5` | `Form::` nos Blades |
| `intervention/image` | (via `FileTrait`) | compressão do banner (herdada do `Repository`) |

> A dependência externa mais relevante é o **Google Sheets**: a planilha
> precisa ser acessível **sem autenticação** (a URL de export é pública).

---

## 7. Onde o módulo é consumido

| Consumidor | Dependência | Onde |
|---|---|---|
| Menu do AdminLTE | `route('e-vacina.index')` + `$modulos['e-vacina']` | `v6/resources/views/vendor/adminlte/page.blade.php:263-270` |
| Portal público | **nenhum consumidor identificado** no CMS | — |
| `app/Console/Kernel.php` | `reload:evacina` mensal | `v6/app/Console/Kernel.php:26-28` |

> O portal público **não** exibe os dados de e-Vacina na v6 — não há
> view, rota nem serviço do portal que consuma `evacinas`. O módulo
> escreve em uma tabela que ninguém lê no portal.

---

## 8. Mapa de arquivos

```
app/Http/Controllers/Prefecture/EvacinaController.php
app/Http/Model/Prefecture/Evacina.php
app/Http/Requests/EvacinaRequest.php
app/Repositories/Contracts/IEvacinaRepository.php
app/Repositories/Eloquent/Prefecture/Evacina/EvacinaRepository.php
app/Console/Commands/ReloadEvacina.php
app/Console/Kernel.php

resources/views/prefecture/configurations/evacina/
├── edit.blade.php
└── form.blade.php

resources/views/prefecture/contents/components/banner-modal/index.blade.php
public/assets/js/custom/utilities/helpers/banner-image.js

database/migrations/2022_09_06_091951_create_evacinas_table.php
routes/basepro.php:201
```
