# Destaques — Modelagem de Dados

## 1. Tabela `highlights`

Criada por `v6/database/migrations/2025_03_31_210313_create_highlights_table.php`
(classe `CreateHighlightsTable`). Dump real do banco `prefeituras_v5`:

| Coluna | Tipo | Null | Default | Observação |
|---|---|---|---|---|
| `id` | `integer` (serial) | não | `nextval('highlights_id_seq')` | PK |
| `title` | `character varying(255)` | não | — | Título do destaque |
| `subtitle` | `text` | não | — | Subtítulo exibido sobre a imagem |
| `text_button` | `character varying(255)` | não | — | Rótulo do botão CTA |
| `url` | `character varying(255)` | não | — | Destino do clique |
| `position` | `integer` | não | — | Ordem de exibição (1-based) |
| `status` | `boolean` | sim | — | `true` = publicado; `null` = despublicado |
| `status_button` | `boolean` | sim | — | Exibe ou oculta o botão |
| `layout` | `character varying(255)` | sim | — | `"1"` = largura da página; `"2"` = centralizado |
| `is_blank` | `boolean` | sim | — | Abre em nova aba (não usado no Blade do portal) |
| `created_at` | `timestamp` | sim | — | Eloquent `timestamps` |
| `updated_at` | `timestamp` | sim | — | Eloquent `timestamps` |

> Observação: `layout` é `varchar(255)` no banco, mas o controller compara com inteiro
> (`$content->layout == 1`) e o provider usa `where('layout', 1)` — a comparação funciona
> por coerção do PostgreSQL (cast implícito de `varchar` para `int` **não** ocorre em
> `=`). **[NÃO VERIFICADO em runtime]** o resultado real dessa comparação; o seed da
> base de produção tem `layout` numérico.

Migration real:

```php
Schema::create('highlights', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title');
    $table->text('subtitle');
    $table->string('text_button');
    $table->string('url');
    $table->integer('position');
    $table->boolean('status')->nullable();
    $table->boolean('status_button')->nullable();
    $table->string('layout')->nullable();
    $table->boolean('is_blank')->nullable();
    $table->timestamps();
});

Schema::table('archives', function (Blueprint $table) {
    $table->integer('highlight_id')->unsigned()->nullable();
    $table->foreign('highlight_id')->references('id')->on('highlights')->onDelete('cascade');
});
```

## 2. Coluna `archives.highlight_id`

| Aspecto | Valor |
|---|---|
| Tipo | `integer` unsigned, nullable |
| FK | `highlights(id)` |
| `ON DELETE` | `CASCADE` — apagar o destaque apaga o registro do arquivo |
| Índice | criado automaticamente pelo `foreign()` |

## 3. Relacionamentos

| Relação | Tipo | Implementação |
|---|---|---|
| `Highlight::archive()` | `hasOne` | `v6/app/Http/Model/Prefecture/Highlight.php` — `hasOne(Archive::class, 'highlight_id', 'id')` |
| `Archive::content()` | `belongsTo` | `v6/app/Http/Model/Prefecture/Archive.php:47` |
| `Archive::scopeByHighLight()` | scope | `v6/app/Http/Model/Prefecture/Archive.php:104` — `where('highlight', $status)` |

> A tabela `archives` é compartilhada por todo o portal (conteúdos, páginas estáticas,
> licitações, agendas, destaques). A coluna `archives.highlight` (booleana) marca a
> **imagem principal de um conteúdo** e é independente de `highlight_id`.

## 4. Modelo Eloquent

```php
// v6/app/Http/Model/Prefecture/Highlight.php
class Highlight extends Model
{
    protected $fillable = [
        'title', 'subtitle', 'text_button', 'url', 'status',
        'is_blank', 'position', 'layout', 'status_button'
    ];

    public function archive()
    {
        return $this->hasOne(Archive::class, 'highlight_id', 'id');
    }
}
```

Pontos frágeis do model:

- **Sem `protected $table`** — o Laravel deduz `highlights` (plural snake_case). Correto.
- **Sem `$casts`** — `status`, `status_button` e `is_blank` chegam como `1`/`null` do
  PostgreSQL; `layout` chega como string.
- **Sem `SoftDeletes`** — destaques são removidos de forma definitiva (`destroy`).
- **Sem `PresentableTrait`** — não há presenter para destaques.

## 5. Views SQL

O módulo possui **uma view SQL própria**: `highlight`, criada por
`v6/database/migrations/2025_03_31_212620_create_view_highligh_table.php` sobre a
tabela `highlights`.

```sql
-- v6/database/migrations/2025_03_31_212620_create_view_highligh_table.php
CREATE OR REPLACE VIEW highlight
AS
SELECT
    row_number() OVER (ORDER BY h.status desc) as value,
    h.title AS titulo,
    h.subtitle AS subtitulo,
    h.status AS status,
    h.position AS posicao,
    h.id
FROM highlights h
ORDER BY h.created_at DESC;
```

| Coluna da view | Origem | Tipo |
|---|---|---|
| `value` | `row_number()` sobre `status DESC` | bigint |
| `titulo` | `highlights.title` | varchar(191) |
| `subtitulo` | `highlights.subtitle` | text |
| `status` | `highlights.status` | boolean |
| `posicao` | `highlights.position` | integer |
| `id` | `highlights.id` | integer |

O grid do CMS consome essa view:

```php
// v6/app/Http/Controllers/Prefecture/DatatableController.php:56-60
public function get_highlight()
{
    $destaques = DB::table('highlight')->get();
    return DataTables::of($this->struct_views($destaques, 'destaques'))->make(true);
}
```

Observações:

- `DB::table()` contorna o model `Highlight`: não há filtro de status e as colunas
  `text_button`, `url`, `status_button`, `layout` e `is_blank` não chegam ao grid.
- A view ordena por `row_number() OVER (ORDER BY h.status DESC)` no `value`, mas o
  `ORDER BY` final é `h.created_at DESC` — a numeração exibida não segue a ordem
  visual do grid.
- A tabela `highlights` **não tem** `deleted_at`; a remoção é definitiva.

Views SQL existentes na plataforma que **não** pertencem a este módulo (para evitar
confusão): `noticias`, `banners`, `super_banners`, `glossario`, `rede_social`,
`telefones_uteis`, `paginas_estaticas`.

## 6. Registro do módulo

| Tabela | Colunas relevantes | Registro |
|---|---|---|
| `modulos` | `id`, `name`, `slug`, `status` | `id = 55`, `name = 'Destaques'`, `slug = 'detaques'` (**typo**), `status = 0` (desabilitado) |
| `menu_orders` | `id`, `slug`, `modulo_id` | `id = 43`, `slug = 'destaques'`, `modulo_id = 55` |
| `resources` | `id`, `slug`, `name`, `modulo_id` | `id = 75`, `slug = 'destaques'`, `name = 'Destaques'`, `modulo_id = 55` |

Seed da tabela `modulos` (`v6/database/migrations/2024_11_01_150206_create_modulos_table.php:354-357`):

```php
// ID 55
DB::table('modulos')->insert([
    'name' => 'Destaques',
    'slug' => 'detaques',
    'status' => 0,
]);
```

> Os comentários `// ID N` do seed são **anteriores** ao `insert` que descrevem; o
> registro "Destaques" é de fato o `id = 55`, igual ao banco.

## 7. Arquivos físicos

| Caminho | Conteúdo |
|---|---|
| `storage/highlights/<id>/<nome>` | Imagem do destaque, gravada com `storeAs("highlights/{$id}", $name)` |
| `archives.path` | Valor gravado: `storage/highlights/<id>/<nome>` (sem barra inicial) |

O portal consome o caminho com `getLargFile($highlight->archive->path ?? null)`
(`v6/resources/views/portal/layouts/modelo1/home/destaque.blade.php`), que procura
variantes `_larg`, `_med` e `_min` do mesmo arquivo antes de devolver o original.

## 8. Estado atual dos dados

Consulta na base `prefeituras_v5` (somente leitura):

```sql
select count(*) from highlights;                -- 0
select count(*) from archives where highlight_id is not null;  -- 0
```

O módulo está instalado e migrado, porém **sem nenhum destaque cadastrado** e com o
módulo desabilitado no menu.

## 9. Seeds

Não há seed que popule `highlights`. Existe, porém, uma factory **vazia** —
`v6/database/factories/HighlightFactory.php` (idêntica à
`v5/database/factories/HighlightFactory.php`):

```php
$factory->define(\App\Http\Model\Prefecture\Highlight::class, function (Faker $faker) {
    return [
        //
    ];
});
```

Ou seja, ela **não** gera atributos: os testes precisam instanciar o model à mão.

## 10. Migrations relacionadas (nenhuma é do módulo, mas afetam o ambiente)

| Migration | Efeito |
|---|---|
| `v6/database/migrations/2018_04_02_181807_create_archives_table.php` | Cria `archives` (inclui a coluna `highlight` booleana, conceito distinto) |
| `v6/database/migrations/2018_04_02_180433_create_contents_table.php` | Cria `contents` (inclui `highlights` booleano, conceito distinto) |
| `v6/database/migrations/2025_03_31_210313_create_highlights_table.php` | Cria `highlights` e adiciona `archives.highlight_id` |
| `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` | Registra o módulo (com typo `detaques`) |
