feat(frontend): Telefonia > Ramais — CRUD, reset de senha, isolamento por tenant
Tela /app/telefonia/ramais completa: listagem com busca/ordenacao, criacao com reveal de senha SIP (gerada pela API, mostrada uma unica vez), detalhe com redefinir senha (novo POST /extensions/:id/reset-password — unica forma de "editar" a senha, nunca reexpoe a existente) e remover (soft delete), confirmacao inline de 2 cliques em vez de modal. Cada tela deixa explicito de qual tenant os ramais sao, alem do isolamento por RLS que ja existia. Corrige de quebra um bug real que afeta qualquer acao futura sem payload: apiFetch sempre mandava Content-Type: application/json mesmo em requests sem body, e o parser do Fastify rejeita body vazio com esse header. Testado ponta a ponta com um tenant real (Acme Call Center): criar ramal, revelar senha, redefinir (senha nova confirmada diferente da original), remover, lista voltando vazia. Dark mode e mobile conferidos. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EWHKmcVJtstQFErbZ1AanY
This commit is contained in:
48
TODO.md
48
TODO.md
@@ -766,15 +766,53 @@ app do Tenant + Dashboard (agente.md secao 162, 169)
|
||||
batendo com `maxDailyCalls` do plano trial; drawer mobile abre e
|
||||
fecha corretamente; dark mode conferido. Screenshots em
|
||||
`apps/frontend/.impeccable/review/`.
|
||||
- [ ] Menu Tenant inteiro (Discador/Call Center/Telefonia/Monitoramento/
|
||||
Gravações/IA/Relatórios/Administração) ainda "em breve" — próxima
|
||||
fase natural é Telefonia > Ramais (CRUD mais simples já testado
|
||||
ponta a ponta desde a PHASE 08, mesmo padrão de tabela da Tarifas)
|
||||
- [ ] Menu Tenant fora Dashboard/Telefonia > Ramais (Discador/Call
|
||||
Center/Troncos/Dialplan/Monitoramento/Gravações/IA/Relatórios/
|
||||
Administração) ainda "em breve"
|
||||
- [ ] "Itens sem permissão não aparecem" (secao 169) não é aplicado
|
||||
ainda — a IA do tenant aparece inteira pra qualquer usuário
|
||||
autenticado do tenant, independente das permissions reais dele
|
||||
|
||||
## PHASE 25+ — ver `agente.md` seções 140 em diante (resto do Frontend,
|
||||
## PHASE 25 — Frontend: Telefonia > Ramais (agente.md secao 39-40, 169,
|
||||
178)
|
||||
- [x] `POST /extensions/:id/reset-password` (novo endpoint) — só forma
|
||||
de "editar" a senha SIP é gerar uma nova e mostrar ela UMA vez
|
||||
(mesmo caminho da criação, secao 39: nunca reexpor a existente).
|
||||
`b2bcall-fs-config` resolve o directory ao vivo por request, sem
|
||||
arquivo/sync intermediário — um `UPDATE` já é suficiente, sem
|
||||
precisar notificar nada.
|
||||
- [x] Tela `/app/telefonia/ramais`: listagem com busca/ordenação (mesmo
|
||||
padrão client-side da Tarifas), criação (número, nome, caller ID)
|
||||
com reveal da senha SIP gerada (`SecretReveal`, novo componente:
|
||||
aviso + valor monoespaçado + copiar), detalhe com "Redefinir
|
||||
senha" (confirmação inline de 2 cliques, sem modal) e "Remover
|
||||
ramal" (zona de risco, mesma confirmação inline, soft delete).
|
||||
Cada tela deixa explícito de qual tenant os ramais são (nome do
|
||||
tenant na descrição da lista e no cabeçalho do detalhe) — pedido
|
||||
explícito do usuário, além do isolamento por RLS que já existia.
|
||||
- [x] **Bug real, achado nesta fase**: `apiFetch` (frontend) sempre
|
||||
mandava `Content-Type: application/json` mesmo em requests sem
|
||||
body (`POST .../reset-password`, `DELETE`) — o parser de body do
|
||||
Fastify rejeita body vazio com esse header ("Body cannot be empty
|
||||
when content-type is set to 'application/json'"), então toda
|
||||
ação sem payload quebrava com 400. Nunca tinha aparecido antes
|
||||
porque Tarifas só fazia POST com body. Corrigido: o header só vai
|
||||
quando `init.body` existe de verdade — provavelmente afeta outras
|
||||
ações futuras sem payload, não só Ramais.
|
||||
- [x] Testado ponta a ponta com o tenant real (Acme Call Center):
|
||||
criar ramal 1500 → senha revelada uma vez → ver detalhe → redefinir
|
||||
senha → nova senha diferente da original confirmada → voltar pra
|
||||
lista (1 ramal, badge "Ativo") → remover → lista vazia de novo.
|
||||
Dark mode e mobile conferidos.
|
||||
- [ ] Editar outros campos (nome, caller ID, contexto, registros) ainda
|
||||
não existe — nem no backend (só create/get/list/delete/reset-
|
||||
password) nem no frontend; só a senha tem "edição" por enquanto,
|
||||
conforme pedido
|
||||
- [ ] Quota de ramais (`maxExtensions`) já é aplicada pelo backend desde
|
||||
a PHASE 14, mas a UI não mostra consumo/limite antes de tentar
|
||||
criar — o erro 403 apareceria só depois do submit
|
||||
|
||||
## PHASE 26+ — ver `agente.md` seções 140 em diante (resto do Frontend,
|
||||
Security, Tests)
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user