How bodanlabs/ragfolio works
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: web Web UI · services Services · api Client API · routers Routers
Components 19
Monorepo
Workspace root and shared tooling
- Workspace · Root scripts, workspace config, and orchestration
Web App
React/Vite frontend
- Web UI · Browser application built with Vite and TypeScript
apps/web - Pages · Top-level screens and navigation entry points
apps/web/src/pages - App Shell · Global navigation, sidebar, and top bar
apps/web/src/components/layout - App State · App-wide context plus query-backed API hooks
apps/web/src/contexts - Client API · Frontend API adapters, query keys, and data mappers
apps/web/src/api - UI Primitives · Reusable interface components and design system building blocks
apps/web/src/components/ui - Frontend Types · API and domain types used by the UI
apps/web/src/types
API App
FastAPI backend
- Backend API · HTTP API and background worker oriented backend
apps/api/app - Routers · Request entry points grouped by domain
apps/api/app/routers - Services · Domain rules, orchestration, and integrations
apps/api/app/services - Models · Request and response shapes for API domains
apps/api/app/models - Database Layer · Session setup, enums, and persistent table definitions
apps/api/app/db - Workers · Asynchronous background processing jobs
apps/api/app/tasks - Utilities · Shared helpers for auth and encryption
apps/api/app/utils - Migrations · Database schema evolution and pgvector enablement
apps/api/alembic - File Storage · Persisted uploaded files and processed artifacts
apps/api/storage
Shared Packages
Workspace-wide config and types
- Config Package · Shared ESLint and TypeScript configuration
packages/config - Types Package · Shared TypeScript types published across the monorepo
packages/types
Connections 20
- 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