feat: implement Call Center queues (mod_callcenter)

- Investigated the real callcenter_config command surface via
  'help callcenter_config' on the running FreeSWITCH before writing any
  code: queues only have load/unload/reload (static XML + reload, no
  'queue add' exists), while agents and tiers are fully dynamic via ESL
  commands (agent add, tier add) -- no file involved. This shapes the next
  phase (Agents/Tiers) differently from this one.
- queues table (tenant-scoped, RLS): strategy, moh/announce, wait times,
  tier rules, discard/abandoned handling, skip-agents-with-external-calls,
  recording_enabled
- packages/telephony: buildQueueXml()
- infrastructure/freeswitch: our own callcenter.conf.xml override (empties
  the vanilla static agents/tiers -- those become fully dynamic in the next
  phase) that includes callcenter_queues.conf.d/*.xml via X-PRE-PROCESS,
  same pattern as the Sofia gateway directory
- apps/api/src/queues: CRUD (POST/GET/GET:id/DELETE) using the queues.view/
  .manage permissions already in the seed
- b2bcall-fs-config (queue-sync.ts): one XML file per queue on a shared
  volume, synced via Redis pub/sub (b2bcall:queues:sync) on create/delete
  and once at boot -- same shape as trunk-sync.ts
- confirmed manually against the real FreeSWITCH, before coding the sync
  logic: 'queue load <name>' fails ('Invalid Queue not found!') for a file
  added after boot -- needs 'reloadxml' first to repopulate the in-memory
  XML tree from disk; after that, 'queue reload <name>' alone handles both
  create and update, no need to distinguish load vs reload
- verified end-to-end: created a queue (ROUND_ROBIN, maxWaitTime=120,
  discardAbandonedAfter=90), 'callcenter_config queue list' showed the
  correct values on the FreeSWITCH side; deleted it, list went back empty

docs/QUEUES.md
This commit is contained in:
2026-08-28 09:15:11 -03:00
parent 0720a0efe3
commit 6628578c42
15 changed files with 674 additions and 5 deletions

29
TODO.md
View File

@@ -173,7 +173,34 @@
múltiplas em sequência, não implementado
- [ ] `dialplan.view`/`.manage` não existem — reusei `freeswitch.*`
## PHASE 11+ver `agente.md` seções 37 em diante (Call Center/mod_callcenter,
## PHASE 11 — mod_callcenter / Queues (agente.md secao 37, 50-51)
- [x] Investigado `help callcenter_config` real antes de codar: filas só
têm `load`/`unload`/`reload` (XML estático + reload, sem `queue add`);
agentes e tiers são 100% dinâmicos via comando ESL (`agent add`,
`tier add`) — próxima fase, sem arquivo nenhum
- [x] `queues` table (tenant-scoped, RLS) — strategy, moh/announce,
wait times, tier rules, discard/abandoned, skip-external-calls,
recording_enabled
- [x] `packages/telephony`: `buildQueueXml()`
- [x] `overrides/autoload_configs/callcenter.conf.xml` própria (zera
agents/tiers estáticos da vanilla, inclui
`callcenter_queues.conf.d/*.xml` via X-PRE-PROCESS)
- [x] `apps/api/src/queues`: CRUD (POST/GET/GET:id/DELETE), permissions
`queues.view`/`.manage`
- [x] `b2bcall-fs-config` (`queue-sync.ts`): 1 arquivo por fila (volume
compartilhado), sincroniza via Redis pub/sub (`b2bcall:queues:sync`)
- [x] Achado real, confirmado testando manualmente antes de escrever código:
`queue load` falha se o arquivo foi adicionado depois do boot —
precisa de `reloadxml` primeiro; depois disso, `queue reload` sozinho
serve tanto pra criar quanto atualizar
- [x] Testado ponta a ponta: criar fila (ROUND_ROBIN, maxWaitTime=120,
discardAbandonedAfter=90) → `callcenter_config queue list` mostra os
parâmetros corretos → deletar → lista volta vazia
- [ ] Agentes/Tiers/Pausas (secao 45-49) — próxima fase
- [ ] Monitoramento em tempo real (secao 54) — depende de WebSocket
- [ ] Quota de filas — depende de Plans/Entitlements
## PHASE 12+ — ver `agente.md` seções 45 em diante (Agentes, Tiers, Pausas,
Predictive Dialer, Recordings, AI, Billing, Frontend, Reports, Security, Tests)
---