feat: dual-provider STT routing for IMBE + audio fallback (#7)#51
Open
LumenPrima wants to merge 13 commits into
Open
feat: dual-provider STT routing for IMBE + audio fallback (#7)#51LumenPrima wants to merge 13 commits into
LumenPrima wants to merge 13 commits into
Conversation
- storage: LocalStore tests (save/open round-trip, nested dirs, atomic writes, path traversal security, Exists, LocalPath, URL, Type, Dir, NotFound) - trconfig: LoadConfig, LoadVolumeMap, Discover tests - 2 new test files, 0 regressions across full suite
Bubble Scatter, Calendar Heatmap, Daily Overview (treemap), Emergency Log, Recorder Gauges, TG Sunburst, Traffic & Patterns, Unit Tracker — all registered via card-title/description/order meta tags. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
migrating-auth.md covers the v0.9.8 auth simplification (AUTH_ENABLED deprecated, three-mode auto-detection). glossary-research.md captures PostgreSQL-based phonetic/fuzzy lookup strategy for ASR post-correction. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ards
All GET /api/v1/{systems,calls,recorders} responses are wrapped objects
({systems:[],total} etc.), not plain arrays — pages were iterating the
object directly and displaying no data.
Bugs fixed per page:
- bubble-scatter: unwrap systems/calls; tg_alpha_tag (was tgid_alpha_tag); tg_tag (was tag)
- calendar-heatmap: unwrap systems/calls
- daily-overview: unwrap systems/calls; fix unconditional j-- causing infinite loop;
d.depth===2 for TG leaves (was d.height===2 which selected root); tg_alpha_tag; tg_tag
- tg-sunburst: unwrap systems/calls; tg_alpha_tag (was tgid_alpha_tag)
- recorder-gauges: unwrap recorders and systems
- emergency-log: fix JS syntax error (bare var(--accent) as expression); system name
field (name not system_name); wire up trend chart on init
- traffic-patterns: system name field; call-heatmap uses days param (not hours, max 90)
- unit-tracker: unit_alpha_tag (was alpha_tag); var declaration in strict mode
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Add POST /debug-report (was implemented but missing from spec)
- Add DELETE /users/all with danger notice (bulk delete, admin only)
- Fix /admin/transcribe-backfill path param: {job_id} -> {id} to match code
- go test -race passes clean (zero DATA RACE) - golangci-lint v1.64.8 with govet/staticcheck/errcheck/unused - gates new code only via --new-from-rev HEAD~1
- GET /api/v1/recent-events: UNION of calls + unit_events with filters - GET /api/v1/dashboard/summary: aggregated health/stats/active/top-TG - Audio Range support (200/206/416) via http.ServeContent - OpenAPI specs for all three endpoints - Tests for handlers and audio status codes
…nto UI - Call history: transcript search wired to server-side /transcriptions/search - Call history: draggable seek handle with buffered range visualization - Events page: pre-populate from /recent-events before SSE connects - Signal Flow: surface query 403 errors instead of silent degradation - POST /api/v1/query: explicit QueryAdminOnly middleware with clear 403
…and Playwright smoke tests - docs/quickstart.md: Docker Compose → ingest → UI in 5 minutes - docs/tr-timing-behavior.md: call ID shifts, unit_event:end lag, mitigations - docs/release-notes.md: v0.10.0 release notes with features/fixes/upgrade notes - tests/: Playwright smoke suite (8 tests) against deployed instance
W1: Refresh token rotation — JTI-based rotation with reuse detection - New migration adds refresh_token_jti column to users table - Refresh handler validates JTI, rejects reused tokens with 401 - Logout clears stored JTI before expiring cookie W2: rewriteInstanceID() — replace fragile byte-level JSON with json.Unmarshal/json.Marshal round-trip, preventing false matches on keys like my_instance_id W3: AGENTS.md — fix fuzzy match tolerance documentation (±5s → ±10s) W4: AuthRateLimiter — fix goroutine leak via time.NewTicker with ctx.Done() select, ShutdownCtx propagated from main W5: Middleware chain — swap RateLimiter/Recoverer order so panics in rate limiter are caught by Recoverer
When STT_PROVIDER=imbe, analog/conventional calls previously got no transcription. Add STT_FALLBACK_PROVIDER so .dvcf jobs go to IMBE and non-DVCF audio jobs route to a second worker pool (whisper/elevenlabs/ deepinfra). Backfill and re-transcribe use the same path-based routing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
STT_FALLBACK_PROVIDERso mixed P25 + analog systems can use IMBE for.dvcfand an audio STT (whisper/elevenlabs/deepinfra) for everything elsesample.env, README, and AGENTS; unit tests cover routing edge casesCloses #7
Config example
Without a fallback, IMBE-only behavior is unchanged (audio enqueue sites no-op; only
handleDvcfenqueues).Test plan
go test ./internal/ingest/ ./internal/transcribe/go vet ./...bash build.sh