# wibwl/direkt-calltrainer architecture

> Architecture diagram of the GitHub repository wibwl/direkt-calltrainer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/wibwl/direkt-calltrainer
- Repository: https://github.com/wibwl/direkt-calltrainer
- Video tour (about a minute): https://gitdiagram.com/wibwl/direkt-calltrainer/video

## Overview

Calltrainer lets an authenticated user configure a phone-call practice from a Persona and Scenario, talk to an AI counterpart in a live audio session, then review generated feedback and progress. Its principal path is browser setup → WebSocket conversation (speech recognition, dialogue, speech synthesis) → saved session → asynchronous feedback → history and progress views. The graph preserves the documented scenario authoring, focus, follow-up/reverse, consent, and account capabilities. Several subsystem links are based on the README and source tree; unsampled implementation details are not asserted.

Main entry points: [`backend/api/session_ws.py`](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/api/session_ws.py) (Session WebSocket), [`backend/feedback/generator.py`](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/generator.py) (Feedback analysis), [`backend/app.py`](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/app.py) (FastAPI app), [`frontend/src/App.tsx`](https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/App.tsx) (Training flow)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Web application"]
  node_frontend["React app<br/>[main.tsx]"]
  node_training["Training flow<br/>[App.tsx]"]
  node_live_socket["Session socket"]
  node_history_progress["History and progress<br/>[ProgressView.tsx]"]
end

subgraph group_api["API and session runtime"]
  node_api_app["FastAPI app<br/>[app.py]"]
  node_catalog_api["Catalog and setup APIs"]
  node_session_api["Session WebSocket<br/>[session_ws.py]"]
  node_orchestrator["Turn orchestrator<br/>[orchestrator.py]"]
  node_session_persistence["Session persistence<br/>[persistence.py]"]
end

subgraph group_ai["Speech and dialogue"]
  node_ai_clients["Speech and LLM clients"]
  node_gateway["DiReKT model gateway"]
end

subgraph group_feedback["Feedback processing"]
  node_feedback_jobs["Feedback jobs<br/>[jobs.py]"]
  node_feedback_worker["Feedback worker<br/>[worker.py]"]
  node_feedback_generator["Feedback analysis<br/>[generator.py]"]
  node_feedback_metrics["Speech metrics<br/>[metrics.py]"]
end

subgraph group_state["Identity and state"]
  node_database[("PostgreSQL<br/>[session.py]")]
  node_queue["Redis queue<br/>[queue.py]"]
  node_identity["Keycloak"]
end

node_user(("Trainee"))

node_user -->|"uses"| node_frontend
node_frontend -->|"authenticates"| node_identity
node_frontend -->|"opens training"| node_training
node_training -->|"loads setup"| node_catalog_api
node_training -->|"starts session"| node_live_socket
node_live_socket -->|"sends audio and control"| node_session_api
node_api_app -->|"mounts route"| node_session_api
node_api_app -->|"mounts routes"| node_catalog_api
node_session_api -->|"drives turns"| node_orchestrator
node_orchestrator -->|"transcribes, generates, speaks"| node_ai_clients
node_ai_clients -->|"calls models"| node_gateway
node_session_api -->|"stores session"| node_session_persistence
node_session_persistence -->|"reads and writes"| node_database
node_session_api -->|"enqueues wrap-up"| node_feedback_jobs
node_feedback_jobs -->|"dispatches job"| node_queue
node_feedback_worker -->|"consumes jobs"| node_queue
node_feedback_worker -->|"runs analysis"| node_feedback_generator
node_feedback_generator -->|"uses measurements"| node_feedback_metrics
node_feedback_generator -->|"requests feedback"| node_ai_clients
node_feedback_generator -->|"stores feedback"| node_database
node_history_progress -->|"requests records"| node_api_app
node_api_app -->|"serves stored data"| node_database
node_history_progress -->|"starts follow-up or reverse"| node_training

click node_frontend "https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/main.tsx"
click node_training "https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/App.tsx"
click node_live_socket "https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/hooks/useSessionSocket.ts"
click node_history_progress "https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/components/ProgressView.tsx"
click node_api_app "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/app.py"
click node_catalog_api "https://github.com/wibwl/direkt-calltrainer/tree/main/backend/api"
click node_session_api "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/api/session_ws.py"
click node_orchestrator "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/session/orchestrator.py"
click node_session_persistence "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/session/persistence.py"
click node_ai_clients "https://github.com/wibwl/direkt-calltrainer/tree/main/backend/clients"
click node_feedback_jobs "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/jobs.py"
click node_feedback_worker "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/worker.py"
click node_feedback_generator "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/generator.py"
click node_feedback_metrics "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/metrics.py"
click node_database "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/db/session.py"
click node_queue "https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/queue.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_frontend,node_training,node_live_socket,node_history_progress toneBlue
class node_api_app,node_catalog_api,node_session_api,node_orchestrator,node_session_persistence toneAmber
class node_ai_clients,node_gateway toneMint
class node_feedback_jobs,node_feedback_worker,node_feedback_generator,node_feedback_metrics toneRose
class node_database,node_queue,node_identity,node_user toneIndigo
```

## Components

### Web application

- [React app](https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/main.tsx): `frontend/src/main.tsx`
- [Training flow](https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/App.tsx): `frontend/src/App.tsx`
- [Session socket](https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/hooks/useSessionSocket.ts): `frontend/src/hooks/useSessionSocket.ts`
- [History and progress](https://github.com/wibwl/direkt-calltrainer/blob/main/frontend/src/components/ProgressView.tsx): `frontend/src/components/ProgressView.tsx`

### API and session runtime

- [FastAPI app](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/app.py): `backend/app.py`
- [Catalog and setup APIs](https://github.com/wibwl/direkt-calltrainer/tree/main/backend/api): `backend/api`
- [Session WebSocket](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/api/session_ws.py): `backend/api/session_ws.py`
- [Turn orchestrator](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/session/orchestrator.py): `backend/session/orchestrator.py`
- [Session persistence](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/session/persistence.py): `backend/session/persistence.py`

### Speech and dialogue

- [Speech and LLM clients](https://github.com/wibwl/direkt-calltrainer/tree/main/backend/clients): `backend/clients`
- **DiReKT model gateway**

### Feedback processing

- [Feedback jobs](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/jobs.py): `backend/feedback/jobs.py`
- [Feedback worker](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/worker.py): `backend/worker.py`
- [Feedback analysis](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/generator.py): `backend/feedback/generator.py`
- [Speech metrics](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/metrics.py): `backend/feedback/metrics.py`

### Identity and state

- [PostgreSQL](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/db/session.py): `backend/db/session.py`
- [Redis queue](https://github.com/wibwl/direkt-calltrainer/blob/main/backend/feedback/queue.py): `backend/feedback/queue.py`
- **Keycloak**

### Other components

- **Trainee**

## Connections

- Trainee → React app: uses
- React app → Keycloak: authenticates
- React app → Training flow: opens training
- Training flow → Catalog and setup APIs: loads setup
- Training flow → Session socket: starts session
- Session socket → Session WebSocket: sends audio and control
- FastAPI app → Session WebSocket: mounts route
- FastAPI app → Catalog and setup APIs: mounts routes
- Session WebSocket → Turn orchestrator: drives turns
- Turn orchestrator → Speech and LLM clients: transcribes, generates, speaks
- Speech and LLM clients → DiReKT model gateway: calls models
- Session WebSocket → Session persistence: stores session
- Session persistence → PostgreSQL: reads and writes
- Session WebSocket → Feedback jobs: enqueues wrap-up
- Feedback jobs → Redis queue: dispatches job
- Feedback worker → Redis queue: consumes jobs
- Feedback worker → Feedback analysis: runs analysis
- Feedback analysis → Speech metrics: uses measurements
- Feedback analysis → Speech and LLM clients: requests feedback
- Feedback analysis → PostgreSQL: stores feedback
- History and progress → FastAPI app: requests records
- FastAPI app → PostgreSQL: serves stored data
- History and progress → Training flow: starts follow-up or reverse
