# bodanlabs/ragfolio architecture

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

- Interactive diagram: https://gitdiagram.com/bodanlabs/ragfolio
- Repository: https://github.com/bodanlabs/ragfolio

## Overview

1. **Repo shape and deployment boundary**
   - This is a monorepo with two primary runtime apps: `apps/web` for the browser UI and `apps/api` for the backend API.
   - Supporting workspace packages under `packages/` provide shared TypeScript config/types, while the root scripts orchestrate development, builds, and service startup.

2. **Frontend subsystem**
   - `apps/web` is a React + TypeScript SPA built with Vite.
   - Its structure is page-driven: `src/pages` contains the main screens, `src/components/layout` provides the application shell/navigation, and `src/components/ui` contains the reusable UI primitives.
   - API access is centralized in `src/api` and `src/hooks/api`, with TanStack Query used to cache server state and drive refetching.

3. **Frontend state and domain boundaries**
   - The UI appears organized around business areas that mirror the backend: authentication, organizations, documents, chat, LLM keys, user profile, and settings.
   - `AppContext` likely holds app-wide state such as the current user and selected organization, while the page layer stays thin and delegates to hooks and API clients.

4. **Backend application layering**
   - `apps/api` is a FastAPI service split into `routers`, `services`, `models`, `db`, `tasks`, and `utils`.
   - The architectural pattern is clear: routers expose HTTP endpoints, services contain business logic, models define request/response shapes, and the DB layer holds SQLAlchemy schema/session setup.

5. **Core backend domains**
   - The backend is organized around these major bounded contexts: authentication, users, organizations/memberships/invitations, documents, chat, and LLM key management.
   - The routes in `app/routers` and service modules in `app/services` align closely, making the API and internal domain model easy to map one-to-one.

6. **Document ingestion and processing pipeline**
   - Document upload starts in the API, persists the raw file through `file_storage`, and records metadata in the database.
   - Asynchronous processing is offloaded to Celery tasks in `app/tasks/document_processing.py`.
   - The processing chain includes text extraction, chunking, embedding generation, and storage of vectorized document chunks for later retrieval.
   - This pipeline is one of the key architectural seams: request/response handling stays in FastAPI, while heavy document work runs in background workers.

7. **RAG chat flow**
   - Chat is not just message storage; it is a retrieval-augmented generation pipeline.
   - A chat request goes through the chat service, which uses `rag`, `embedding`, and likely vector similarity search against document chunks stored in PostgreSQL/pgvector.
   - Retrieved context is then sent to the external LLM provider, and the resulting assistant response plus message history are stored in the database.

8. **Organization and access-control boundary**
   - Organizations are the main tenant boundary for data ownership and permissions.
   - Users belong to organizations through members/invitations workflows, and most higher-level resources are scoped by organization.
   - This means document access, chat sessions, and LLM keys are effectively organization-owned resources rather than global app state.

9. **LLM key management and secrets handling**
   - The app supports per-organization LLM API keys, stored encrypted via `utils/encryption.py` and managed through dedicated service logic.
   - There are flows for creating, updating, activating, and testing keys, which indicates the backend can switch between credentials without exposing secrets to the UI.
   - This is a distinct security boundary: the frontend can manage keys, but the sensitive material stays protected server-side.

10. **Infrastructure and external services**
   - PostgreSQL is the primary system of record, with pgvector enabled for semantic search.
   - Redis serves two roles: Celery broker/result backend and general caching/rate-limiting support.
   - External integrations include OpenAI for embeddings/chat and email delivery for invitations.
   - File storage is local by default, but the settings and README indicate an abstraction that can be swapped to S3.

11. **Schema, migrations, and persistence**
   - Database evolution is handled through Alembic migrations under `apps/api/alembic`.
   - The presence of a schema migration plus a pgvector-enabling migration suggests the DB schema is foundational to the app’s behavior, especially for document retrieval and chat.
   - SQLAlchemy model definitions and database enums/tables in `app/db` define the persistent shape of users, orgs, documents, chats, and related records.

12. **Cross-cutting concerns**
   - The backend has explicit services for audit, quota, email, members, invitations, and LLM key management, which suggests these are treated as shared business capabilities rather than isolated endpoint concerns.
   - Authentication is JWT-based, and the `dependencies.py`/`auth.py` utility layers likely inject current-user and authorization context across routers.
   - Overall, the architecture is a fairly clean split between a thin React client, a domain-driven FastAPI backend, and asynchronous background processing for document/RAG workloads.

Main entry points: [`apps/web`](https://github.com/bodanlabs/ragfolio/tree/main/apps/web) (Web UI), [`apps/api/app/services`](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/services) (Services), [`apps/web/src/api`](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/api) (Client API), [`apps/api/app/routers`](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/routers) (Routers)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_repo["Monorepo"]
  node_root["Workspace<br/>monorepo root"]
end

subgraph group_web["Web App"]
  node_web_app["Web UI<br/>react spa"]
  node_web_pages["Pages<br/>route screens"]
  node_web_shell["App Shell<br/>layout ui"]
  node_web_state(("App State<br/>context/hooks"))
  node_web_api["Client API<br/>typed client"]
  node_web_ui["UI Primitives<br/>component kit"]
  node_web_types["Frontend Types<br/>shared types"]
end

subgraph group_api["API App"]
  node_api_app["Backend API<br/>fastapi service"]
  node_api_routers["Routers<br/>http endpoints"]
  node_api_services["Services<br/>business logic"]
  node_api_models["Models<br/>schemas"]
  node_api_db[("Database Layer<br/>sqlalchemy schema")]
  node_api_tasks["Workers<br/>celery tasks"]
  node_api_utils["Utilities<br/>security/helpers"]
  node_api_migrations["Migrations<br/>alembic schema"]
  node_api_storage[("File Storage<br/>object store")]
end

subgraph group_shared["Shared Packages"]
  node_shared_config["Config Package<br/>workspace config"]
  node_shared_types["Types Package<br/>workspace types"]
end

node_root -->|"runs"| node_web_app
node_root -->|"runs"| node_api_app
node_root -->|"shares config"| node_shared_config
node_root -->|"shares types"| node_shared_types
node_web_app -->|"renders"| node_web_pages
node_web_app -->|"wraps"| node_web_shell
node_web_app -->|"uses"| node_web_state
node_web_app -->|"fetches data"| node_web_api
node_web_app -->|"composes"| node_web_ui
node_web_api -->|"calls"| node_api_routers
node_web_state -->|"drives"| node_web_api
node_api_app -->|"exposes"| node_api_routers
node_api_routers -->|"delegates"| node_api_services
node_api_services -->|"validates"| node_api_models
node_api_services -->|"persists"| node_api_db
node_api_services -->|"offloads"| node_api_tasks
node_api_tasks -->|"reads/writes"| node_api_storage
node_api_services -->|"secures"| node_api_utils
node_api_migrations -->|"evolves"| node_api_db
node_shared_types -.->|"aligns"| node_web_types

click node_web_app "https://github.com/bodanlabs/ragfolio/tree/main/apps/web"
click node_web_pages "https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/pages"
click node_web_shell "https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/components/layout"
click node_web_state "https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/contexts"
click node_web_api "https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/api"
click node_web_ui "https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/components/ui"
click node_web_types "https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/types"
click node_api_app "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app"
click node_api_routers "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/routers"
click node_api_services "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/services"
click node_api_models "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/models"
click node_api_db "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/db"
click node_api_tasks "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/tasks"
click node_api_utils "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/utils"
click node_api_migrations "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/alembic"
click node_api_storage "https://github.com/bodanlabs/ragfolio/tree/main/apps/api/storage"
click node_shared_config "https://github.com/bodanlabs/ragfolio/tree/main/packages/config"
click node_shared_types "https://github.com/bodanlabs/ragfolio/tree/main/packages/types"

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_root toneBlue
class node_web_app,node_web_pages,node_web_shell,node_web_state,node_web_api,node_web_ui,node_web_types toneAmber
class node_api_app,node_api_routers,node_api_services,node_api_models,node_api_db,node_api_tasks,node_api_utils,node_api_migrations,node_api_storage toneMint
class node_shared_config,node_shared_types toneRose
```

## Components

### Monorepo

Workspace root and shared tooling

- **Workspace**: monorepo root · Root scripts, workspace config, and orchestration

### Web App

React/Vite frontend

- [Web UI](https://github.com/bodanlabs/ragfolio/tree/main/apps/web): react spa · Browser application built with Vite and TypeScript · `apps/web`
- [Pages](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/pages): route screens · Top-level screens and navigation entry points · `apps/web/src/pages`
- [App Shell](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/components/layout): layout ui · Global navigation, sidebar, and top bar · `apps/web/src/components/layout`
- [App State](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/contexts): context/hooks · App-wide context plus query-backed API hooks · `apps/web/src/contexts`
- [Client API](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/api): typed client · Frontend API adapters, query keys, and data mappers · `apps/web/src/api`
- [UI Primitives](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/components/ui): component kit · Reusable interface components and design system building blocks · `apps/web/src/components/ui`
- [Frontend Types](https://github.com/bodanlabs/ragfolio/tree/main/apps/web/src/types): shared types · API and domain types used by the UI · `apps/web/src/types`

### API App

FastAPI backend

- [Backend API](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app): fastapi service · HTTP API and background worker oriented backend · `apps/api/app`
- [Routers](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/routers): http endpoints · Request entry points grouped by domain · `apps/api/app/routers`
- [Services](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/services): business logic · Domain rules, orchestration, and integrations · `apps/api/app/services`
- [Models](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/models): schemas · Request and response shapes for API domains · `apps/api/app/models`
- [Database Layer](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/db): sqlalchemy schema · Session setup, enums, and persistent table definitions · `apps/api/app/db`
- [Workers](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/tasks): celery tasks · Asynchronous background processing jobs · `apps/api/app/tasks`
- [Utilities](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/app/utils): security/helpers · Shared helpers for auth and encryption · `apps/api/app/utils`
- [Migrations](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/alembic): alembic schema · Database schema evolution and pgvector enablement · `apps/api/alembic`
- [File Storage](https://github.com/bodanlabs/ragfolio/tree/main/apps/api/storage): object store · Persisted uploaded files and processed artifacts · `apps/api/storage`

### Shared Packages

Workspace-wide config and types

- [Config Package](https://github.com/bodanlabs/ragfolio/tree/main/packages/config): workspace config · Shared ESLint and TypeScript configuration · `packages/config`
- [Types Package](https://github.com/bodanlabs/ragfolio/tree/main/packages/types): workspace types · Shared TypeScript types published across the monorepo · `packages/types`

## Connections

- Workspace → Web UI: runs · Root workspace orchestrates the frontend app
- Workspace → Backend API: runs · Root workspace orchestrates the backend app
- Workspace → Config Package: shares config · Workspace tooling depends on common lint and TypeScript settings
- Workspace → Types Package: shares types · Workspace tooling depends on shared type definitions
- Web UI → Pages: renders · The app is page-driven
- Web UI → App Shell: wraps · Global layout frames the UI
- Web UI → App State: uses · Context and hooks hold app-wide state
- Web UI → Client API: fetches data · Frontend communicates through typed API clients
- Web UI → UI Primitives: composes · Pages and layout are built from reusable UI primitives
- Client API → Routers: calls · Client adapters target backend endpoints
- App State → Client API: drives · Query hooks and context coordinate server state
- Backend API → Routers: exposes · FastAPI application mounts domain routers
- Routers → Services: delegates · Routers hand off business logic to services
- Services → Models: validates · Services and endpoints rely on shared schema objects
- Services → Database Layer: persists · Services read and write through the database layer
- Services → Workers: offloads · Heavy document work runs asynchronously
- Workers → File Storage: reads/writes · Processing pipeline operates on stored files and artifacts
- Services → Utilities: secures · Authentication and encryption helpers support sensitive flows
- Migrations → Database Layer: evolves · Alembic migrations define schema changes
- Types Package → Frontend Types: aligns · Frontend types mirror shared domain contracts
