# Licitações Antigas — Arquitetura

> Módulo **somente leitura** do portal público. Sem repository, sem service,
> sem Form Request, sem Policy, sem API Resource.

---

## 1. Fluxo da requisição

### 1.1 Listagem

```
HTTP GET|POST /licitacoes-ate-2018?tipo_modalidade=&ids_secretarias=&ano=&informacoes=
  │
  ├─ middleware group "web"           (v6/app/Providers/RouteServiceProvider.php:57-61)
  │    └─ session, cookies, CSRF (web.php é POST-able)
  ├─ middleware group "check.site.manutention"   (v6/routes/web.php:7)
  ├─ Route::any('licitacoes-ate-2018', 'Portal\BiddingOldController@index')
  │      name = licitacoes.old.index               (v6/routes/web.php:179)
  │
  └─ App\Http\Controllers\Portal\BiddingOldController@index
        ├─ $this->biddingsLegacys  (injetado no construtor)
        ├─ ->with('archives')->orderBy('data','desc')
        ├─ ModalitiesBiddingsLegacys::pluck('name','id')      → biddings_legacys_modalities
        ├─ JurisdictionalBiddingsLegacys::pluck('title','id') → biddings_legacys_jurisdictional
        ├─ DB::select("select extract(year from data) as ano from biddings_legacys
        │              GROUP BY ano order by ano desc;")
        ├─ filtros via ->when(): where / whereRaw / whereYear
        ├─ ->paginate(10)
        └─ view('portal.layouts.'.$this->getTemplateActived().'.licitacao.licitacao-antiga.index')
```

### 1.2 Detalhe

```
HTTP GET /licitacoes-ate-2018/{id}
  ├─ Route::any('licitacoes-ate-2018/{id}', 'Portal\BiddingOldController@show')
  │      name = licitacoes.old.show                (v6/routes/web.php:180)
  └─ BiddingOldController@show(int $id)
        ├─ $this->biddingsLegacys->find($id)
        ├─ se vazio → view('admin.errors.conteudo-nao-encontrado')
        └─ view('portal.layouts.'.$template.'.licitacao.licitacao-antiga.show')
             └─ @foreach($bidding->archives ...) → /storage/licitacoes_old/{id}/{name}
```

## 2. Diagrama (Mermaid)

```mermaid
flowchart TD
    U[Cidadão] --> R["web.php:179-180<br/>Route::any licitacoes-ate-2018"]
    R --> M["middleware: web + check.site.manutention"]
    M --> C["Portal\BiddingOldController<br/>(extends Admin\Controller)"]
    C --> T["getTemplateActived()<br/>configurations.layout"]
    C --> E["Eloquent: BiddingsLegacys<br/>+ archives() hasMany"]
    C --> MOD["ModalitiesBiddingsLegacys<br/>JurisdictionalBiddingsLegacys"]
    C --> RAW["DB::select anos"]
    E --> DB[(biddings_legacys)]
    MOD --> DB2[(biddings_legacys_modalities<br/>biddings_legacys_jurisdictional)]
    RAW --> DB
    C --> V["view portal.layouts.{layout}.licitacao.<br/>licitacao-antiga.{index,show}"]
    V --> S[("/storage/licitacoes_old/...")]
```

## 3. Classes envolvidas

| Classe | Caminho | Papel |
|---|---|---|
| `App\Http\Controllers\Portal\BiddingOldController` | `v6/app/Http/Controllers/Portal/BiddingOldController.php` | Controller do portal; `index()` e `show()`. |
| `App\Http\Controllers\Admin\Controller` | `v6/app/Http/Controllers/Admin/Controller.php` | Classe-pai (herança cruzada); fornece `getTemplateActived()` (linhas 39-49). |
| `App\Http\Model\Prefecture\BiddingsLegacys` | `v6/app/Http/Model/Prefecture/BiddingsLegacys.php` | Model principal; tabela `biddings_legacys`; relação `archives()`. |
| `App\Http\Model\Prefecture\ArchivesBiddingsLegacys` | `v6/app/Http/Model/Prefecture/ArchivesBiddingsLegacys.php` | Model dos anexos; tabela `archives_biddings_legacy`. |
| `App\Http\Model\Prefecture\ModalitiesBiddingsLegacys` | `v6/app/Http/Model/Prefecture/ModalitiesBiddingsLegacys.php` | Catálogo de modalidades; tabela `biddings_legacys_modalities`. |
| `App\Http\Model\Prefecture\JurisdictionalBiddingsLegacys` | `v6/app/Http/Model/Prefecture/JurisdictionalBiddingsLegacys.php` | Catálogo de secretarias; tabela `biddings_legacys_jurisdictional`. |
| `App\Http\Controllers\Admin\ModulosController` | `v6/app/Http/Controllers/Admin/ModulosController.php` | Única tela do CMS que toca o módulo (toggle de status na tabela `modulos`). |
| `App\Providers\ModulosServiceProvider` | `v6/app/Providers/ModulosServiceProvider.php` | Publica `modulos` (slug->status) em cache `rememberForever` para as views do portal. |
| `App\Http\Model\Admin\Modulos` | `v6/app/Http/Model/Admin/Modulos.php` | Model da tabela `modulos`. |

**Não existem** no módulo: repository (`v6/app/Repositories/Eloquent/Prefecture/` não
tem pasta de legadas), Form Request, Presenter, Policy, Export, seed ou migration
além das duas de criação das tabelas.

## 4. Dependências externas

| Pacote / recurso | Uso | Origem |
|---|---|---|
| `laravel/framework` 5.5 | Eloquent, `paginate()`, `when()`, `DB::select` | `v6/composer.json` |
| `laravelcollective/html` | `Form::open()`, `Form::select()` nos filtros | `v6/composer.json` |
| `ext-intl` | `transliterator_transliterate('Any-Latin; Latin-ASCII', ...)` | `v6/app/Helpers/functions.php` (uso no controller) |
| `doctrine/dbal` (indireto) | `whereYear` gerado pelo Eloquent | dependência do framework 5.5 |
| Bootstrap 4 / AdminLTE | renderização das views do portal | `v6/resources/views/portal/**` |

## 5. Onde o módulo encosta em outros módulos

| Módulo relacionado | Ponto de contato |
|---|---|
| `licitacoes` (`modulos.id = 21`) | Botões de navegação cruzada entre `/licitacoes` e `/licitacoes-ate-2018`; o módulo novo lê a chave de configuração `licitacoes_old` (`v6/app/Http/Controllers/Portal/BiddingsController.php:73`). |
| `modulos` (cadastro de módulos) | `modulos.id = 20` habilita/desabilita o slug; sem `menu_orders` vinculado (consulta: 0 linhas com `modulo_id = 20`). |
| Configurações | `configurations.key = 'layout'` define qual template do portal renderiza as views. |

## 6. Ausência de camada de CMS

Não há `Prefecture\...Controller` para licitações legadas, nem rota em
`v6/routes/basepro.php`, nem view em `v6/resources/views/prefecture/**`
referente a legadas. Consequência: **não existe CRUD, não existe upload de
arquivo pelo CMS, não existe exportação**. A carga do acervo é feita por
scripts externos/direto no banco (ver `08-GAPS-E-DIVIDAS.md`).
