feat: add outbound routes (Issabel-style dial pattern masking)
Nova aba 'Dialplan -> Rotas de Saída': abstração amigável sobre o dialplan bruto, no mesmo espírito das Outbound Routes do Issabel/FreePBX. O usuário informa (prepend) + prefix | match pattern (sintaxe de padrão do Asterisk: X/Z/N/faixas/coringas, sem o '_' inicial) e escolhe o tronco, sem escrever exten=>/Dial() à mão. - packages/database: model OutboundRoute + migration - apps/api/src/outbound-routes: gerador determinístico (contexto b2bcall-outbound-routes, incluído em b2bcall-agents — contexto padrão de Extension.context), service/controller CRUD reaproveitando as permissões dialplans.*, 6 testes unitários - apps/api/src/dialplan/dialplan.service.ts: publish() agora gera e verifica também o contexto das rotas, no mesmo pipeline de versionamento/rollback automático das entradas de dialplan brutas - apps/frontend: aba com formulário (prepend/prefix/padrão/tronco) e preview ao vivo da máscara resultante O prefixo é sempre removido do número antes de discar e substituído pelo prepend — o tronco nunca vê o prefixo digitado pelo agente, só o número já mascarado. Não usado pelo discador preditivo (campanhas já sabem o tronco via Campaign.trunkId diretamente). Build/lint/testes (api+frontend) verificados; teste end-to-end contra o Asterisk real ficou pendente porque a senha do super_admin foi trocada durante a sessão (acesso legítimo do usuário) — validação via UI delegada ao usuário.
This commit is contained in:
@@ -29,6 +29,27 @@ quando um Tronco/Ramal é criado/editado pela API.
|
||||
`DialplanService` a partir de `DialplanEntry`/`DialplanVersion`
|
||||
(Postgres). Toda alteração é uma nova `DialplanVersion` com validação
|
||||
(`dialplan reload` + checagem de erro) e rollback automático se falhar.
|
||||
- **Rotas de saída** (`OutboundRoute`, tela "Dialplan → Rotas de Saída"):
|
||||
abstração amigável no estilo Issabel/FreePBX sobre o dialplan bruto — o
|
||||
usuário informa `prepend` + `prefix` + `matchPattern` (sintaxe de padrão
|
||||
do Asterisk: `X`/`Z`/`N`/faixas `[1-5]`/`.`/`!`, sem o `_` inicial) e
|
||||
escolhe o tronco, sem escrever `exten =>`/`Dial()` à mão
|
||||
(`apps/api/src/outbound-routes/outbound-route-generator.ts`). Gera o
|
||||
contexto `b2bcall-outbound-routes`:
|
||||
```
|
||||
exten => _<prefix><matchPattern>,1,NoOp(...)
|
||||
same => n,Dial(PJSIP/<prepend>${EXTEN:<len(prefix)>}@<tronco>,60)
|
||||
same => n,Hangup()
|
||||
```
|
||||
e inclui esse contexto em `[b2bcall-agents]` (contexto padrão de
|
||||
`Extension.context`), para que a discagem manual de um agente já passe
|
||||
pelas rotas sem configuração extra. O prefixo é **sempre** removido do
|
||||
número antes de discar e substituído pelo prepend — o tronco nunca vê o
|
||||
prefixo que o agente digitou, só o número já mascarado. Publicado e
|
||||
versionado junto com `DialplanEntry` pelo mesmo `DialplanService.publish()`
|
||||
(mesma validação `dialplan show`/rollback automático). Não usado pelo
|
||||
discador preditivo — campanhas já sabem o tronco diretamente via
|
||||
`Campaign.trunkId`, sem precisar casar padrão.
|
||||
- `infrastructure/asterisk/config/queues.conf` inclui
|
||||
`/etc/asterisk-generated/b2bcall-queues.conf` — gerado a partir de
|
||||
`Queue` (Postgres). **Membros nunca são estáticos** — adicionados/
|
||||
|
||||
Reference in New Issue
Block a user