# P19 — Engajamento e comunicação

| Campo | Valor |
|---|---|
| Programa | F7+ — operação, estrutura e conteúdo |
| Status | `planejado` |
| Depende de | P9, P11, P14 |
| Habilita | P20 |
| Tamanho | **G** (5–7 sessões) |
| ADRs | ADR-019 (LGPD), ADR-021 (rate limit), ADR-024, ADR-026, ADR-028, ADR-033, ADR-035 |

## 1. Objetivo

Implementar os canais de **participação e contato** — Agenda de Eventos, Fale Conosco, Trabalhe
Conosco, Enquetes, Newsletters, Revisões e, se houver demanda, Formulários Dinâmicos — com
consentimento, antiabuso e retenção. Nenhum formulário confia no cliente; nenhum log carrega PII.

**Resultado observável:** o cidadão vê a agenda, envia uma mensagem, vota em uma enquete, assina a
newsletter com double opt-in e se candidata a uma vaga; o CMS responde e exporta; o formulário
resiste a spam e não duplica voto/assinatura.

## 2. Escopo fechado

### S1 — Agenda de Eventos + Fale Conosco

- `Portal/Agenda` (token `agenda`, grupo `Portal`):
  - `eventos`: `id`, `slug` único, `titulo` jsonb, `descricao` AST, `inicio`, `fim` null,
    `local`, `categoria`, `imagem_media_id`, `link` (https validado), `status` enum
    (`agendado|realizado|cancelado`), `active`, timestamps.
  - Portal `/agenda` (lista por mês/categoria, destaque do próximo), detalhe; CMS CRUD; sitemap/busca.
  - Sem calendário JS obrigatório; visão em lista é o baseline.
- `Portal/FaleConosco` (token `fale_conosco`):
  - `mensagens_contato`: `id`, `nome`, `email`, `assunto`, `mensagem`, `consent_at`, `status`
    enum (`nova|lida|respondida|arquivada`), `ip_hash` (HMAC com pepper), timestamps.
  - Portal form com honeypot/time-trap/rate limit (ADR-021); notificação ao setor via P9; CMS lista/
    responder; retenção; sem PII em log.
  - Distinto da Ouvidoria (P11): contato não gera protocolo/prazo legal.

### S2 — Trabalhe Conosco

- `Portal/TrabalheConosco` (token `trabalhe_conosco`).
- Tabelas `vagas` (`titulo`, `slug`, `descricao` AST, `requisitos`, `inicio`, `fim`, `status`,
  `anexo_media_id`) e `candidaturas` (`vaga_id`, `nome`, `email`, `curriculo_media_id`,
  `consent_at`, `status`, `ip_hash`, timestamps).
- Portal vagas/detalhe + candidatura; CMS CRUD/status; currículo privado (Media privado, download
  restrito); retenção e expurgo; consentimento explícito.
- Regras: candidatura duplicada por vaga+e-mail bloqueada; upload com MIME/magic bytes e limite;
  nenhum currículo em URL pública; não enviar e-mail com anexo (link seguro).
- `PODE`: só com demanda/contrato; o módulo é sensível (dados pessoais).

### S3 — Enquetes + Newsletters

- `Portal/Enquetes` (token `enquetes`):
  - `enquetes`: `id`, `slug`, `pergunta` jsonb, `inicio`, `fim`, `active`, timestamps;
  - `enquete_opcoes`: `id`, `enquete_id`, `texto` jsonb, `position`;
  - `enquete_votos`: `id`, `enquete_id`, `opcao_id`, `voter_hash` (HMAC de IP+sessão+enquete),
    `created_at`; `UNIQUE (enquete_id, voter_hash)` — um voto por participante, sem PII.
  - Portal vota + resultados agregados; CMS cria/encerra; sem cookie de tracking; rate limit.
- `Portal/Newsletters` (token `newsletters`):
  - `newsletter_inscricoes`: `id`, `email` único case-insensitive, `consent_at`, `confirmed_at`,
    `unsubscribed_at`, `token` (hash), timestamps.
  - Portal assina (double opt-in), confirma e descadastra por link assinado; CMS lista/segmenta
    (mínimo), export; envio em lote fora do MVP (P13/deliverability).
  - Regras: sem confirmação não recebe; unsubscribe imediato; retenção; nenhum e-mail em log.
- `PODE` para newsletter (só com demanda real e operação de e-mail).

### S4 — Revisões + Formulários Dinâmicos (condicional)

- `Portal/Revisoes` (token `revisoes`):
  - `revisao_formularios` (versão, schema de perguntas, ativo), `revisao_respostas` (respostas
    jsonb, score, consented_at, ip_hash); portal responde; CMS vê agregados (não respostas
    individuais sem base legal).
  - Avaliação do site com perguntas fechadas e faixa de score; sem texto livre obrigatório.
- `Formulários Dinâmicos` (`COND` — §7 B3 da `REVISAO`):
  - Só com demanda real (pesquisa/autoavaliação); **módulo**, sem service prematuro.
  - `formularios` (schema versionado, scoring, ativo) + `formulario_respostas` (answers jsonb,
    score, consent, ip_hash, result_token assinado); versão imutável após a 1ª submissão.
  - Tipos de campo concretos, validação server-side, agregação em SQL, export CSV; sem HTML/Blade
    no banco; sem service até o 2º consumidor.
- Sem demanda, `Formulários` fica fora; `Revisões` pode ser entregue como formulário fixo.

### S5 — Integração e fechamento

- Notificações via P9; nenhum módulo troca mailer global.
- Cada módulo com URL pública registra `SitemapSource`/`SearchSource` quando fizer sentido (agenda,
  vagas; não formulários/enquetes).
- LGPD: consentimento, retenção, expurgo, DSAR; nenhum PII em log/telemetria; acesso a candidaturas
  auditado.
- E2E: agenda, contato, candidatura, voto único, double opt-in/unsubscribe, revisão; axe; 4 locales.
- `make check` 2× + `E2E=1`; cobertura ≥90%; PHPStan max 0.

## 3. Fora de escopo

- **PNTP 15.6** (pesquisas de satisfação com resultado público) é **P25**; P19 pode fornecer o
  formulário, mas o resultado agregado é de P25.
- CRM, automação de marketing, disparo de newsletter em massa (P13/deliverability).
- Chat/WhatsApp, atendimento em tempo real.
- Formulários como service; motor genérico sem demanda.
- Pagamento/inscrição em eventos.
- Dados sensíveis (saúde, biometria) em formulários.

## 4. Fatias de sessão

| Sessão | Entrega | Prova | Depende |
|---|---|---|---|
| **P19.S1** | Agenda + Fale Conosco | anti-spam; notificação; retenção; sem PII | P9/P11/P14 |
| **P19.S2** | Trabalhe Conosco (PODE) | currículo privado; consentimento; duplicata | S1 |
| **P19.S3** | Enquetes + Newsletters | voto único; double opt-in; unsubscribe | S1 |
| **P19.S4** | Revisões + Formulários (COND) | versão imutável; score; sem HTML no banco | S1 |
| **P19.S5** | integração + E2E + docs | 4 locales; axe; 2× check | S1–S4 |

## 5. DoD

- [ ] Formulários com CSRF, honeypot/time-trap/rate limit e validação server-side.
- [ ] Consentimento persistido; retenção/expurgo; DSAR; nenhum PII em log.
- [ ] Voto único e assinatura double opt-in funcionam; unsubscribe imediato.
- [ ] Currículos e mensagens privados; nenhuma URL pública de arquivo pessoal.
- [ ] Formulários dinâmicos só com demanda; sem service prematuro.
- [ ] `make check` 2× + `E2E=1`; cobertura ≥90%; PHPStan max 0.
- [ ] PNTP 14.3/15.6: Carta de Serviços (P15) e satisfação pública (P25) linkadas, sem duplicar.

## Fechamento — ficha de revisão

> **Obrigatório antes de fechar:** criar `_to_revision/P19-engajamento.md` e seguir
> `_to_revision/README.md` + `_to_revision/PROTOCOLO.md` (v2.0). A ficha não é gate de build; é a
> entrada da fila de revisão profunda.

- Cabeçalho: fase, `kd` épico/tasks/slices, âncoras (este arquivo, ADRs e código) e status
  `⬜ pendente` → `🟡 em revisão` → `✅ revisado` / `🔧 com correções`.
- Conteúdo: o que foi implementado, arquivos/superfícies a revisar, checklist D1–D14 aplicável,
  riscos e observações.
- Fechamento: preencher “Notas da revisão” com data/revisor/resultado e achados (`kd write
  --anchor`), atualizar a fila em `_to_revision/README.md` e `_to_revision/_inventario.md`.
- Achado com correção exige teste vermelho→verde; a fase só é `closed` no `kd` com a ficha
  registrada.

## 6. Riscos

| Risco | Mitigação |
|---|---|
| Spam/flood | honeypot/time-trap/rate limit + 429 RFC 7807 |
| Voto duplicado | `UNIQUE (enquete_id, voter_hash)` + teste |
| Newsletter sem consentimento | double opt-in + unsubscribe + retenção |
| Currículo exposto | Media privado + download restrito + auditoria |
| Formulários virarem HTML no banco | schema/AST + renderer; teste |
| E-mail em log | metadados only; teste de payload |

## 7. Retomada

```bash
kd prime
kd ask "agenda fale conosco trabalhe conosco enquetes newsletters revisões formulários"
kd task list --ready
```

Ler: `dossie_modules/{agenda-de-eventos,enquetes,newsletters,revisoes,formularios-dinamicos}/**`
→ `sucesu_analise/05_modulos/Institucional/FaleConosco/**`, `Publicacoes/Agenda/**`,
`Publicacoes/TrabalheConosco/**` → `MODULOS.md` §1/P19 → P9/P11.
