PostgreSQL — the source of truth
Everything structured lives here: users, workspaces, sessions, transcripts, jobs, summaries, speaker identities. If you need to understand “what happened in session X”, the answer is in Postgres. Key tables:
Why Postgres? Relational integrity matters here — a transcript belongs to a job, a job belongs to a session, a session belongs to a workspace. Foreign keys and transactions prevent orphaned records.
Redis — queues & real-time
Redis serves two roles:1. Job queue
When a chunk is uploaded, the API pushes a job onto a Redis list. The transcription worker pops from that list and processes the job. This decouples the HTTP request (fast, returns immediately) from the actual transcription work (slow, runs in the background).2. WebSocket pub/sub & recording status
Live session state (is a recording active? who’s recording?) is stored in Redis with a TTL. The web app subscribes via WebSocket; the API publishes status changes so the UI updates without polling.Neo4j — knowledge graph (HiRAG)
After a session is transcribed and summarised, the HiRAG worker indexes it into a Neo4j graph. Entities (people, topics, concepts) become nodes; relationships between them become edges. This powers the “ask a question across all sessions” feature — instead of searching raw text, the moderator queries a structured graph of what was discussed and by whom. Why Neo4j? Graph traversal queries (“find all concerns related to entity X across sessions Y and Z”) are natural in Cypher but painful in SQL.Neo4j is only populated after HiRAG indexing completes. A session must be transcribed and summarised first. If HiRAG is disabled in config, this store is unused.