feat(S9): captura de novidades da campanha na home pública (form + CTA do hero) #104

Merged
fsolla merged 1 commit from S9-captura-de-novidades-da-campanha-na-home-publica-form-cta into main 2026-08-19 20:45:31 +00:00
Owner

Closes #93

Captura de novidades da campanha na home pública (S9): seção "Receba as novidades da campanha" logo acima do rodapé + CTA secundário do hero virando o atalho (#novidades, scroll suave). Form: nome + WhatsApp obrigatórios; e-mail, estado, cidade e comentário opcionais; toggle pré-selecionado "Quero fazer parte do time" gravado como subscription.campaignLevel (time|esporadico) — visível como coluna própria no admin.

Dados/consent: Contact + Subscription em withPayloadTransaction com consentimento NOVO fail-closed por chave estável campanha-novidades — sem o texto aprovado no admin (jurídico pendente), o form recusa a captura e nada é gravado. Anti-goals respeitados: nada de supporter, sem mescla com /mandato-no-whatsapp, bandeiras seguem acessíveis (rodapé + "Ver bandeiras" no estado de sucesso).

Schema: migration 20260819_192605_add_campaign_newsletter_capture — contact.state DROP NOT NULL (estado opcional no form; a ficha staff via zod segue exigindo) + coluna subscription.campaign_level com enum. Cadeia validada por pnpm migrate + int tests.

Testes: int submitCampaignNewsletter.int.spec.ts (fail-closed com mensagem exata + nada gravado; gravação dos dois níveis; estado omitido → null) · e2e campaignNewsletter.e2e.spec.ts (âncora do hero, submissão, sucesso in-place, verificação REST do registro) · e2e frontend atualizados (âncora #novidades; pins de geometria do hero preservados com "Receba/novidades" — 2 linhas, mesma contagem de caracteres).

Plano: docs/plans/captura-novidades-home-campanha-impl.md (aprovado em sessão; posição da seção ajustada a pedido — acima do rodapé; scroll suave) · changelog 2026-08-19-s9.md. Débito pós-entrega registrado como #102 (blocked, depends: #93).

Nota: o path de recusa (consent ausente) é coberto pelo int test — o e2e guard trata 5xx como falha e a action fail-closed responde 500 (precedente WebAuthn usa 4xx tratado).

Closes #93 Captura de novidades da campanha na home pública (S9): seção "Receba as novidades da campanha" logo acima do rodapé + CTA secundário do hero virando o atalho (`#novidades`, scroll suave). Form: nome + WhatsApp obrigatórios; e-mail, estado, cidade e comentário opcionais; toggle pré-selecionado "Quero fazer parte do time" gravado como `subscription.campaignLevel` (`time|esporadico`) — visível como coluna própria no admin. **Dados/consent:** `Contact` + `Subscription` em `withPayloadTransaction` com consentimento NOVO fail-closed por chave estável `campanha-novidades` — sem o texto aprovado no admin (jurídico pendente), o form recusa a captura e nada é gravado. Anti-goals respeitados: nada de `supporter`, sem mescla com `/mandato-no-whatsapp`, bandeiras seguem acessíveis (rodapé + "Ver bandeiras" no estado de sucesso). **Schema:** migration `20260819_192605_add_campaign_newsletter_capture` — `contact.state` DROP NOT NULL (estado opcional no form; a ficha staff via zod segue exigindo) + coluna `subscription.campaign_level` com enum. Cadeia validada por `pnpm migrate` + int tests. **Testes:** int `submitCampaignNewsletter.int.spec.ts` (fail-closed com mensagem exata + nada gravado; gravação dos dois níveis; estado omitido → null) · e2e `campaignNewsletter.e2e.spec.ts` (âncora do hero, submissão, sucesso in-place, verificação REST do registro) · e2e `frontend` atualizados (âncora `#novidades`; pins de geometria do hero preservados com "Receba/novidades" — 2 linhas, mesma contagem de caracteres). **Plano:** `docs/plans/captura-novidades-home-campanha-impl.md` (aprovado em sessão; posição da seção ajustada a pedido — acima do rodapé; scroll suave) · changelog `2026-08-19-s9.md`. Débito pós-entrega registrado como #102 (blocked, `depends: #93`). Nota: o path de recusa (consent ausente) é coberto pelo int test — o e2e guard trata 5xx como falha e a action fail-closed responde 500 (precedente WebAuthn usa 4xx tratado).
fsolla added 1 commit 2026-08-19 20:28:25 +00:00
feat(S9): captura de novidades da campanha na home pública (form + CTA do hero)
All checks were successful
CI (PR) / checks (pull_request) Successful in 8m33s
PR Ready + auto-merge / ready-automerge (pull_request) Successful in 17m6s
Promote plan-issue Related on main merge / plan-issue-ready (pull_request) Has been skipped
Main merge flips claimed issues to done + in-prod / issue-done (pull_request) Successful in 13s
2eab8dc07b
Seção 'Receba as novidades da campanha' acima do rodapé: nome + WhatsApp
obrigatórios, e-mail/estado/cidade/comentário opcionais, toggle pré-selecionado
'Quero fazer parte do time' gravado como subscription.campaignLevel
(time|esporadico). CTA secundário do hero vira o atalho (#novidades, scroll
suave). Contact + Subscription em withPayloadTransaction com consentimento
novo fail-closed por chave estável 'campanha-novidades' — nada é gravado sem o
texto aprovado no admin. Migration 20260819_192605 (state de contact nullable
+ coluna campaign_level). Impl plan, changelog, int + e2e.
Author
Owner

Consentimento criado em produção (rascunho p/ revisão jurídica): Consent id 7, chave campanha-novidades, 4 parágrafos cobrindo os dois níveis (time: comunicações frequentes + grupos de WhatsApp + ações; esporádico: sem grupos/sem frequência) + tratamento LGPD (finalidade, não-compartilhamento, direito de correção/exclusão/revogação). Inserido direto no teqo_1313 (2026-08-19) a pedido do produto; o jurídico revisa/edita o texto via admin (a chave permanece estável). Com o deploy do S9 a captura já nasce ativa — o fail-closed abriu porque o documento existe.

**Consentimento criado em produção (rascunho p/ revisão jurídica):** `Consent` id 7, chave `campanha-novidades`, 4 parágrafos cobrindo os dois níveis (time: comunicações frequentes + grupos de WhatsApp + ações; esporádico: sem grupos/sem frequência) + tratamento LGPD (finalidade, não-compartilhamento, direito de correção/exclusão/revogação). Inserido direto no `teqo_1313` (2026-08-19) a pedido do produto; o jurídico revisa/edita o texto via admin (a chave permanece estável). Com o deploy do S9 a captura já nasce ativa — o fail-closed abriu porque o documento existe.
fsolla merged commit 8d2352c06e into main 2026-08-19 20:45:31 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: fsolla/teqo#104
No description provided.