collabSupport/services
Joseph McQueen 96b26a5aca DECT relay Phase 1: WSS hub + agent + /phonestatus follow-up
The bot runs in the public cloud and can't reach the 10.x/8 network
where DBS-210 bases live. This phase adds a data-center-resident relay
agent that dials outbound over WSS to the bot, and lets /phonestatus
post a follow-up message with per-base health after its main output
has already shipped.

Bot side (services/):
- dectRelayHub.js: WebSocket upgrade handler on /dect-relay/ws with
  bearer-token auth (constant-time compare, header + Sec-WebSocket-
  Protocol fallback for header-stripping proxies). Promise-based RPC
  API with per-call timeouts, mid-flight-disconnect rejection, and
  clean replacement of a stale agent socket when a newer one connects.
- dectDiscovery.js: pure filter that turns a phoneService result into
  a list of reachable bases. Enforces the "must be on 10.0.0.0/8"
  guardrail per requirements, dedups by IP + MAC, prefers Meraki-live
  IP over Webex-cached IP.
- dectCollectorService.js: fan-out layer over the hub. collectAll()
  runs one RPC per base in parallel with per-base error isolation —
  one bad base never fails the batch.

Phone-status integration:
- Renderer gets a dectFollowUpBaseCount opt that emits an italic
  "diagnostics loading for N base(s)..." hint inside the DECT section
  of the main message.
- New exported renderDectDiagnosticsMarkdown() renders the follow-up
  message: healthy/warning icon per base, uptime + firmware summary,
  structured Power Loss reboot line, and per-base failure hints (e.g.
  "relay accepted the request but the base did not respond in time").
- commands/phoneStatus.js discovers reachable bases synchronously
  (pure), sends the main message, then fires collectAll() and posts
  the follow-up as a separate message. Failures logged, never thrown
  back to the user.
- Chat only: HTTP callers keep their single-message contract.

Agent side (dect-relay-agent/):
- Standalone Node process with its own package.json (only ws, axios,
  dotenv). Reuses the shared integrations/cisco-dect/{client,probes,
  statusXml}.js modules from the parent workspace so there's no code
  duplication.
- Auto-reconnect with exponential backoff + jitter.
- Dispatches collect / reboot / force-reboot / reboot-chain /
  force-reboot-chain / factory-reset / reconfigure-tree.
- DECT admin credentials live ONLY on the agent (never on the bot).
  Shared bearer token gates the WSS handshake.
- README.md covers install, config, wire protocol, and safety model.

Env / infra:
- .env.example: adds DECT_RELAY_AGENT_TOKEN + optional DECT_RELAY_PATH
  and DECT_COLLECT_TIMEOUT_MS. Reframes DECT_TEST_* as the local-dev
  test harness rather than the production path.
- index.js: captures the http.Server from app.listen() and attaches
  the relay hub when DECT_RELAY_AGENT_TOKEN is set; graceful shutdown
  now closes the hub so in-flight RPCs get rejected cleanly.
- Adds "ws" to bot dependencies.

Tests (99 -> 113):
- tests/dectDiscovery.test.js: 13 cases covering the 10.x guardrail,
  MAC normalization, IP source preference, dedup, and warning shape.
- tests/dectRelayHub.test.js: 14 integration cases using a real
  ws pair on an ephemeral 127.0.0.1 port — auth (missing / wrong /
  correct via header / correct via protocol fallback), hello frame,
  RPC round-trip with correlation, agent error surfacing, concurrent
  out-of-order replies, timeout, mid-flight disconnect, replacement
  of a stale socket, and execAction routing.
- tests/renderers.test.js: 8 new cases for the DECT-follow-up loading
  hint (plural / singular / off) and the diagnostics renderer (empty,
  healthy, warning, power-loss dedup, active RTP, error hint, footer).
2026-07-02 17:03:32 -04:00
..
enrichment Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
renderers DECT relay Phase 1: WSS hub + agent + /phonestatus follow-up 2026-07-02 17:03:32 -04:00
avDeviceBuilder.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
avDeviceService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
avEnricher.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
avModalService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
dectCollectorService.js DECT relay Phase 1: WSS hub + agent + /phonestatus follow-up 2026-07-02 17:03:32 -04:00
dectDiscovery.js DECT relay Phase 1: WSS hub + agent + /phonestatus follow-up 2026-07-02 17:03:32 -04:00
dectRelayHub.js DECT relay Phase 1: WSS hub + agent + /phonestatus follow-up 2026-07-02 17:03:32 -04:00
deviceService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
jiraPollerService.js Tag skipped Jira tickets with bot-skipped label 2026-07-01 17:14:17 -04:00
jiraService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
jiraSummarizer.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
phoneDeviceBuilder.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
phoneService.js Detect and inline-remediate Meraki IGMP snooping in /phonestatus 2026-07-02 14:10:33 -04:00
ticketClassifier.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
vcMonitorService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
vcProvisionService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
webhookService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00
woService.js Initial commit: CollabFinder Webex bot 2026-07-01 16:55:03 -04:00