# shabab-personal/nsw-heights-safety-rag architecture

> Architecture diagram of the GitHub repository shabab-personal/nsw-heights-safety-rag, 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/shabab-personal/nsw-heights-safety-rag
- Repository: https://github.com/shabab-personal/nsw-heights-safety-rag

## Overview

This is a local NSW working-at-heights safety assistant. Users ask questions in the Angular chat; the FastAPI endpoint retrieves relevant document chunks and generates a context-grounded answer with a local LLM, returning the answer and chunk previews. Separately, PDF ingestion extracts pages, chunks text, embeds it, and stores vectors for later retrieval. The README documents dynamic document support, but sampled ingestion only shows rebuilding the collection; UI component and dynamic document-management wiring were not sampled.

Main entry points: [`api/main.py`](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/api/main.py) (Ask API), [`safety-rag-ui/src/app/components/chat/chat.component.ts`](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/safety-rag-ui/src/app/components/chat/chat.component.ts) (Chat interface), [`safety-rag-ui/src/app/services/rag.service.ts`](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/safety-rag-ui/src/app/services/rag.service.ts) (RAG service), [`rag_basic/ingest.py`](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/ingest.py) (PDF ingestion)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingestion["Document ingestion"]
  node_pdfs["Safety PDFs"]
  node_ingest["PDF ingestion<br/>[ingest.py]"]
end

subgraph group_rag["RAG pipeline"]
  node_embed["Embedding model"]
  node_vectors[("ChromaDB collection")]
  node_retrieval["Chunk retrieval<br/>[query.py]"]
  node_generation["Answer generation<br/>[query.py]"]
  node_ollama["Ollama LLM"]
end

subgraph group_backend["API backend"]
  node_api["Ask API<br/>[main.py]"]
end

subgraph group_frontend["Angular frontend"]
  node_chat["Chat interface<br/>[chat.component.ts]"]
  node_service["RAG service<br/>[rag.service.ts]"]
end

node_worker(("Safety worker"))

node_pdfs -->|"reads PDFs"| node_ingest
node_ingest -->|"encodes chunks"| node_embed
node_ingest -->|"writes vectors"| node_vectors
node_worker -->|"asks question"| node_chat
node_chat -->|"submits question"| node_service
node_service -->|"POST /ask"| node_api
node_api -->|"retrieves chunks"| node_retrieval
node_retrieval -->|"encodes question"| node_embed
node_retrieval -->|"queries vectors"| node_vectors
node_api -->|"generates answer"| node_generation
node_generation -->|"calls model"| node_ollama
node_api -->|"returns answer and chunks"| node_service
node_service -->|"emits response"| node_chat
node_chat -->|"shows answer"| node_worker

click node_pdfs "https://github.com/shabab-personal/nsw-heights-safety-rag/tree/main/data/pdfs"
click node_ingest "https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/ingest.py"
click node_retrieval "https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/query.py"
click node_generation "https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/query.py"
click node_api "https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/api/main.py"
click node_chat "https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/safety-rag-ui/src/app/components/chat/chat.component.ts"
click node_service "https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/safety-rag-ui/src/app/services/rag.service.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_pdfs,node_ingest toneBlue
class node_embed,node_vectors,node_retrieval,node_generation,node_ollama toneAmber
class node_api toneMint
class node_chat,node_service,node_worker toneRose
```

## Components

### Document ingestion

- [Safety PDFs](https://github.com/shabab-personal/nsw-heights-safety-rag/tree/main/data/pdfs): `data/pdfs`
- [PDF ingestion](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/ingest.py): `rag_basic/ingest.py`

### RAG pipeline

- **Embedding model**
- **ChromaDB collection**
- [Chunk retrieval](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/query.py): `rag_basic/query.py`
- [Answer generation](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/rag_basic/query.py): `rag_basic/query.py`
- **Ollama LLM**

### API backend

- [Ask API](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/api/main.py): `api/main.py`

### Angular frontend

- [Chat interface](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/safety-rag-ui/src/app/components/chat/chat.component.ts): `safety-rag-ui/src/app/components/chat/chat.component.ts`
- [RAG service](https://github.com/shabab-personal/nsw-heights-safety-rag/blob/main/safety-rag-ui/src/app/services/rag.service.ts): `safety-rag-ui/src/app/services/rag.service.ts`

### Other components

- **Safety worker**

## Connections

- Safety PDFs → PDF ingestion: reads PDFs
- PDF ingestion → Embedding model: encodes chunks
- PDF ingestion → ChromaDB collection: writes vectors
- Safety worker → Chat interface: asks question
- Chat interface → RAG service: submits question
- RAG service → Ask API: POST /ask
- Ask API → Chunk retrieval: retrieves chunks
- Chunk retrieval → Embedding model: encodes question
- Chunk retrieval → ChromaDB collection: queries vectors
- Ask API → Answer generation: generates answer
- Answer generation → Ollama LLM: calls model
- Ask API → RAG service: returns answer and chunks
- RAG service → Chat interface: emits response
- Chat interface → Safety worker: shows answer
