From 40f38eeb8c715ebabab388fc2e03b48f1d1ec628 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Mon, 10 Aug 2026 04:00:33 -0300 Subject: [PATCH] =?UTF-8?q?feat(C106):=20cards=20do=20feed=20edge-to-edge?= =?UTF-8?q?=20com=20linha=20+=20empty=20state=20(padr=C3=A3o=20B184/C107?= =?UTF-8?q?=20compartilhado)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adota o mecanismo canônico que o irmão B184/C107 estabeleceu em main (campaignListOmniboxFormClassName + campaignMobileHeaderIconClassName): a hipótese original de CSS de página virava twin — rebase resolveu mantendo a versão do irmão em CampaignUpdatesFilters. - C106 entrega o que o irmão não cobriu: cards edge-to-edge (-mx-4, border-b last:border-b-0, padrão exato de MunicipalityListMobileCards), neutralização do leak do @layer base ul (my-0 list-none [&>li]:mt-0) e copy única do empty state. - E2E campaignUpdatesMobile: label oculta, form sticky, icon abre o bottom sheet, cards edge-to-edge, empty state, regressão desktop. - Impl plan + changelog atualizados com a decisão revisada. --- docs/CHANGELOG-AGENTS.md | 2 + .../atualizacoes-mobile-sem-moldura-impl.md | 37 +++++++------------ tests/e2e/campaignUpdatesMobile.e2e.spec.ts | 14 +++---- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/docs/CHANGELOG-AGENTS.md b/docs/CHANGELOG-AGENTS.md index ea639794..582596ec 100644 --- a/docs/CHANGELOG-AGENTS.md +++ b/docs/CHANGELOG-AGENTS.md @@ -10,6 +10,8 @@ Conteúdo movido do `AGENTS.md` em 2026-07-30 (fatiamento do paradigma de agente **Recently resolved (2026-08-09):** **D6** (Issue #521) — push no device fechado de ponta a ponta. **Diagnóstico com evidência por elo** (leitura read-only de prod): (1) **envs VAPID ausentes no Vercel production** (verificado com `vercel env ls production`) — elo raiz: sem elas o servidor nunca chama o web-push e o card de perfil desabilita "Ativar"; (2) consentimento `campanha-notificacoes-push` já publicado (Onda 0, 2026-07-19); (3) 0 inscrições `pushSubscription` (bloqueado pelo elo 1); (4) 74 `Notification` geradas no sino (eventos fluem) mas **zero envios**; (5) banner no OS = passo humano (Android). **Dois defeitos de código corrigidos com evidência:** (a) o SW `/campanha/sw.js` servia `CACHE_NAME "campanha-dev"` em prod — deploys são CLI `vercel build --prebuilt` (git builds ignorados), e a rota `force-static` congelava o buildId no build onde `VERCEL_GIT_COMMIT_SHA`/`VERCEL_DEPLOYMENT_ID` não existem; a rota virou **`force-dynamic`** (lê `VERCEL_DEPLOYMENT_ID`, garantido em runtime) → cache versionado por deploy (unit test pina `dynamic`); (b) **subscribe não idempotente** — segundo toque em "Ativar neste dispositivo" no mesmo device devolvia a mesma subscription do browser e estourava o UNIQUE do `endpoint` (erro falso com o device já ativo); `subscribeCampaignPush` agora faz find-before-create e responde sucesso. **Ferramenta nova:** `pnpm db:check:push-chain` (`scripts/check-push-chain.mjs`, read-only — `PROD_DATABASE_URL` obrigatória, conexões com `default_transaction_read_only`) fecha um veredito por elo (SW servido/versionado, envs, consentimento, inscrições por usuário, log de eventos) com exit code. **Ops:** par VAPID gerado e adicionado em **Production** (`VAPID_PUBLIC_KEY`/`VAPID_PRIVATE_KEY`/`VAPID_SUBJECT`/`NEXT_PUBLIC_VAPID_PUBLIC_KEY`); preview ficou de fora — o projeto não tem Git repo conectado (deploys CLI) e `vercel env add ... preview` exige branch (`branch_not_found`); `NEXT_PUBLIC_*` precisa do build do próximo deploy para inliner. \*\*Pe... **Recently resolved (2026-08-09):** **C106** (Issue #517) — feed de atualizações `/campanha/atualizacoes` sem moldura no mobile: label "Filtrar atualizações" vira sr-only (continua no a11y tree), o filtro perde caixa/borda e fica **sticky** sob a top bar com a linha separadora (`border-bottom`), cards edge-to-edge (`-mx-4`) sem borda/arredondamento com divisor de linha. **Mecanismo herdado do C101** (CSS de página, não prop no chassis): `CampaignUpdatesFeed.css` com media query + `:has()` zerando o padding-top do scroll container (padrão `activity-agenda-filter-strip`); o chassis B127 ganhou só um hook estável `data-slot="campaign-omnibox-field"` (sem mudança de comportamento, reutilizável pelo B184). "Nova atualização" (texto+outline) some do mobile e vira **icon no header via `SetCampaignHeaderAction`** (slot C94/C95; `md:hidden` + botão `hidden md:inline-flex` — gate de resolução 100% CSS, mesmo modal C89). Empty state: copy única "Ajuste o filtro ou registre um novo fato de campo." (descreve a ação, vale nas duas resoluções). **Bug pré-existente corrigido no caminho:** o `@layer base` editorial aplica `my-6 ml-6 list-disc [&>li]:mt-2` a todo `ul` — o feed era a única lista campaign em `