- Shipped
- April 24, 2026 at 10:39 PM UTC
- Author
- Kamo
- Commit
- 3bc4f64
Per-instance resource CRUD (extensions / users / devices / voicemail): - VoipExtensionsController at **************** - VoipUsersController at /api/voip/instances/{id}/users - VoipDevicesController at **************** - VoipVoicemailController at **************** - Every GET accepts ?refresh=true to force-fetch from provider and refresh cache; otherwise serves from local cache for snappy UI. - Every write path calls provider AND upserts local cache so the aggregated views stay consistent without waiting for the next scheduled sync. - Voicemail GET /{vmId}/audio streams the raw audio from the provider via StreamingResponseBody so the UI can <audio src=...> it directly. Org-aggregate (VoipOrgAggregateController at /api/voip/org): - /extensions, /users, /devices, /voicemails return rows across every instance with {instanceId, instanceName} pills. UI renders these into the aggregated tabs in /settings/features/phone. - /health runs checkHealth() on every active instance in parallel per-instance (via InstanceSyncService's cached counts), returns InstanceHealthDto[]. - POST /sync runs InstanceSyncService against every active instance of the current org. Powers the tenant-level "Sync this org now" button in the UI. Internal sync (VoipInternalSyncController): - POST /internal/voip/sync-global loops all active instances platform-wide. Called by DaemonService's scheduled Quartz job. Protected by the existing InternalAuthFilter in VOIPService. Builds green.