# Perguntas Frequentes — Modelagem de Dados

> A FAQ não tem tabela própria: pergunta e resposta são campos de uma linha de `contents`.

---

## 1. Tabela `contents` — a pergunta/resposta

| Coluna | Tipo | Null | Default | Uso na FAQ |
|---|---|---|---|---|
| `id` | serial | não | — | PK; exibido na coluna ID do DataTable |
| `title` | varchar(191) | não | — | **Texto da pergunta** (ex.: "Quem está obrigado a prestar informações?") |
| `text` | text | sim | — | **Resposta** em HTML |
| `category_contents_id` | integer | não | — | 12 (categoria `perguntas-frequentes`) |
| `slug` | varchar(191) | sim | — | Gerado do título; usado como chave do `updateOrCreate` no seed |
| `status` | boolean | sim | — | Herdado do conteúdo genérico; **não** filtrado na listagem pública |
| `publication_date` | timestamp | sim | — | Não exposto no formulário da FAQ |
| `order` | integer | sim | — | Não exposto no formulário da FAQ |
| `clicks` | integer | sim | — | Contador genérico (não é incrementado nesta página) |
| `created_at`/`updated_at` | timestamp | sim | — | `deleted_at` para soft delete |

Cast relevante: `publication_date` => `datetime`
(`v6/app/Http/Model/Prefecture/Content.php:54-56`).

## 2. Tabela `category_contents` — a categoria da FAQ

| Coluna | Valor para a FAQ |
|---|---|
| `id` | 12 |
| `name` | `Perguntas Frequentes` |
| `slug` | `perguntas-frequentes` |
| `status_create` | 1 |
| `status` | true (default) |
| `category_contents_id` | NULL (categoria de topo) |

```php
// v6/database/seeds/CategoryContentTableSeeder.php:81-86
// ID 12
CategoryContent::updateOrCreate(['slug' => 'perguntas-frequentes'], [
    'name' => 'Perguntas Frequentes',
    'status_create' => 1
]);
```

## 3. View SQL `perguntas_frequentes`

`v6/database/migrations/2023_04_10_151038_create_view_to_perguntas_frequentes.php`:

```sql
CREATE OR REPLACE VIEW perguntas_frequentes AS
SELECT row_number() OVER (ORDER BY c.created_at DESC) AS value,
    c.title AS titulo,
    c.id as id

FROM contents c
    JOIN category_contents cc ON cc.id = c.category_contents_id
WHERE c.deleted_at IS NULL AND cc.slug = 'perguntas-frequentes'
ORDER BY c.created_at DESC;
```

| Coluna | Origem | Uso |
|---|---|---|
| `value` | `row_number()` sobre `created_at DESC` | Coluna ID (numeração) do DataTable |
| `titulo` | `c.title` | Coluna "Título" (a pergunta) |
| `id` | `c.id` | Link `editar/perguntas-frequentes/{id}` |

Observações:

- A view **não** expõe o `text` (a resposta): o CMS mostra apenas a pergunta na listagem.
- Não filtra `status` nem `publication_date`.
- É consumida apenas por `DatatableController@get_perguntas_frequentes`; o portal usa
  Eloquent sobre `contents`.

## 4. Relacionamentos

| Relação | Tipo | Declaração |
|---|---|---|
| `Content.categoryContents()` | `belongsTo(CategoryContent::class, 'category_contents_id', 'id')` | `v6/app/Http/Model/Prefecture/Content.php:105-108` |
| `CategoryContent.contents()` | `hasMany(Content::class, 'category_contents_id', 'id')` | `v6/app/Http/Model/Prefecture/CategoryContent.php:96` |
| `Content.linksUnique()` | `hasOne(Link::class, 'contents_id', 'id')` | `v6/app/Http/Model/Prefecture/Content.php:116-119` — usada pelo link "Perguntas Frequentes" do bloco Acesso Rápido |

Não há pivot, nem FK composta, nem tabela de "pergunta -> resposta" separada.

## 5. Registro de módulo, permissões e menu

| Tabela | Registro | Onde |
|---|---|---|
| `modulos` | id 25, `name = 'Perguntas Frequentes'`, `slug = 'perguntas-frequentes'`, `status = 1` | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php:172-177` |
| `resources` | `slug = 'perguntas-frequentes'`, `modulo_id = 25` | `v6/database/seeds/ResourcesTableSeeder.php:243-248` |
| `menu_orders` | `slug = 'perguntas-frequentes'`, `modulo_id = 25` | `v6/database/seeds/MenuOrderSeeder.php:133-140` |
| `menu_items` | item de menu do portal com `category_contents_id` da FAQ | `v6/database/seeds/MenuItemsTableSeeder.php:1040` |

```php
// v6/database/migrations/2024_11_01_150206_create_modulos_table.php
// ID 25
DB::table('modulos')->insert([
    'name' => 'Perguntas Frequentes',
    'slug' => 'perguntas-frequentes',
    'status' => 1,
]);
```

O item de menu do **CMS** é montado em `v6/app/Providers/MenuServiceProvider.php:275-277`:

```php
case 'perguntas-frequentes':
    $event->menu->add(['text' => 'Perguntas Frequentes', 'url' => '/cms/conteudos/perguntas-frequentes', 'icon' => 'question-circle']);
```

## 6. Seed de conteúdo de demonstração

`v6/database/seeds/ContentsTableSeeder.php:438-487` cria 8 perguntas da Lei de Acesso à
Informação, no padrão `updateOrCreate` por `slug`:

| Slug | Pergunta (title) |
|---|---|
| `quem-esta-obrigado-prestar-informacoes` | Quem está obrigado a prestar informações? |
| `quais-sao-informacoes-disponibilizadas` | Quais são as informações que serão disponibilizadas? |
| `quem-pode-solicitar-informacoes` | Quem pode solicitar as informações? |
| `justificar-pedido-informacoes` | É necessário justificar o pedido de informações? |
| `pedido-solicitacao-anonimo` | Pode haver pedido de solicitação de informação anônimo? |
| `prazo-resposta-administracao` | Existe prazo para resposta da administração pública? |
| `recusa-prestacao-informacoes` | É possível a recusa imotivada à prestação de informações? |
| `cobranca-fornecimento-informacoes` | A administração pública pode cobrar pelo fornecimento das informações? |

Trecho real do seed:

```php
/*Perguntas frequentes*/
$categoryPerguntas = CategoryContent::where('slug', 'perguntas-frequentes')->first();
$content = Content::updateOrCreate(['slug' => 'quem-esta-obrigado-prestar-informacoes'],
    ['category_contents_id' => $categoryPerguntas->id]
);
$content->title ?? $content->update(['title' => 'Quem está obrigado a prestar informações?']);
$content->text ?? $content->update(['text' => '- os órgãos públicos integrantes da administração direta dos Poderes Executivo, Legislativo, incluindo as Cortes de Contas, e Judiciário e do Ministério Público;']);
```

## 7. Link no bloco "Acesso Rápido"

`v6/database/seeds/AcessoRapidoSeeder.php:49-57` insere na tabela `links` o atalho que
aponta para a página pública:

```php
DB::table('links')->insert([
    'title' => 'Perguntas Frequentes',
    'alt' => 'Perguntas Frequentes',
    'name' => 'Perguntas Frequentes',
    'isBlank' => false,
    'status_create' => '1',
    'link' => '/acesso-rapido/perguntas-frequentes',
    'contents_id' => $content_1
]);
```

O `contents_id` aponta para o item da categoria `acesso-rapido` (id 45) que carrega o
ícone e o texto do atalho.

## 8. Migrations relevantes

| Migration | Efeito |
|---|---|
| `v6/database/migrations/2018_04_02_180433_create_contents_table.php` | Cria `contents` |
| `v6/database/migrations/2018_04_01_180916_create_category_contents_table.php` | Cria `category_contents` |
| `v6/database/migrations/2023_04_10_151038_create_view_to_perguntas_frequentes.php` | Cria a view `perguntas_frequentes` |
| `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` | Cria `modulos` e insere o módulo `perguntas-frequentes` |

## 9. Integridade e índices

- `contents.category_contents_id` é FK para `category_contents.id`.
- Não há unicidade sobre `title`: perguntas repetidas são permitidas.
- Não há índice dedicado para busca textual: a busca global usa `ilike` com `translate`
  (`v6/app/Http/Filter/FilterSearchAllSite.php:52-55`), o que exige varredura.
