teqo/docs/plans/orientacao-shell-sem-titulos-secao-impl.md
Cursor Agent 39f69e603b
fix(B123): pass notification bell as server slot in desktop header
Client component cannot import async CampaignNotificationBellSlot directly;
mirror CampaignMobileTopBar slot pattern to fix staff page hangs in e2e.
2026-08-02 18:48:30 +00:00

3.9 KiB
Raw Blame History

Impl: Orientação na shell + aba — sem títulos grandes de seção

Status: aprovado Atualizado em: 2026-08-02 Issue: #250 Intenção: docs/plans/orientacao-shell-sem-titulos-secao.md Appetite restante: herdado (~1–1,5 dia eng)

Leitura da intenção

  • Outcome: orientação “onde estou” sai do corpo da página e vai para chrome estável (header mobile/desktop + aba Solla - Campanha - <Página>); corpo começa direto no trabalho; detalhe mantém h1 da entidade; Início sem título no header.
  • O que NÃO negociar: wizard/auth/convite/offline intocados; h1 de entidade em detalhe; leader lockdown; chips de universo removidos (não no header).
  • O que reavaliar: hipótese de CampaignListPageHeader — não existe; B118 nunca landou. Pathname registry + context override é mais maintainable que 15 nested layouts.

Abordagem recomendada

flowchart LR
  subgraph server [Server RSC]
    P[page.tsx] --> M[export metadata via campaignPageMetadata]
    P --> S[SetCampaignPageChrome em edit dinâmico]
  end
  subgraph client [Shell client]
    R[resolveCampaignPageChrome pathname+role] --> C[Provider merge override]
    C --> MB[CampaignMobileTopBar]
    C --> DH[CampaignDesktopHeader]
  end

Opções consideradas: A) nested layout.tsx por segmento · B) pathname registry + override context · C) só metadata sem shell
Recomendação: B — um owner (campaignPageChrome.ts), precedente wizard/home-search, role no layout, override só em edit dinâmico.
Rejeitadas: A (34 rotas, drift) · C (aceite exige shell)

Componentes / mudanças

  • campaignPageChrome.ts (src/lib/): vocabulário client-safe; resolveCampaignPageChrome; campaignPageMetadata
  • CampaignPageChromeContext.tsx: provider + SetCampaignPageChrome (override, layout effect cleanup)
  • CampaignPageChromeResolver.tsx: client; pathname + role → base chrome
  • CampaignDesktopHeader.tsx: uma linha título+subtítulo md+
  • CampaignMobileTopBar.tsx: app mode lê chrome efetivo; home vazio
  • (app)/layout.tsx: provider + resolver + desktop header; passa role
  • (campaign)/layout.tsx: title.template: 'Solla - Campanha - %s'
  • Páginas/componentes: remover headers de seção/create; manter h1 entidade + back em detalhe; SetCampaignPageChrome em edit; metadata em rotas
  • Migration: sem migration
  • Access / Consent: inalterado

Dados → forma

  • Orientação = texto estático por rota + role (quadro); sem dados de Payload no resolver.

Fases verificáveis

  1. Infra — lib + context + shell headers + metadata template
  2. Páginas — strip body headers; metadata; edit bridges
  3. Gates — pnpm gate:fast; pnpm push

Rabbit holes / Não escopo (engenharia)

  • Reintroduzir chips de escopo no header
  • Mexer em wizard chrome
  • h2 internos (ex. “Meus contatos (N)”)

Riscos e mitigação

  • E2E busca heading level 1 → atualizar para shell slot ou manter entity h1 only
  • Home search focus: chrome vazio em /campanha mesmo focado

Aceite de engenharia

  • Aceite de produto da intenção ainda coberto
  • Invariantes AGENTS/engineering-standards
  • Testes unit mobile top bar + metadata resolver previstos

Débitos deferidos (/simplify)

  • Registry único (pathRules + metadata por página): defer — gatilho quando 3ª rota dinâmica exigir override; hoje catálogo + metadata explícita é legível.
  • Resolver único no provider (evitar dupla resolução mobile/desktop): defer — custo negligível (~28 regex); revisit se bundle crescer.
  • Desktop header RSC (slot bell sem client boundary): corrigido nesta entrega — notificationBell slot como mobile.
  • Subtitle desktop truncado em uma linha: defer — validar com usuários; mobile já usa duas linhas.
  • Table-driven pathRules tests: defer — cobertura smoke suficiente para B123; expandir se matcher quebrar de novo.