Webhook controller now skips outbound calls (type=Manual/OutBound).
An unanswered outbound dial is NOT a missed inbound call — it was
being incorrectly created as MISSED with PENDING_CALLBACK status.
MissedQueueService now filters the Ozonetel abandonCalls API response
by campaign name (read from TelephonyConfigService). Prevents
cross-tenant ingestion when multiple sidecars share the same
Ozonetel account.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Defect 5: Worklist, missed-call-webhook, missed-queue, ai-chat, and
rules-engine all used legacy lowercase field names (callbackstatus,
callsourcenumber, missedcallcount, callbackattemptedat) from the old
VPS schema. Fixed to camelCase (callbackStatus, callSourceNumber,
missedCallCount, callbackAttemptedAt) matching the current SDK sync.
Defect 6: Dial endpoint used global defaults (OZONETEL_AGENT_ID env
var) instead of the logged-in agent's config. Now accepts agentId
and campaignName from the frontend request body. Falls back to
telephony config → DID-derived campaign name → explicit error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SSE agent state stream: supervisor maintains state map from Ozonetel webhooks, streams via /api/supervisor/agent-state/stream
- Force-logout via SSE: distinct force-logout event type avoids conflict with normal login cycle
- Maint module (/api/maint): OTP-guarded endpoints for force-ready, unlock-agent, backfill-missed-calls, fix-timestamps
- Fix Ozonetel IST→UTC timestamp conversion: istToUtc() in webhook controller and missed-queue service
- Missed call lead lookup: ingestion queries leads by phone, stores leadId + leadName on Call entity
- Timestamp backfill endpoint: throttled at 700ms/mutation, idempotent (skips already-fixed records)
- Structured logging: full JSON payloads for agent/call webhooks, [DISPOSE] trace with agentId
- Fix dead code: agent-state endpoint auto-assign was after return statement
- Export SupervisorService for cross-module injection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MissedQueueService: polls Ozonetel abandonCalls every 30s, dedup by phone
- Auto-assigns oldest PENDING_CALLBACK call on agent Ready (dispose + state change)
- GET /api/worklist/missed-queue, PATCH /api/worklist/missed-queue/:id/status
- Worklist query updated with callback fields and FIFO ordering
- PlatformGraphqlService.query() made public for server-to-server ops
- forwardRef circular dependency resolution between WorklistModule and OzonetelAgentModule
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>