From 2ac3a3e512bf0f1d1c416cb2b4543ae6b3c9a831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Ign=C3=A1cio=20Fontoura=20Solla?= Date: Sun, 26 Jul 2026 22:17:04 -0300 Subject: [PATCH] Fix Prettier on B40/B41 plan docs. --- docs/plans/login-biometrico-campanha.md | 4 ++-- docs/plans/scroll-horizontal-lista-municipios.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/plans/login-biometrico-campanha.md b/docs/plans/login-biometrico-campanha.md index 236f41ee..3ae1f691 100644 --- a/docs/plans/login-biometrico-campanha.md +++ b/docs/plans/login-biometrico-campanha.md @@ -27,7 +27,7 @@ Dados: N/A — credenciais WebAuthn; nenhum KPI/série/mapa. ## Contexto -Hoje o único caminho de login é senha (`payload.login` → cookie `campaign-token`). **B39** alonga a sessão (checkbox "Lembrar de mim"), mas quando a sessão expira o usuário digita de novo. Em dispositivos com Secure Enclave / StrongBox, o browser expõe **WebAuthn** (`navigator.credentials`) com *platform authenticator* — a UI do SO pede digital/Face ID e devolve uma asserção verificável no servidor. +Hoje o único caminho de login é senha (`payload.login` → cookie `campaign-token`). **B39** alonga a sessão (checkbox "Lembrar de mim"), mas quando a sessão expira o usuário digita de novo. Em dispositivos com Secure Enclave / StrongBox, o browser expõe **WebAuthn** (`navigator.credentials`) com _platform authenticator_ — a UI do SO pede digital/Face ID e devolve uma asserção verificável no servidor. Pedido de produto (2026-07-26): após o primeiro login, oferecer login com digital nos aparelhos que tiverem leitor. @@ -46,7 +46,7 @@ Não há WebAuthn / passkey / Credential Management de produto no código hoje. - **WebAuthn platform authenticator (passkey/device-bound), não "ler a digital e comparar com hash nosso".** O SO faz a biometria; o app só verifica a asserção. **Rejeitado:** (a) Credential Management API só para autofill de senha (não é feature de produto); (b) armazenar senha cifrada e "desbloquear" com WebAuthn sem asserção server-side (pior modelo); (c) SDK nativo / Capacitor (fora do app Next). - **Enrollment só depois de sessão senha válida** (ou reset de senha recente). **Rejeitado:** registrar passkey a partir de e-mail mágico sem senha no v1 (explode recovery). - **Storage server-side das credenciais** (collection ou campo array versionado em `campaignUser`) com `credentialID`, `publicKey`, `counter`, `transports`, label do dispositivo. **Rejeitado:** só `localStorage` (não autentica no servidor); depender só do password manager do browser sem registro nosso (não controlamos UX "Entrar com digital"). -- **Login biométrico emite o TTL longo (B39 "lembrar")** — o enrollment no dispositivo *é* o consentimento de confiança. **Rejeitado:** TTL curto no biométrico (derrota o job); exigir checkbox remember no fluxo biométrico. +- **Login biométrico emite o TTL longo (B39 "lembrar")** — o enrollment no dispositivo _é_ o consentimento de confiança. **Rejeitado:** TTL curto no biométrico (derrota o job); exigir checkbox remember no fluxo biométrico. - **i18n e naming:** `campaignWebAuthn`, `passkey`/`webauthnCredential` nos identificadores; copy pt-BR ("Entrar com digital ou Face ID", "Ativar neste aparelho"). ## Questões em aberto diff --git a/docs/plans/scroll-horizontal-lista-municipios.md b/docs/plans/scroll-horizontal-lista-municipios.md index bee8dc25..19242853 100644 --- a/docs/plans/scroll-horizontal-lista-municipios.md +++ b/docs/plans/scroll-horizontal-lista-municipios.md @@ -27,9 +27,9 @@ Dados: N/A — chrome de tabela; as métricas já existentes não mudam de forma ## Contexto -Em **B16 ✓**, a lista de municípios optou por `containerClassName="overflow-x-visible"` para o `sticky top-0` dos `th` resolver contra o scroller do `
` (`campaign-content-scroll`). Trade-off documentado no plano: *"uma tabela mais larga que a viewport passa a rolar junto com a página"*. Com as colunas de E8/E9/E10/B27, em tablet/desktop a tabela **estoura** a tela — pedido de produto 2026-07-26. +Em **B16 ✓**, a lista de municípios optou por `containerClassName="overflow-x-visible"` para o `sticky top-0` dos `th` resolver contra o scroller do `
` (`campaign-content-scroll`). Trade-off documentado no plano: _"uma tabela mais larga que a viewport passa a rolar junto com a página"_. Com as colunas de E8/E9/E10/B27, em tablet/desktop a tabela **estoura** a tela — pedido de produto 2026-07-26. -O precedente já existe na página de territórios (**B21 ✓**): [`TerritoryList.tsx`](../../src/components/campaign/municipality/TerritoryList.tsx) usa `overflow-x-auto` e [`TerritoryListColumns.tsx`](../../src/components/campaign/municipality/TerritoryListColumns.tsx) marca a 1ª coluna com `sticky left-0 z-20 … bg-background`. O plano de reorder ([reordenar-colunas-lista-municipios.md](reordenar-colunas-lista-municipios.md), fora de escopo) já travava *"Coluna Município fixa à esquerda"* como âncora — este item entrega essa âncora **sem** DnD. +O precedente já existe na página de territórios (**B21 ✓**): [`TerritoryList.tsx`](../../src/components/campaign/municipality/TerritoryList.tsx) usa `overflow-x-auto` e [`TerritoryListColumns.tsx`](../../src/components/campaign/municipality/TerritoryListColumns.tsx) marca a 1ª coluna com `sticky left-0 z-20 … bg-background`. O plano de reorder ([reordenar-colunas-lista-municipios.md](reordenar-colunas-lista-municipios.md), fora de escopo) já travava _"Coluna Município fixa à esquerda"_ como âncora — este item entrega essa âncora **sem** DnD. `CampaignTable` / `MunicipalityList` (trecho desktop `hidden md:block`) são o alvo. Cards mobile (`md:hidden`) ficam em **B42**.