Skip to content

fix(agenda): o botão "Reativar" tipo de agendamento passa a funcionar - #716

Open
paulolimajr77 wants to merge 1 commit into
melgarafael:mainfrom
paulolimajr77:fix/reativar-tipo-de-agendamento
Open

fix(agenda): o botão "Reativar" tipo de agendamento passa a funcionar#716
paulolimajr77 wants to merge 1 commit into
melgarafael:mainfrom
paulolimajr77:fix/reativar-tipo-de-agendamento

Conversation

@paulolimajr77

Copy link
Copy Markdown
Contributor

O botão "Reativar" de Configurações › Tipos de agendamento existe desde que a tela existe e nunca funcionou uma vez. Clicar devolve sempre 422 "Nenhum campo para alterar." — para quem não pediu para alterar campo nenhum.

Quem desativa um tipo por engano fica sem saída pela tela: o nome segue ocupado pelo tipo desligado, porque o slug é único.

A causa

app/app/settings/tenant/agenda/_client.tsx manda PATCH /api/v1/agenda/tipos com { id, is_active: true }. O alterarSchema daquela rota é criarSchema.partial().extend({ id }), e is_active não está entre os doze campos de camposDoTipo. Zod descarta chave desconhecida em silêncio: o corpo chega vazio ao update e a rota cai na recusa de "nenhum campo".

O compilador teria acusado. Não acusou porque a chamada terminava em as never — o único cast do arquivo, exatamente em cima da travessia.

O conserto

Espelha o DELETE em vez de tornar is_active editável. Aceitá-lo no PATCH deixaria o mesmo pedido que muda duração poder desligar um tipo, e a trilha registraria a religada como agenda.tipo_alterado { campos: ["is_active"] } — indistinguível de uma alteração de campo qualquer. Sub-rota de ação é a forma que a casa já usa (agenda/google/desconectar, contacts/merge, lgpd/anonymize).

  • POST /api/v1/agenda/tipos/reativar — mesma guarda do desativar (manager + requireSupportWrite), filtro explícito de organization_id, 404 quando não há linha
  • agenda.tipo_reativado em AUDIT_ACTIONS
  • o as never sai da tela

O que medi

tests/unit/agenda-reativar-tipo.test.ts (12 casos), em duas camadas:

  • comportamento da rota nova: grava is_active: true, filtra o tenant pela sessão, audita com verbo próprio, recusa o que não existe, e os dois caminhos de recusa não escrevem
  • travessia tela → rota: toda chave que a tela manda tem de ser aceita pelo schema, medida nas duas pontas pelo AST. Sabotado de volta ao estado anterior, o caso reprova nomeando is_active

⚠️ Custo pago no próprio teste, e vale para quem escrever guarda parecida: a primeira versão da travessia passou verde com a tela sabotada. O corpo era {…} as never — um AsExpression, não um ObjectLiteralExpression —, então a varredura atravessava sem ver chave nenhuma. O cast escondia o campo do compilador e do guarda escrito para vigiar o compilador. O leitor agora desembrulha as/satisfies antes de ler o corpo.

O caso e2e já existia e conferia o botão só com toBeVisible — foi assim que ele sobreviveu morto. Ver que o controle está desenhado não é ver que ele abre. Reescrito: agora clica e cobra o efeito nos dois lugares (o rótulo "desativado" sai da lista, e o tipo volta a ser oferecido em /app/agenda).

Gates na prévia do merge: typecheck 0, testes da área 26/26.

Provado em tela, numa VPS real rodando a mudança: desativar → reativar → o aviso "Tipo reativado." e a linha volta ao normal.

O que NÃO medi

  • pnpm test:unit inteiro nesta branch (rodei na branch de origem da mudança: 5 arquivos vermelhos, os 4 conhecidos de Windows + 1 meu, já corrigido)
  • a corrida do pnpm test:e2e — precisa de Supabase local e app buildado; a spec alterada roda no CI

🤖 Generated with Claude Code

Ele nunca funcionou, desde que a tela nasceu. Mandava
`PATCH /api/v1/agenda/tipos` com `{ id, is_active: true }`, e o
`alterarSchema` daquela rota e `criarSchema.partial()` — `is_active` nao
esta entre os doze campos de `camposDoTipo`. Zod descarta chave
desconhecida em SILENCIO: o corpo chegava vazio ao `update` e a rota
respondia 422 "Nenhum campo para alterar." para quem nao pediu para
alterar campo nenhum.

Quem desativou um tipo por engano ficava sem saida pela tela — o nome
seguia ocupado pelo tipo desligado, porque o slug e unico.

O compilador teria acusado. Nao acusou porque a chamada terminava em
`as never`, o unico cast do arquivo da tela, exatamente em cima da
travessia.

O conserto espelha o Desativar em vez de tornar `is_active` editavel:
aceita-lo no PATCH deixaria o mesmo pedido que muda a duracao poder
DESLIGAR um tipo, e a trilha registraria a religada como
`agenda.tipo_alterado { campos: ["is_active"] }` — indistinguivel de uma
alteracao de campo qualquer. Sub-rota de acao e a forma que a casa ja usa
(`agenda/google/desconectar`, `contacts/merge`, `lgpd/anonymize`).

O que vigia:

- `tests/unit/agenda-reativar-tipo.test.ts` — comportamento da rota nova
  (grava, filtra o tenant pela sessao, audita com verbo proprio, recusa o
  que nao existe) e a TRAVESSIA tela->rota: toda chave que a tela manda
  tem de ser aceita pelo schema. Sabotado de volta ao estado antigo, o
  caso reprova nomeando `is_active`.

- O caso e2e ja existia e conferia o botao so com `toBeVisible` — foi
  assim que ele sobreviveu morto. Ver que o controle esta DESENHADO nao e
  ver que ele ABRE. Agora clica e cobra o efeito nos dois lugares.

⚠️ Custo medido no proprio teste: a primeira versao da travessia passou
verde com a tela sabotada. O corpo era `{…} as never`, um `AsExpression`
e nao um `ObjectLiteralExpression`, entao a varredura atravessava sem ver
chave nenhuma. O cast escondia o campo do compilador E do guarda escrito
para vigiar o compilador. O leitor agora desembrulha `as`/`satisfies`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

@paulolimajr77 is attempting to deploy a commit to the rafael-maudibrasil's projects Team on Vercel.

A member of the Team first needs to authorize it.

@ecc-tools

ecc-tools Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

ECC Tools / Security Evidence

Commit: 44d5b86c4bb7aeeafa54eb6a260aac57eb60f129

Security evidence gate passed (success)

No security-sensitive scanner-evidence gap detected.

Mode: enforce

Scanned 7 changed file(s). No missing scanner-evidence signal was detected.

Check publication was denied or unavailable. An app owner must enable Checks: read and write, and the installation owner must approve the updated permission.

@ecc-tools

ecc-tools Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

ECC Tools / PR Risk Taxonomy

Commit: 44d5b86c4bb7aeeafa54eb6a260aac57eb60f129

PR taxonomy review recommended (neutral)

Detected 1 PR taxonomy bucket(s): CI/CD Recommendation.

Scanned 7 changed file(s).

Roadmap taxonomy buckets:

CI/CD Recommendation

CI, dependency, coverage, and contract signals should be routed into follow-up checks or verification work.

Signals:

  • API implementation changes may ship without contract artifact updates
  • 2 CI or workflow path(s) changed

Paths:

  • tests/e2e/agenda-tipos-de-agendamento.spec.ts
  • tests/unit/agenda-reativar-tipo.test.ts
  • app/api/v1/agenda/tipos/reativar/route.ts
  • app/api/v1/agenda/tipos/route.ts
  • app/app/settings/tenant/agenda/_client.tsx
  • lib/audit/actions.ts

Check publication was denied or unavailable. An app owner must enable Checks: read and write, and the installation owner must approve the updated permission.

@ecc-tools

ecc-tools Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

ECC Tools / Reference Set Readiness

Commit: 44d5b86c4bb7aeeafa54eb6a260aac57eb60f129

Reference set readiness gaps detected (neutral)

Reference evidence present for 1/7 areas (14%) across 7 changed file(s).

This check is based on files changed in this PR. Repository-level readiness is still reported by /ecc-tools analyze comments and generated manifests.

Area Status Evidence / Next Step
Deep analyzer corpus Missing Add analyzer fixture, golden, benchmark, or reference-set files that can catch analyzer regressions.
RAG/evaluator comparison Missing Add retrieval or evaluator reference-set comparison fixtures with expected ranking behavior.
PR salvage/review corpus Missing Add stale-PR, review-thread, reopen-flow, or salvage reference cases for queue cleanup automation.
Discussion triage corpus Missing Add public discussion triage fixtures, golden cases, or reference sets for informational, answered, and no-response classifications.
Harness compatibility Missing Add cross-harness, adapter-compliance, or harness-audit evidence for Claude, Codex, OpenCode, Zed, dmux, and agent surfaces.
Security evidence Present lib/audit/actions.ts
CI failure-mode evidence Missing Add captured CI failure logs, dry-run fixtures, or troubleshooting docs for common workflow failure modes.

Check publication was denied or unavailable. An app owner must enable Checks: read and write, and the installation owner must approve the updated permission.

@ecc-tools

ecc-tools Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

ECC Tools / Hosted Promotion Readiness

Commit: 44d5b86c4bb7aeeafa54eb6a260aac57eb60f129

Hosted promotion readiness passed (success)

No hosted promotion evidence gaps detected across 7 changed file(s); 0 corpus scenarios had matching evidence.

This check compares PR file changes against the evaluator/RAG promotion corpus in src/analyzers/fixtures/evaluator-rag-corpus.ts.
Hosted output scoring inspected 0 completed cached hosted job results.

No evaluator corpus scenarios matched this PR.

Check publication was denied or unavailable. An app owner must enable Checks: read and write, and the installation owner must approve the updated permission.

@github-actions

Copy link
Copy Markdown

Recebido, @paulolimajr77 — obrigado por isto.

Duas coisas que vão parecer erro seu e não são:

  • O check Vercel vermelho ("Authorization required to deploy") é esperado em PR de fork. A
    main faz deploy de produção e a Vercel se recusa a construir código de fora, o que está
    certo. Ele não entra no gate de merge.
  • No primeiro PR de quem nunca contribuiu aqui, os workflows ficam parados esperando
    liberação
    — política do GitHub, não sua. Enquanto isso o PR parece não ter check nenhum
    (nem o gh pr checks mostra os que estão nesse estado). Quem tria libera; você não precisa
    fazer nada.

Um mantenedor vai revisar de verdade — rodando os gates e reproduzindo o comportamento, não só
lendo o diff — e responde aqui em até um dia útil, com a medição junto, nunca com um "acho
que".

Esta mensagem é automática e não diz nada sobre o seu PR: ela é sobre o processo. O que vem
depois é pessoa.

@melgarafael

Copy link
Copy Markdown
Owner

Recebido — obrigado.

Duas coisas que vão parecer erro seu e não são:

  • O check Vercel vermelho ("Authorization required to deploy") é esperado em PR de fork. A main faz deploy de produção e a Vercel se recusa a construir código de fora, o que está certo. Ele não entra no gate de merge.
  • Os workflows ficam parados esperando liberação no primeiro PR de quem nunca contribuiu — política do GitHub, não sua. Acabei de liberar, o CI já está rodando.

Um aviso útil: a main andou doze PRs hoje e a v1.19.0 saiu. Se o seu ficar com conflito por causa disso, o conserto é do nosso lado — não precisa correr atrás. O mesmo vale para número de migration colidido e fragmento de release faltando.

Vou revisar de verdade — rodando os gates e reproduzindo o comportamento, não só lendo o diff — e volto com o resultado. Se eu achar algo, venho com a medição junto, nunca com um "acho que".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants