Overview
The client operates a sales/support call center and was drowning in raw audio. Recordings landed on an FTP server, but supervisors had no way to know — without listening to hundreds of MP3s per day — which calls were good, which violated the script, or which customers were unhappy.
They needed a single internal web application that would automatically ingest every call from their telephony provider, transcribe it, evaluate it against a configurable list of quality questions, and present the results in a fast, filterable dashboard their managers could actually work with.

My Contribution
I designed and built the entire system end-to-end in Go.
Backend & Pipeline
A webhook endpoint (POST /call) ingests call metadata pushed by the telephony provider and enqueues background jobs. Five independent background workers, each backed by a database-driven queue with pending → done / failed status tracking, attempt counters, retry logic, and per-job error capture:
- Duration worker — connects to the client’s FTP server, streams the MP3, and extracts true audio duration.
- Transcription worker — sends audio to AssemblyAI and stores the transcript with a “too-short” guard.
- AI evaluation worker — composes a prompt from the transcript plus a dynamic list of quality questions managed from the UI, calls OpenAI, validates the structured JSON response, and stores it with a hash for change detection (so re-evaluation only happens when inputs actually change).
- Webhook log cleanup worker — applies configurable retention.
- Error log cleanup worker — same, for error history.
Web App
- HTTP layer built on Echo v4 with a clean handler → service → repository split.
- Server-side rendered UI using Templ (compiled, type-safe Go templates) — no SPA overhead, fast first paint.
- DataTables with full server-side processing (pagination, filtering, sorting done in PostgreSQL, not the browser) for the calls table and webhook log table.
- Per-user column visibility persisted in the database, so each manager sees their own preferred view.
- Role-based access control (admin / regular user), Redis-backed sessions via
scs, secure password change flow. - In-app settings UI for AssemblyAI keys, OpenAI model/parameters, AI questions, and log retention — no redeploys needed to tune the pipeline.
- Built-in MP3 audio playback proxied from FTP, so managers can listen to a call right next to its transcript and AI score.

Infrastructure
- PostgreSQL (
sqlx) with 25+ versioned migrations applied automatically on startup viagolang-migrate. - Redis for sessions.
- Docker Compose for local development; single binary for production.
- Timezone-aware (Europe/Kyiv), structured logging via
logrus.

In-App Configuration
Every part of the pipeline is tunable from the UI — no redeploys. Supervisors manage AssemblyAI keys, OpenAI model parameters, minimum audio duration, transcription routes, and log retention directly in the settings screen.

The list of AI quality questions is itself a CRUD-managed entity. Adding a new criterion (“did the operator greet?”, “was a conflict raised?”, “was a TG-bot proposed?”) takes seconds: type it into the questions UI, and the next batch of calls is evaluated against it.

Technical Stack
| Layer | Technology |
|---|---|
| Language | Go (Golang) |
| HTTP framework | Echo v4 |
| UI rendering | Templ (compiled, type-safe Go templates) |
| Database | PostgreSQL with sqlx, 25+ versioned migrations via golang-migrate |
| Sessions | Redis (via scs) |
| AI / ML | OpenAI API, AssemblyAI |
| Integration | FTP audio ingestion, telephony webhooks |
| Frontend interactivity | DataTables with server-side processing |
| Infrastructure | Docker Compose, single-binary production deploy |
| Observability | Structured logging via logrus, timezone-aware (Europe/Kyiv) |
Outcome
The client replaced hours of manual call listening with an automated pipeline that processes every recorded call within minutes of it landing on FTP.
- Supervisors now open a single dashboard, filter by date, agent, or AI verdict, and drill straight into a transcript with per-question scoring.
- Adding a new quality criterion takes seconds — they type the question into the settings UI and the next batch of calls is evaluated against it.
- The platform has been running reliably in production and is the team’s primary tool for call quality review.