Concepts

Architecture

How the moving parts fit together and which job each one does.

Stack at a glance

  • Backend — FastAPI (Python 3.12+) exposing REST endpoints and two SSE streams. LangGraph drives the seven-agent pipeline with a Redis checkpointer.
  • Frontend — Next.js 16 (App Router) + TypeScript. The Issue detail view consumes the pipeline SSE to render the run in real time.
  • PostgreSQL — durable business data: users, repositories, issues, pipeline steps and the structural code map (symbols + edges).
  • Redis — LangGraph checkpoints, SSE pub/sub channels, and a capped event-replay buffer.
  • Qdrant — vector store: embeddings of code symbols and embeddings of past issues for the few-shot retriever.
  • External APIs — Anthropic (Claude Sonnet 4.6 and Haiku 4.5), OpenAI (text-embedding-3-small) and GitHub (OAuth + REST).

C4 Level 2 Diagram

C4 container diagram of the Issue to Code system, showing the Next.js frontend, the FastAPI backend (LangGraph orchestrator and indexer service), Postgres, Redis, Qdrant, and the external APIs (GitHub, Anthropic, OpenAI).

What the indexer does

When the user adds a repository, the indexer clones it shallowly, parses every supported file with tree-sitter and extracts structural information at the symbol level (functions, classes, components). It builds a code map in Postgres (code_symbols, code_edges) and generates one embedding per symbol in Qdrant. The temporary clone is removed as soon as the run finishes — we never persist source code.

The Locator later combines semantic search (top-K in Qdrant) with a graph expansion (callers, callees, same-file siblings) so it can return both lexically similar code and code that is contextually relevant.

Multi-tenant isolation

Every query to Postgres and Qdrant is keyed by the authenticated user's id. Qdrant collections are named code_{user_id}_{repo_id} and issues_{user_id}; the service layer never exposes these names to the frontend. Postgres queries always filter by user_id at the service layer. Row-Level Security is not enabled in the MVP.