# emiber/utdt architecture

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

- Interactive diagram: https://gitdiagram.com/emiber/utdt
- Repository: https://github.com/emiber/utdt

## Overview

UTDT is a Vue-and-Fastify text-to-SQL chatbot. A user supplies the shared access key, explores the available data, then submits a question; the backend classifies it, generates and executes read-only SQL, builds narrative and chart/table blocks, and returns the answer. Follow-up context and LLM-call records persist in the app database; the UI also offers a usage report. The graph preserves the documented catalog, multi-result answers, conversational replies, and usage features. Some subsystem links use README evidence because their implementations were not excerpted.

Main entry points: [`backend/src/pipeline.ts`](https://github.com/emiber/utdt/blob/main/backend/src/pipeline.ts) (Answer pipeline), [`frontend/src/api.ts`](https://github.com/emiber/utdt/blob/main/frontend/src/api.ts) (API client), [`backend/src/app.ts`](https://github.com/emiber/utdt/blob/main/backend/src/app.ts) (Route assembly), [`backend/src/llm.ts`](https://github.com/emiber/utdt/blob/main/backend/src/llm.ts) (LLM adapter)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web interface"]
  node_appui["App shell<br/>[App.vue]"]
  node_keyui["Key entry<br/>[AccessKeyForm.vue]"]
  node_authui["Key state<br/>[auth.ts]"]
  node_chatui["Chat view<br/>[ChatView.vue]"]
  node_blocks["Answer blocks<br/>[ResponseBlocks.vue]"]
  node_chartui["Chart display<br/>[ChartBlock.vue]"]
  node_catalogui["Data catalog view<br/>[DataCatalog.vue]"]
  node_usageui["Usage view<br/>[UsageView.vue]"]
  node_apiclient["API client<br/>[api.ts]"]
end

subgraph group_api["API and state"]
  node_server["HTTP server<br/>[server.ts]"]
  node_routes["Route assembly<br/>[app.ts]"]
  node_chatroute["Chat endpoint<br/>[chat.ts]"]
  node_auth["Request authentication<br/>[auth.ts]"]
  node_conversations[("Conversation history<br/>[conversations.ts]")]
  node_catalog["Catalog endpoint<br/>[catalog.ts]"]
  node_usage_route["Usage endpoint<br/>[usage-route.ts]"]
  node_metadata[("Data metadata<br/>[metadata.ts]")]
  node_data_db[("Dataset database<br/>[db.ts]")]
end

subgraph group_answer["Question answering"]
  node_pipeline["Answer pipeline<br/>[pipeline.ts]"]
  node_classify["Question classification<br/>[classify.ts]"]
  node_schema["Schema context<br/>[schema-context.ts]"]
  node_sqlgen["SQL generation<br/>[generate-sql.ts]"]
  node_execute["SQL execution<br/>[execute-sql.ts]"]
  node_reply["Text replies<br/>[reply.ts]"]
  node_insights["Result insights<br/>[insights.ts]"]
  node_chart["Chart construction<br/>[chart.ts]"]
end

subgraph group_support["LLM and reporting"]
  node_usage["Usage reporting<br/>[usage.ts]"]
  node_llm["LLM adapter<br/>[llm.ts]"]
  node_prompts["Prompt rendering<br/>[prompts.ts]"]
  node_timing["Call timing<br/>[timing.ts]"]
end

node_user(("User"))
node_openai{{"OpenAI APIs"}}

node_user -->|"enters key"| node_keyui
node_keyui -->|"saves key"| node_authui
node_user -->|"asks question"| node_chatui
node_appui -->|"routes to"| node_chatui
node_appui -->|"shows catalog"| node_catalogui
node_appui -->|"routes to"| node_usageui
node_chatui -->|"requests chat"| node_apiclient
node_catalogui -->|"loads catalog"| node_apiclient
node_usageui -->|"loads report"| node_apiclient
node_apiclient -->|"uses key"| node_authui
node_apiclient -->|"posts question"| node_chatroute
node_apiclient -->|"requests catalog"| node_catalog
node_apiclient -->|"requests report"| node_usage_route
node_blocks -->|"renders chart"| node_chartui
node_chatui -->|"renders answer"| node_blocks
node_server -->|"builds app"| node_routes
node_routes -->|"checks key"| node_auth
node_routes -->|"registers route"| node_chatroute
node_routes -->|"registers route"| node_usage_route
node_routes -->|"serves catalog"| node_catalog
node_chatroute -->|"runs pipeline"| node_pipeline
node_chatroute -->|"loads and saves"| node_conversations
node_catalog -.->|"reads metadata"| node_metadata
node_catalog -.->|"reads dataset"| node_data_db
node_pipeline -->|"builds context"| node_schema
node_pipeline -->|"classifies question"| node_classify
node_pipeline -->|"builds text reply"| node_reply
node_pipeline -->|"generates queries"| node_sqlgen
node_pipeline -->|"builds insights"| node_insights
node_pipeline -.->|"builds charts"| node_chart
node_sqlgen -->|"executes SQL"| node_execute
node_sqlgen -->|"requests SQL"| node_llm
node_classify -->|"requests classification"| node_llm
node_reply -->|"requests reply"| node_llm
node_insights -->|"requests insights"| node_llm
node_sqlgen -->|"renders prompts"| node_prompts
node_pipeline -.->|"uses history types"| node_conversations
node_llm -->|"calls APIs"| node_openai
node_usage_route -.->|"builds report"| node_usage
node_usage -.->|"reads call records"| node_conversations

click node_appui "https://github.com/emiber/utdt/blob/main/frontend/src/App.vue"
click node_keyui "https://github.com/emiber/utdt/blob/main/frontend/src/components/AccessKeyForm.vue"
click node_authui "https://github.com/emiber/utdt/blob/main/frontend/src/auth.ts"
click node_chatui "https://github.com/emiber/utdt/blob/main/frontend/src/components/ChatView.vue"
click node_blocks "https://github.com/emiber/utdt/blob/main/frontend/src/components/ResponseBlocks.vue"
click node_chartui "https://github.com/emiber/utdt/blob/main/frontend/src/components/ChartBlock.vue"
click node_catalogui "https://github.com/emiber/utdt/blob/main/frontend/src/components/DataCatalog.vue"
click node_usageui "https://github.com/emiber/utdt/blob/main/frontend/src/components/UsageView.vue"
click node_apiclient "https://github.com/emiber/utdt/blob/main/frontend/src/api.ts"
click node_server "https://github.com/emiber/utdt/blob/main/backend/src/server.ts"
click node_routes "https://github.com/emiber/utdt/blob/main/backend/src/app.ts"
click node_chatroute "https://github.com/emiber/utdt/blob/main/backend/src/chat.ts"
click node_auth "https://github.com/emiber/utdt/blob/main/backend/src/auth.ts"
click node_conversations "https://github.com/emiber/utdt/blob/main/backend/src/conversations.ts"
click node_catalog "https://github.com/emiber/utdt/blob/main/backend/src/catalog.ts"
click node_usage "https://github.com/emiber/utdt/blob/main/backend/src/usage.ts"
click node_usage_route "https://github.com/emiber/utdt/blob/main/backend/src/usage-route.ts"
click node_pipeline "https://github.com/emiber/utdt/blob/main/backend/src/pipeline.ts"
click node_classify "https://github.com/emiber/utdt/blob/main/backend/src/classify.ts"
click node_schema "https://github.com/emiber/utdt/blob/main/backend/src/schema-context.ts"
click node_sqlgen "https://github.com/emiber/utdt/blob/main/backend/src/generate-sql.ts"
click node_execute "https://github.com/emiber/utdt/blob/main/backend/src/execute-sql.ts"
click node_reply "https://github.com/emiber/utdt/blob/main/backend/src/reply.ts"
click node_insights "https://github.com/emiber/utdt/blob/main/backend/src/insights.ts"
click node_chart "https://github.com/emiber/utdt/blob/main/backend/src/chart.ts"
click node_metadata "https://github.com/emiber/utdt/blob/main/backend/src/metadata.ts"
click node_data_db "https://github.com/emiber/utdt/blob/main/backend/src/db.ts"
click node_llm "https://github.com/emiber/utdt/blob/main/backend/src/llm.ts"
click node_prompts "https://github.com/emiber/utdt/blob/main/backend/src/prompts.ts"
click node_timing "https://github.com/emiber/utdt/blob/main/backend/src/timing.ts"

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_appui,node_keyui,node_authui,node_chatui,node_blocks,node_chartui,node_catalogui,node_usageui,node_apiclient,node_user toneBlue
class node_server,node_routes,node_chatroute,node_auth,node_conversations,node_catalog,node_usage_route,node_metadata,node_data_db toneAmber
class node_pipeline,node_classify,node_schema,node_sqlgen,node_execute,node_reply,node_insights,node_chart,node_openai toneMint
class node_usage,node_llm,node_prompts,node_timing toneRose
```

## Components

### Web interface

- [App shell](https://github.com/emiber/utdt/blob/main/frontend/src/App.vue): `frontend/src/App.vue`
- [Key entry](https://github.com/emiber/utdt/blob/main/frontend/src/components/AccessKeyForm.vue): `frontend/src/components/AccessKeyForm.vue`
- [Key state](https://github.com/emiber/utdt/blob/main/frontend/src/auth.ts): `frontend/src/auth.ts`
- [Chat view](https://github.com/emiber/utdt/blob/main/frontend/src/components/ChatView.vue): `frontend/src/components/ChatView.vue`
- [Answer blocks](https://github.com/emiber/utdt/blob/main/frontend/src/components/ResponseBlocks.vue): `frontend/src/components/ResponseBlocks.vue`
- [Chart display](https://github.com/emiber/utdt/blob/main/frontend/src/components/ChartBlock.vue): `frontend/src/components/ChartBlock.vue`
- [Data catalog view](https://github.com/emiber/utdt/blob/main/frontend/src/components/DataCatalog.vue): `frontend/src/components/DataCatalog.vue`
- [Usage view](https://github.com/emiber/utdt/blob/main/frontend/src/components/UsageView.vue): `frontend/src/components/UsageView.vue`
- [API client](https://github.com/emiber/utdt/blob/main/frontend/src/api.ts): `frontend/src/api.ts`

### API and state

- [HTTP server](https://github.com/emiber/utdt/blob/main/backend/src/server.ts): `backend/src/server.ts`
- [Route assembly](https://github.com/emiber/utdt/blob/main/backend/src/app.ts): `backend/src/app.ts`
- [Chat endpoint](https://github.com/emiber/utdt/blob/main/backend/src/chat.ts): `backend/src/chat.ts`
- [Request authentication](https://github.com/emiber/utdt/blob/main/backend/src/auth.ts): `backend/src/auth.ts`
- [Conversation history](https://github.com/emiber/utdt/blob/main/backend/src/conversations.ts): `backend/src/conversations.ts`
- [Catalog endpoint](https://github.com/emiber/utdt/blob/main/backend/src/catalog.ts): `backend/src/catalog.ts`
- [Usage endpoint](https://github.com/emiber/utdt/blob/main/backend/src/usage-route.ts): `backend/src/usage-route.ts`
- [Data metadata](https://github.com/emiber/utdt/blob/main/backend/src/metadata.ts): `backend/src/metadata.ts`
- [Dataset database](https://github.com/emiber/utdt/blob/main/backend/src/db.ts): `backend/src/db.ts`

### Question answering

- [Answer pipeline](https://github.com/emiber/utdt/blob/main/backend/src/pipeline.ts): `backend/src/pipeline.ts`
- [Question classification](https://github.com/emiber/utdt/blob/main/backend/src/classify.ts): `backend/src/classify.ts`
- [Schema context](https://github.com/emiber/utdt/blob/main/backend/src/schema-context.ts): `backend/src/schema-context.ts`
- [SQL generation](https://github.com/emiber/utdt/blob/main/backend/src/generate-sql.ts): `backend/src/generate-sql.ts`
- [SQL execution](https://github.com/emiber/utdt/blob/main/backend/src/execute-sql.ts): `backend/src/execute-sql.ts`
- [Text replies](https://github.com/emiber/utdt/blob/main/backend/src/reply.ts): `backend/src/reply.ts`
- [Result insights](https://github.com/emiber/utdt/blob/main/backend/src/insights.ts): `backend/src/insights.ts`
- [Chart construction](https://github.com/emiber/utdt/blob/main/backend/src/chart.ts): `backend/src/chart.ts`

### LLM and reporting

- [Usage reporting](https://github.com/emiber/utdt/blob/main/backend/src/usage.ts): `backend/src/usage.ts`
- [LLM adapter](https://github.com/emiber/utdt/blob/main/backend/src/llm.ts): `backend/src/llm.ts`
- [Prompt rendering](https://github.com/emiber/utdt/blob/main/backend/src/prompts.ts): `backend/src/prompts.ts`
- [Call timing](https://github.com/emiber/utdt/blob/main/backend/src/timing.ts): `backend/src/timing.ts`

### Other components

- **User**
- **OpenAI APIs**

## Connections

- User → Key entry: enters key
- Key entry → Key state: saves key (evidence: `frontend/src/components/AccessKeyForm.vue`)
- User → Chat view: asks question
- App shell → Chat view: routes to
- App shell → Data catalog view: shows catalog (evidence: `frontend/src/App.vue`)
- App shell → Usage view: routes to
- Chat view → API client: requests chat (evidence: `frontend/src/components/ChatView.vue`)
- Data catalog view → API client: loads catalog (evidence: `frontend/src/components/DataCatalog.vue`)
- Usage view → API client: loads report (evidence: `frontend/src/components/UsageView.vue`)
- API client → Key state: uses key (evidence: `frontend/src/api.ts`)
- API client → Chat endpoint: posts question
- API client → Catalog endpoint: requests catalog
- API client → Usage endpoint: requests report
- Answer blocks → Chart display: renders chart (evidence: `frontend/src/components/ResponseBlocks.vue`)
- Chat view → Answer blocks: renders answer (evidence: `frontend/src/components/ChatView.vue`)
- HTTP server → Route assembly: builds app (evidence: `backend/src/server.ts`)
- Route assembly → Request authentication: checks key (evidence: `backend/src/app.ts`)
- Route assembly → Chat endpoint: registers route (evidence: `backend/src/app.ts`)
- Route assembly → Usage endpoint: registers route (evidence: `backend/src/app.ts`)
- Route assembly → Catalog endpoint: serves catalog (evidence: `backend/src/app.ts`)
- Chat endpoint → Answer pipeline: runs pipeline (evidence: `backend/src/chat.ts`)
- Chat endpoint → Conversation history: loads and saves (evidence: `backend/src/chat.ts`)
- Catalog endpoint → Data metadata: reads metadata
- Catalog endpoint → Dataset database: reads dataset
- Answer pipeline → Schema context: builds context (evidence: `backend/src/pipeline.ts`)
- Answer pipeline → Question classification: classifies question (evidence: `backend/src/pipeline.ts`)
- Answer pipeline → Text replies: builds text reply (evidence: `backend/src/pipeline.ts`)
- Answer pipeline → SQL generation: generates queries (evidence: `backend/src/pipeline.ts`)
- Answer pipeline → Result insights: builds insights (evidence: `backend/src/pipeline.ts`)
- Answer pipeline → Chart construction: builds charts (evidence: `backend/src/pipeline.ts`)
- SQL generation → SQL execution: executes SQL (evidence: `backend/src/generate-sql.ts`)
- SQL generation → LLM adapter: requests SQL (evidence: `backend/src/generate-sql.ts`)
- Question classification → LLM adapter: requests classification (evidence: `backend/src/classify.ts`)
- Text replies → LLM adapter: requests reply (evidence: `backend/src/reply.ts`)
- Result insights → LLM adapter: requests insights (evidence: `backend/src/insights.ts`)
- SQL generation → Prompt rendering: renders prompts (evidence: `backend/src/generate-sql.ts`)
- Answer pipeline → Conversation history: uses history types (evidence: `backend/src/pipeline.ts`)
- LLM adapter → OpenAI APIs: calls APIs (evidence: `backend/src/llm.ts`)
- Usage endpoint → Usage reporting: builds report
- Usage reporting → Conversation history: reads call records
