Skip to content

feat(insights): voice usage monitors (minutes, calls, connection rates, durations) - #45

Merged
kshahbw merged 5 commits into
mainfrom
feat/insights-monitors
Aug 25, 2026
Merged

feat(insights): voice usage monitors (minutes, calls, connection rates, durations)#45
kshahbw merged 5 commits into
mainfrom
feat/insights-monitors

Conversation

@kshahbw

@kshahbw kshahbw commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

What

New band insights group: read-only voice usage/quality aggregates from the Insights Monitoring API (insights.bandwidth.com).

Command Endpoint
insights minutes-of-use /v1/monitors/voice/minutes-of-use
insights completed-calls /v1/monitors/voice/completed-calls
insights failed-calls /v1/monitors/voice/failed-calls
insights connection-rates /v1/monitors/voice/connection-rates
insights average-durations /v1/monitors/voice/average-durations

Shared filters: --to/--from (comma-separated E.164), --direction, --call-type (accepts TOLLFREE-IN or TOLLFREE_IN), --subaccount, --since/--until (RFC3339 or relative 30d/24h/90m; API defaults to the last 7 days). Results are time slices whose granularity the API scales with the window.

Why

Completes the usage half of the number-inspection story: PR #44 answers "how is this number configured/routed", this answers "how much traffic does it carry" — per-number minutes, call counts, answer rates, and ACD, isolatable to toll-free ingress via --call-type TOLLFREE-IN.

Design notes

  • New cmdutil.InsightsClient — single prod host, BW_INSIGHTS_URL override, standard OAuth Bearer (accepted, verified live).
  • deepObject query encoding per spec (accountId[eq], timestamp[gte/lte], …).
  • Monitoring-feature 403 → actionable "not enabled on account" message, exit 2 — same gate pattern as tollfree template and portin TF automation.
  • v1 covers the five traffic-profile monitors; the API's other six (cps, concurrent-calls, error-percentages, NER, short-calls, call-data) drop into the same table when wanted.

Validation

  • go test ./... green; live prod probes: Bearer token accepted by the Insights host, query encoding accepted (no 400), feature-gate 403 → exit 2 with mapped message, flag validation → exit 6 pre-HTTP. Happy path needs a Monitoring-enabled account (none available to this credential); envelope unwrap is unit-tested against spec examples and passes unexpected shapes through raw.

Stacking

Based on feat/number-reads-tollfree (PR #44) — retarget to main after #44 lands. #44 merged; rebased onto main.

This PR was substantially AI-generated (Claude Code), reviewed and directed by @kshahbw.

🤖 Generated with Claude Code

@kshahbw
kshahbw requested review from a team as code owners August 24, 2026 20:34
@bwappsec

bwappsec commented Aug 24, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

joshraub-bw
joshraub-bw previously approved these changes Aug 25, 2026
achandras
achandras previously approved these changes Aug 25, 2026
@kshahbw
kshahbw disabled auto-merge August 25, 2026 15:18
Base automatically changed from feat/number-reads-tollfree to main August 25, 2026 15:21
@kshahbw
kshahbw dismissed stale reviews from achandras and joshraub-bw August 25, 2026 15:21

The base branch was changed.

…s, durations)

Add band insights — read-only usage/quality aggregates from the Insights
Monitoring API, answering 'how much traffic does this number carry?':

- insights minutes-of-use | completed-calls | failed-calls |
  connection-rates | average-durations, all sharing the same filters:
  --to/--from (comma-separated E.164), --direction, --call-type
  (dash or underscore forms accepted, e.g. TOLLFREE-IN), --subaccount,
  and --since/--until (RFC3339 or relative shorthand: 30d, 24h, 90m)
- new InsightsClient against insights.bandwidth.com (single prod host,
  BW_INSIGHTS_URL override); the standard OAuth Bearer token is accepted
  (verified live)
- deepObject query encoding per the API spec (accountId[eq],
  timestamp[gte/lte], toPhoneNumber[eq], ...)
- the Monitoring-feature 403 maps to an actionable message (exit 2),
  same pattern as the toll-free template gate

Live-probed against production: token acceptance, query encoding, the
feature-gate 403 mapping, and flag validation (exit 6). Happy path needs
a Monitoring-enabled account; envelope unwrapping is unit-tested against
spec examples and passes unexpected shapes through raw.
…lidate-before-auth, relative-time bounds

Review findings from an independent pass:

- Insights is production-only, but the token was minted per --environment:
  an active test profile produced a test-realm token that the prod
  Insights host rejects with 401. Mint against prod and warn on non-prod
  environments, mirroring MessagingClient.
- --call-type now validates against the API enum after normalization
  (--call-type banana was reaching the server as BANANA and returning a
  400 instead of a local flag error).
- Flag validation moved before authentication so misuse exits 6
  deterministically regardless of login state (repo pattern).
- Relative time shorthand is bounded at 400d: the API keeps one year of
  history, and unbounded values overflowed time.Duration into future
  timestamps (e.g. 106752d).
@kshahbw
kshahbw force-pushed the feat/insights-monitors branch from 988365a to 0bb6f81 Compare August 25, 2026 15:26
joshraub-bw
joshraub-bw previously approved these changes Aug 25, 2026
ckoegel
ckoegel previously approved these changes Aug 25, 2026
Merging main brought in the context.Context client migration; pass
cmd.Context() at the insights call site like the rest of the tree.
@kshahbw
kshahbw dismissed stale reviews from ckoegel and joshraub-bw via e7baea5 August 25, 2026 17:45
@kshahbw
kshahbw merged commit b63720e into main Aug 25, 2026
8 checks passed
@kshahbw
kshahbw deleted the feat/insights-monitors branch August 25, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants