# Novidades — Modelagem de Dados

> Estrutura de dados do changelog. Fonte: schema real do banco
> `prefeituras_v5`.

---

## 1. `change_logs` — o changelog do produto

Criada por `v6/database/migrations/2022_04_22_094515_create_changelog_table.php`.

| Coluna | Tipo | Null | Default | Observação |
|---|---|---|---|---|
| `id` | integer | não | `nextval('change_logs_id_seq')` | PK |
| `title` | text | **não** | — | título da versão |
| `numero_versao` | varchar(20) | **não** | — | ver histórico do tipo abaixo |
| `descricao` | text | **não** | — | HTML do Summernote |
| `data_versao` | timestamp(0) | **não** | — | data de publicação |
| `icon` | text | **não** | — | classe CSS do ícone (ex.: `fas fa-code-branch`) |
| `created_at` / `updated_at` | timestamp(0) | sim | — | |
| `deleted_at` | timestamp(0) | sim | — | **nunca é usado** (o model não tem `SoftDeletes`) |

### 1.1 Histórico do tipo de `numero_versao`

| Migration | Tipo | Observação |
|---|---|---|
| `2022_04_22_094515_create_changelog_table.php` | `float` | versão como número (5.0, 6.0) |
| `2025_09_26_103213_alter_number_versao_to_string_in_change_logs_table.php` | `varchar(20)` | passou a string, para permitir "5.0.1", "6.0-beta" etc. |

> A migration de alteração usa `->change()` (doctrine/dbal) e tem o corpo
> fora do padrão de indentação (a classe e os métodos estão com 0
> indentação). Funciona, mas é inconsistente com o resto do projeto.

### 1.2 O model

`v6/app/Http/Model/Admin/ChangeLog.php`:

```php
class ChangeLog extends Model
{
    protected $fillable = [
        'title', 'numero_versao', 'data_versao', 'descricao', 'icon'
    ];

    protected $dates = [
        'data_versao'
    ];
}
```

Observações:

- **Não há `$table`** — o Eloquent infere `change_logs` a partir do
  nome da classe. Correto, mas frágil: renomear a classe quebra.
- **Não há `SoftDeletes`**, apesar de a coluna `deleted_at` existir. A
  exclusão é definitiva (o `deleted_at` fica sempre `NULL`).
- `$dates` (equivalente ao `casts` moderno) converte `data_versao` em
  Carbon. Com PHP 8 / Laravel 11, `$dates` foi **removido** — usar
  `casts` é obrigatório.
- Não há casts para `descricao` (HTML) — é gravado e impresso cru.

---

## 2. `update_logs` — a versão do sistema (conceito separado)

Criada por `v6/database/migrations/2023_03_22_095658_create_update_logs_table.php`.

| Coluna | Tipo | Null | Default | Observação |
|---|---|---|---|---|
| `id` | integer | não | seq | PK |
| `version` | text | **não** | — | ex.: `6.0.0` |
| `date` | date | **não** | — | |
| `title` | varchar(191) | sim | — | |
| `message` | text | sim | — | |
| `author_name` | varchar(191) | sim | — | |
| `commit_id` | varchar(191) | sim | — | |
| `created_at` / `updated_at` | timestamp(0) | sim | — | |

A migration inicial insere `version = '6.0.0'`, `date = '2025-03-05'`.

> O model `App\Http\Model\Prefecture\UpdateLogs` tem `'description'` no
> `$fillable`, mas a tabela **não tem** essa coluna.

### 2.1 Consumidores

| Consumidor | Uso |
|---|---|
| `v6/app/Console/Commands/UpdateVersion.php` (`update:logs`) | cria a próxima versão incrementando o **patch** da última |
| `v6/resources/views/vendor/adminlte/page.blade.php:418,421-423` | rodapé do CMS: `{{ $systemVersion->version }}` com link para `changelog.index` |
| `v6/app/Providers/FooterServiceProvider.php:102` | mesma informação no rodapé do **portal público** |

### 2.2 Relação com `change_logs`

As duas tabelas são **independentes**, mas representam o mesmo domínio
conceitual ("versão do sistema"):

- `change_logs` guarda o **detalhe** de cada versão entregue (com texto e
  imagem);
- `update_logs` guarda a **versão numérica corrente** (incrementada
  automaticamente por comando).

Nada garante que as duas estejam sincronizadas. O rodapé do CMS mostra
`update_logs.version` e linka para a listagem de `change_logs` — o
usuário pode ver "6.0.0" e não encontrar nenhuma entrada 6.0.0 no
changelog.

---

## 3. `modulos` e `resources`

| Item | Valor |
|---|---|
| `modulos` | id **10**, name "Novidades", slug `novidades`, `status = true` |
| `resources` | **NENHUMA LINHA** com slug `changelog` (ou `novidades`) |
| `menu_orders` | **NENHUMA LINHA** para `novidades` |

Sem recurso, as permissões `changelog.index`, `changelog.edit` e
`changelog.delete` (usadas na view) **não podem ser concedidas** a
nenhum perfil. Apenas `super-admin` passa, porque `has_access()`
retorna `true` para ele.

---

## 4. Views SQL

**Nenhuma.** O módulo usa Eloquent diretamente
(`ChangeLog::orderBy('id','DESC')->get()`).

---

## 5. Relacionamentos

Nenhum. `change_logs` é uma tabela isolada, sem FK de entrada ou saída.

---

## 6. Migrations e seeds

| Item | Caminho | Efeito |
|---|---|---|
| Migration | `v6/database/migrations/2022_04_22_094515_create_changelog_table.php` | cria `change_logs` |
| Migration | `v6/database/migrations/2025_09_26_103213_alter_number_versao_to_string_in_change_logs_table.php` | `numero_versao`: `float` -> `varchar(20)` |
| Migration | `v6/database/migrations/2023_03_22_095658_create_update_logs_table.php` | cria `update_logs` (conceito irmão) |
| Seed | `v6/database/seeds/ChangeLogTableSeeder.php` | popula `change_logs` com ~28 versões |

### 6.1 Conteúdo do `ChangeLogTableSeeder`

O seeder faz `DB::table('change_logs')->truncate()` e insere
aproximadamente 28 registros, com `numero_versao` `5.0` (a maioria) e
`6.0` (as últimas), `data_versao` entre `2021-10-26` e `2025-07-02`, e
descrições HTML com imagens em `/storage/img/changelog/*.png`.

Exemplos de título: "Barra de privacidade", "Agenda de eventos",
"Enquetes", "Editor de imagem", "Pré-visualização de notícias",
"Banners dinâmicos", "Menu dinâmico", "Changelog / Novidades",
"Opções de layout", "Manual do Sistema", "Servidores", "Diário oficial",
"Requerimento de diárias", "Feriados municipais", "Política de Privacidade",
"Certificado", "Pesquisa de Satisfação", "Newsletter", "Public V6",
"Reorganização dos Botões de Transparência Fiscal", "Habilitar módulo de
destaques com carrossel", "Formulários Dinâmicos", "Gerar textos com IA",
"Ajustar o Módulo de Ouvidoria...".

> O seed **trunca** a tabela: executá-lo apaga as novidades cadastradas
> manualmente.

---

## 7. Observações de modelagem para a v7

1. **`deleted_at` deve ser usado.** Ou o model ganha `SoftDeletes`, ou a
   coluna é removida. Hoje há uma coluna que nunca é preenchida.
2. **`numero_versao` deve ser único** (porData ou por `title`), para
   impedir duas entradas da mesma versão.
3. **Unificar `change_logs` e `update_logs`?** A v7 pode ter uma única
   tabela `release_notes` com `version` (string), `released_at`, `title`,
   `body`, `icon`, `is_current` (bool). O rodapé usaria
   `where('is_current', true)`.
4. **Casts explícitos**: `data_versao => datetime`, `descricao` =>
   string; e `icon` deve ser validado contra uma lista fechada de
   classes (hoje é texto livre renderizado dentro de `<i class="...">`).
5. **Índice em `data_versao`** para ordenar a timeline sem filesort.
