feat(ai): pipeline assincrono — transcricao, analise, prompts (fase 20)

Sub-fase B do modulo de IA: novo servico apps/ai-worker (poll + FOR UPDATE
SKIP LOCKED) processa AIJob de TRANSCRIPTION/ANALYSIS disparados
automaticamente apos uma gravacao ficar disponivel, respeitando a cascata
de privacidade Tenant>Queue>Campaign e o entitlement do Plan. Transcricao
separa o WAV estereo em 2 canais (parser proprio, sem ffmpeg) e transcreve
cada perna independente; analise sempre redige dados sensiveis antes de
sair pro provider e valida o resultado contra o schema antes de persistir.
CRUD de AIPromptTemplate/AIPromptVersion em apps/api.

Testado ponta a ponta contra o worker real em Docker e Postgres real com
RLS (cascata de privacidade em 3 cenarios, WAV sintetico real no object
storage, claim/retry/dead-letter reais) — chamada de rede contra
OpenAI/Anthropic continua nunca exercitada (mesma restricao de rede desde
o Provider Layer). Detalhes em docs/AI_PIPELINE.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X1HxY46WGU4G1zmVDNKcWw
This commit is contained in:
2026-08-28 16:39:38 -03:00
parent 7597b35454
commit 91c0448dd4
29 changed files with 1427 additions and 5 deletions

31
pnpm-lock.yaml generated
View File

@@ -12,6 +12,31 @@ importers:
specifier: ^5.9.3
version: 5.9.3
apps/ai-worker:
dependencies:
'@b2bcall/ai':
specifier: workspace:*
version: link:../../packages/ai
'@b2bcall/database':
specifier: workspace:*
version: link:../../packages/database
'@b2bcall/shared':
specifier: workspace:*
version: link:../../packages/shared
'@b2bcall/storage':
specifier: workspace:*
version: link:../../packages/storage
devDependencies:
'@types/node':
specifier: ^22.0.0
version: 22.20.1
tsx:
specifier: ^4.23.12
version: 4.23.12
typescript:
specifier: ^5.7.0
version: 5.9.3
apps/api:
dependencies:
'@b2bcall/ai':
@@ -127,9 +152,15 @@ importers:
apps/freeswitch-events:
dependencies:
'@b2bcall/ai':
specifier: workspace:*
version: link:../../packages/ai
'@b2bcall/database':
specifier: workspace:*
version: link:../../packages/database
'@b2bcall/entitlements':
specifier: workspace:*
version: link:../../packages/entitlements
'@b2bcall/shared':
specifier: workspace:*
version: link:../../packages/shared