# Licitações Antigas — Rotas e Controllers

---

## 1. Rotas do Portal (público)

Arquivo: `v6/routes/web.php`. Todas as rotas abaixo estão dentro do grupo
`Route::middleware(['check.site.manutention'])->group(...)` (linha 7) e recebem
o grupo `web` (sessão, cookies, CSRF) aplicado em
`v6/app/Providers/RouteServiceProvider.php:57-61`.

| Método | URI | Nome (`->name()`) | Controller@action | Middleware |
|---|---|---|---|---|
| `ANY` | `licitacoes-ate-2018` | `licitacoes.old.index` | `Portal\BiddingOldController@index` | `web` + `check.site.manutention` |
| `ANY` | `licitacoes-ate-2018/{id}` | `licitacoes.old.show` | `Portal\BiddingOldController@show` | `web` + `check.site.manutention` |

Definição literal (`v6/routes/web.php:178-180`):

```php
    //Licitacoes antigas
    Route::any('licitacoes-ate-2018', 'Portal\BiddingOldController@index')->name('licitacoes.old.index');
    Route::any('licitacoes-ate-2018/{id}', 'Portal\BiddingOldController@show')->name('licitacoes.old.show');
```

Observações:
- `Route::any` aceita GET e POST; o formulário de filtros usa `Form::open`
  com `url => ['licitacoes-ate-2018']` e método POST implícito, mas o
  controller lê os parâmetros via `$request->tipo_modalidade` etc., que
  funciona igual para query string e corpo.
- Não há restrição de parâmetro em `{id}`: o controller tipa `show(int $id)`,
  então valores não numéricos produzem erro de coerção de tipo (HTTP 500) em
  vez de 404.
- Não há rota de API correspondente (`v6/routes/api.php` não menciona
  licitações).
- Não há rota de exportação (o módulo novo tem `exportacao` via
  `Portal\BiddingsController@index`; o legado **não**).

## 2. Rotas do CMS (`/cms/...`)

**O CMS não expõe nenhuma rota própria deste módulo.** Verificação: nenhuma
ocorrência de `licitacoes-ate-2018`, `BiddingOldController` ou `licitacao-antiga`
em `v6/routes/basepro.php`, `v6/routes/api.php`, `v6/routes/prefecture.php`,
`v6/routes/service_letter.php` ou `v6/routes/breadcrumbs.php`.

O que existe no CMS, indiretamente:

| Caminho | Relação com o módulo |
|---|---|
| `v6/routes/basepro.php:35` (`Route::group(['prefix' => 'cms', 'before' => 'csrf'], ...)`) | Grupo do CMS; nenhuma sub-rota de licitações legadas. |
| `v6/routes/basepro.php:184` (`Route::resource('licitacao', 'Prefecture\Bidding\BiddingController')`) | Recurso de **licitações novas** (`biddings`), não do acervo legado. |
| `v6/app/Http/Controllers/Admin/ModulosController.php` (`index`, `update`) | Único ponto do CMS que mexe no módulo: habilita/desabilita `modulos.id = 20`. |

## 3. Controller — ações

Arquivo: `v6/app/Http/Controllers/Portal/BiddingOldController.php`

| Ação | Assinatura | O que faz |
|---|---|---|
| `__construct` | `__construct(BiddingsLegacys $biddingsLegacys)` | Injeta o model (injeção de dependência do container). |
| `index` | `index(Request $request): View` | Monta a query com filtros, pagina 10/página e renderiza `...licitacao-antiga.index`. |
| `show` | `show(int $id): View` | Busca por `find($id)`; se vazio devolve `admin.errors.conteudo-nao-encontrado`; senão renderiza `...licitacao-antiga.show`. |

### 3.1 Filtros implementados em `index()`

```php
$biddings = $this->biddingsLegacys->with('archives')->orderBy('data', 'desc');

$biddings->when(($request->tipo_modalidade), function ($data) {
    return $data->where('tipo_modalidade', request('tipo_modalidade'));
});
$biddings->when(($request->ids_secretarias), function ($data) {
    return $data->where('ids_secretarias', request('ids_secretarias'));
});
$biddings->when(($request->informacoes), function ($data) {
    return $data->whereRaw("translate(lower(informacoes), ' ''àáâãäéèëêíìïîóòõöôúùüûçÇ', '--aaaaaeeeeiiiiooooouuuucc') ilike",'%'.transliterator_transliterate('Any-Latin; Latin-ASCII',request('informacoes')).'%');
});
$biddings->when(($request->ano), function ($data) {
    return $data->whereYear('data', request('ano'));
});
$biddings = $biddings->paginate(10);
```

Variáveis repassadas à view: `biddings`, `title`, `modalitiesLegacy`,
`jurisdictionalLegacy`, `years`, `links`, `tipoModalidade`, `anoSelecionado`,
`idsSecretarias`, `informacoes`.

### 3.2 Consulta de anos (SQL cru)

```php
$years = DB::select("select  extract(year from data) as ano from biddings_legacys GROUP BY ano order by ano desc;");
```

Usa `GROUP BY` sobre o alias `ano` — aceito pelo PostgreSQL, mas não
portável para outros SGBDs.

## 4. Form Requests / validação

**Nenhum.** O controller lê a query string diretamente, sem validação de
tipo, tamanho ou existência:

| Parâmetro | Validação hoje | Efeito de valor malicioso |
|---|---|---|
| `tipo_modalidade` | nenhuma | valor é repassado ao `where` (string; Postgres converte, erro em não-numérico) |
| `ids_secretarias` | nenhuma | idem |
| `ano` | nenhuma | `whereYear` com string; valor inválido gera erro de SQL |
| `informacoes` | nenhuma | concatenado no `ilike` **após** transliteração; o `%` do usuário é aceito como curinga (comportamento de busca esperado) |

## 5. API Resources / Presenters

**Nenhum.** O módulo não expõe JSON. O `Portal\BiddingsController` (módulo
novo) responde JSON quando `request()->ajax()`; o legado não tem esse
caminho — nem retorno JSON nem `JsonResponse`.

## 6. Permissões e guards

- **Portal**: rota pública, sem guard, sem `check.logged`. O único controle é
  `check.site.manutention` (modo manutenção do portal).
- **CMS**: inexistente para este módulo. A tela de módulos usa
  `check.logged` e o middleware `check.route.permission`
  (ver `v6/routes/basepro.php:35-41` e `v6/app/Http/Controllers/Admin/ModulosController.php`).
- A tabela `modulos` (`id = 20`, `slug = 'licitacoes-antigas'`, `status = true`)
  é lida por `v6/app/Providers/ModulosServiceProvider.php:22-24` e injetada
  nas views do portal como `$modulos['licitacoes-antigas']`. O status **não**
  é consultado pelo controller legado: desligar o módulo não remove a rota
  nem o link.

## 7. Breadcrumbs

`v6/routes/breadcrumbs.php` não define breadcrumb específico do módulo
legado. As views reutilizam:
- `licitacoes` (`v6/routes/breadcrumbs.php:139-142`) — "Home > Licitações";
- `licitacao` (linhas 144-148) — recebe o **número** da licitação como string.

Detalhe: a view de detalhe passa `$bidding->number`
(`v6/resources/views/portal/layouts/modelo1/licitacao/licitacao-antiga/show.blade.php`),
mas o model legado **não tem** atributo `number` (é `numero`), portanto o
breadcrumb do detalhe fica vazio.
