# CRUD minimo do CMS

## Objetivo

Definir o escopo funcional minimo do painel privado para gerir conteudo, midia, taxonomias e configuracoes globais sem depender de decisoes tacitas durante a implementacao.

## Principios

- O CMS privado e a origem de verdade de autoria e configuracao.
- A API publica continua somente-leitura e consome apenas entidades publicaveis ou configuracoes explicitamente expostas.
- Toda operacao de criacao, edicao, publicacao, arquivamento ou exclusao logica relevante precisa gerar evento de auditoria.
- Exclusao definitiva fica restrita a `super_admin` e so existe para casos excepcionais.

## Dominios cobertos

| Dominio | Objetivo | Exposicao publica |
| --- | --- | --- |
| Conteudo | Gerir posts e paginas com workflow editorial | Sim, via `/api/v1` quando publicado |
| Midia | Gerir biblioteca de arquivos e metadados | Indireta, por referencias em conteudo/configuracao |
| Taxonomias | Organizar conteudo por categorias e tags | Sim, quando vinculadas a conteudo publicado |
| Configuracoes | Controlar identidade e comportamento global do site | Parcial, via endpoint de site/config quando aplicavel |

## Papeis minimos por dominio

| Acao | `author` | `editor` | `super_admin` |
| --- | --- | --- | --- |
| Criar/editar rascunho de conteudo proprio | Sim | Sim | Sim |
| Submeter conteudo para revisao | Sim | Sim | Sim |
| Aprovar, publicar, agendar, arquivar conteudo | Nao | Sim | Sim |
| Upload e edicao de metadados de midia | Sim | Sim | Sim |
| Exclusao logica de midia sem uso publico | Nao | Sim | Sim |
| Criar/editar categorias e tags | Nao | Sim | Sim |
| Alterar configuracoes globais | Nao | Nao | Sim |
| Exclusao definitiva | Nao | Nao | Sim |

## 1. Conteudo

### Tipos minimos

- `post`: conteudo editorial listavel, categorizavel e tagueavel.
- `page`: conteudo estatico institucional, sem obrigacao de taxonomia.

### Campos minimos

| Campo | Post | Page | Observacoes |
| --- | --- | --- | --- |
| `id` | Sim | Sim | Identificador interno estavel |
| `type` | Sim | Sim | `post` ou `page` |
| `title` | Sim | Sim | Obrigatorio antes de envio para revisao |
| `slug` | Sim | Sim | Unico por tipo; reservado por historico |
| `excerpt` | Sim | Opcional | Resumo editorial e para listagens |
| `body` | Sim | Sim | Conteudo rico sanitizavel |
| `status` | Sim | Sim | Conforme workflow editorial |
| `featured_media_id` | Opcional | Opcional | Referencia a midia existente |
| `seo_title` | Opcional | Opcional | Fallback pode derivar de `title` |
| `seo_description` | Opcional | Opcional | Fallback controlado |
| `canonical_url` | Opcional | Opcional | Sobrescrita manual quando necessario |
| `author_user_id` | Sim | Sim | Ownership primario |
| `publish_at` | Opcional | Opcional | Obrigatorio para agendamento |
| `published_at` | Opcional | Opcional | Preenchido na publicacao |
| `updated_at` | Sim | Sim | UTC |

### Operacoes minimas

| Operacao | Resultado esperado |
| --- | --- |
| Criar rascunho | Cria conteudo em `draft` com ownership e primeira revisao de trabalho |
| Editar rascunho | Atualiza versao de trabalho e registra diff/versionamento |
| Submeter para revisao | Move para `in_review` com snapshot da submissao |
| Solicitar ajustes | Move para `changes_requested` com comentario obrigatorio |
| Aprovar | Move para `approved` e registra revisor |
| Agendar publicacao | Move para `scheduled` com `publish_at` futuro |
| Publicar | Move para `published` e fixa revisao publica |
| Arquivar | Remove da superficie publica sem apagar historico |
| Restaurar para retrabalho | Move de `archived` para `draft` |
| Excluir logicamente | Oculta do CMS padrao, preserva auditoria e referencias internas |

### Regras especificas

- `post` exige ao menos uma categoria antes de `approved`.
- `page` nao exige categoria nem tag.
- Slug publicado nao deve ser reciclado silenciosamente; se houver reuso, precisa de decisao explicita de `super_admin`.
- Conteudo publicado alterado deve gerar nova revisao interna antes de substituir a revisao publica.
- A listagem administrativa precisa expor filtros por `type`, `status`, `author`, `updated_at` e busca por `title`/`slug`.

## 2. Midia

### Objetivo

Centralizar upload, consulta e reuso de ativos sem transformar o CMS em DAM completo.

### Tipos minimos suportados

- Imagem raster: `jpg`, `jpeg`, `png`, `webp`
- Documento leve: `pdf`
- Vetor simples: `svg`, sujeito a sanitizacao/allowlist

### Campos minimos

| Campo | Obrigatorio | Observacoes |
| --- | --- | --- |
| `id` | Sim | Identificador interno |
| `storage_path` | Sim | Caminho interno/relativo controlado pelo CMS |
| `public_url` | Sim | URL resolvida para consumo |
| `filename` | Sim | Nome fisico |
| `mime_type` | Sim | Tipo validado no upload |
| `size_bytes` | Sim | Tamanho do arquivo |
| `width` | Opcional | Para imagens |
| `height` | Opcional | Para imagens |
| `alt_text` | Opcional | Recomendado para imagens publicas |
| `title` | Opcional | Rotulo editorial |
| `caption` | Opcional | Texto de apoio |
| `credit` | Opcional | Fonte/autoria quando houver |
| `uploaded_by` | Sim | Usuario responsavel |
| `created_at` | Sim | UTC |
| `status` | Sim | `active`, `archived`, `deleted` |

### Operacoes minimas

| Operacao | Resultado esperado |
| --- | --- |
| Upload | Valida tipo/tamanho, armazena arquivo e cria registro |
| Editar metadados | Atualiza `alt_text`, `caption`, `credit`, `title` |
| Buscar biblioteca | Filtro por tipo, data, uploader e texto |
| Reutilizar ativo | Permite associar o mesmo arquivo a multiplos conteudos |
| Arquivar ativo | Remove de seletores padrao sem quebrar referencias existentes |
| Excluir logicamente | Permitido apenas quando nao for midia principal de conteudo publicado ou mediante override auditado |

### Regras especificas

- O upload deve rejeitar extensoes e `mime_type` fora da allowlist.
- O CMS deve registrar referencias de uso para impedir exclusao insegura.
- Imagens usadas como destaque em conteudo publicado nao podem ser removidas sem substituicao ou override de `super_admin`.
- Variantes derivadas como thumbnail podem existir, mas nao entram no escopo minimo de edicao manual.

## 3. Taxonomias

### Tipos minimos

- `category`: hierarquica, usada como classificacao principal de `post`.
- `tag`: nao hierarquica, usada para rotulacao complementar.

### Campos minimos

| Campo | Category | Tag | Observacoes |
| --- | --- | --- | --- |
| `id` | Sim | Sim | Identificador interno |
| `type` | Sim | Sim | `category` ou `tag` |
| `name` | Sim | Sim | Nome visivel |
| `slug` | Sim | Sim | Unico por tipo |
| `description` | Opcional | Opcional | Apoio editorial/SEO |
| `parent_id` | Opcional | Nao | Apenas para categoria |
| `seo_title` | Opcional | Opcional | Quando houver pagina agregada publica |
| `seo_description` | Opcional | Opcional | Quando houver pagina agregada publica |
| `status` | Sim | Sim | `active`, `archived`, `deleted` |

### Operacoes minimas

| Operacao | Resultado esperado |
| --- | --- |
| Criar categoria/tag | Cria termo com slug valido |
| Editar termo | Permite renomear, atualizar slug e descricao |
| Reorganizar hierarquia | Atualiza `parent_id` de categorias |
| Arquivar termo | Remove de seletores padrao e de novas associacoes |
| Excluir logicamente | Permitido apenas quando nao houver conteudo publicado dependente ou mediante reassociacao previa |
| Listar uso | Exibe contagem de conteudos relacionados por estado |

### Regras especificas

- Categoria nao pode apontar para si mesma nem criar ciclo ancestral.
- Tag nao possui hierarquia.
- Slug alterado de termo publico deve acionar revisao de links agregados e cache.
- Conteudo publicado com categoria arquivada precisa de comportamento explicito: ou manter referencia historica ate edicao do conteudo, ou exigir remapeamento antes do arquivamento. O baseline minimo recomendado e bloquear o arquivamento se houver conteudo publicado dependente.

## 4. Configuracoes globais

### Objetivo

Gerir parametros transversais do site sem misturar configuracoes de infraestrutura com preferencia editorial.

### Conjuntos minimos

| Grupo | Campos minimos |
| --- | --- |
| Identidade do site | `site_name`, `site_tagline`, `default_locale`, `timezone` |
| URLs canonicas | `site_url`, `canonical_host`, `asset_base_url` |
| SEO global | `default_seo_title_pattern`, `default_seo_description`, `robots_policy` |
| Contato institucional | `contact_email`, `contact_phone`, `social_links` |
| Comportamento editorial | `posts_per_page`, `default_post_category_id`, `content_reviewer_policy` |

### Operacoes minimas

| Operacao | Resultado esperado |
| --- | --- |
| Consultar configuracoes | Carrega snapshot atual por grupo |
| Atualizar configuracoes | Persiste alteracoes validadas por grupo |
| Restaurar fallback de campo | Remove override e volta ao valor padrao do sistema quando permitido |
| Publicar efeito global | Invalida cache e disponibiliza configuracoes publicas derivadas para API/frontend |

### Regras especificas

- Apenas `super_admin` altera configuracoes globais.
- Cada salvamento precisa registrar diff por chave alterada.
- Configuracoes sensiveis de infraestrutura, segredos e credenciais nao pertencem a este CRUD; continuam em `config.php` ou ambiente.
- `default_post_category_id` precisa referenciar categoria `active`.
- `site_url` e `canonical_host` nao podem conflitar com a politica de SEO publica.

## Dependencias cruzadas

- Conteudo depende de midia para `featured_media_id`.
- Conteudo `post` depende de ao menos uma categoria `active`.
- Taxonomias nao podem ser excluidas se quebrarem conteudo publicado.
- Configuracoes globais podem definir defaults editoriais e SEO consumidos por conteudo.

## Auditoria minima por dominio

| Dominio | Eventos obrigatorios |
| --- | --- |
| Conteudo | criar, salvar rascunho, enviar revisao, pedir ajustes, aprovar, agendar, publicar, arquivar, excluir logicamente |
| Midia | upload, editar metadados, arquivar, excluir logicamente, restaurar |
| Taxonomias | criar, editar, reparentear categoria, arquivar, excluir logicamente, restaurar |
| Configuracoes | editar grupo, restaurar fallback, publicar efeito global |

## Ordem recomendada de implementacao

1. Modelar entidades persistentes e eventos de auditoria para os quatro dominios.
2. Implementar RBAC e ownership minimo conforme o workflow editorial.
3. Entregar CRUD de conteudo com revisoes e relacoes para midia/taxonomias.
4. Entregar biblioteca de midia com bloqueios de exclusao por uso.
5. Entregar CRUD de taxonomias com validacao hierarquica.
6. Entregar configuracoes globais por grupo com invalidacao de cache.

## Fora de escopo desta definicao

- Workflow de aprovacao multipla.
- Edicao colaborativa em tempo real.
- DAM avancado com crops manuais, pastas, IA ou versionamento binario.
- Taxonomias customizadas arbitrarias alem de categorias e tags.
- Configuracoes multi-site ou overrides por tenant.
