# metal-code/orbit architecture

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

- Interactive diagram: https://gitdiagram.com/metal-code/orbit
- Repository: https://github.com/metal-code/orbit

## Overview

1. **Repository shape**
   - This repo is a two-app monorepo: a **TanStack Start / React frontend** at the root `frontend/` and a **FastAPI backend** in `backend/`.
   - The two halves are independently deployable and communicate only over HTTP/JSON, with JWT bearer auth for protected requests.

2. **System boundary**
   - The frontend owns presentation, routing, optimistic interaction, and client-side token storage.
   - The backend owns all business rules, persistence, auth verification, file-upload signing, and AI/RAG logic.
   - External services are part of the backend’s runtime boundary: **SQLite**, **AWS S3**, **ChromaDB**, **Redis (Upstash)**, **Mistral AI**, and **Gmail SMTP**.

3. **Frontend surface and routing**
   - The frontend is a file-routed SSR app using TanStack Router/TanStack Start.
   - Route groups map cleanly to product surfaces: public marketing (`/`, `/about`, `/report`), auth (`/login`, `/register`, `/verify-otp`, `/join`), and authenticated app views (`/dashboard`, `/projects/:id/timeline`).
   - `src/routes/__root.tsx` is the top-level shell; `routeTree.gen.ts` is generated routing metadata.

4. **Frontend data and API layer**
   - `src/lib/api.ts` centralizes all backend calls through one Axios instance.
   - It injects `Authorization: Bearer <token>` from `localStorage["orbit_token"]` on protected requests, and handles `401` by clearing auth state and redirecting to login.
   - TanStack Query is wired through `src/router.tsx` so routes and components can prefetch and hydrate backend data consistently.

5. **Frontend feature composition**
   - The dashboard and timeline are assembled from feature components in `src/components/`.
   - Key UI boundaries are: org/project management modals, timeline entry creation and inspection, and the AI chat panel.
   - The landing page includes a Remotion-driven hero asset (`frontend/remotion/`) which is separate from the main app runtime.

6. **Backend entrypoint and layering**
   - `backend/main.py` is the ASGI app entrypoint.
   - The backend follows a clear router → service → model pattern:
     - `routers/` expose HTTP endpoints
     - `services/` implement business logic
     - `models/` map to database tables
     - `schemas/` define request/response contracts
   - This boundary keeps API concerns thin and pushes real logic into service modules.

7. **Persistence model**
   - Core relational state lives in SQLite via SQLAlchemy.
   - Main entities are `User`, `Organization`, `Project`, `ProjectMember`, `TimelineEntry`, `Link`, `Attachment`, and `PendingRegistration`.
   - The design is multi-tenant: users belong to orgs, projects belong to orgs, and access to a project is mediated by `ProjectMember`.
   - Timeline entries snapshot author name/email so historical records remain stable even if the user changes later.

8. **Auth and access control**
   - Authentication is JWT-based and enforced by `dependencies/auth.py` using FastAPI `Depends`.
   - Registration is OTP-gated: unverified data stays in `PendingRegistration` until OTP confirmation creates a real `User`.
   - Authorization is mostly membership-driven:
     - org invite codes control org membership
     - project invite codes control project access
     - project membership is required for timeline and chat access
   - Roles are simple and org-level, with owner vs member behavior affecting creation and deletion actions.

9. **Timeline and attachment flow**
   - Timeline entries are the core content object in the product.
   - Creating an entry can include nested links and attachments in one request.
   - File uploads do not stream through the backend; instead the frontend requests a presigned S3 PUT URL from `/upload/presigned-url`, uploads directly to S3, then stores the resulting file URL in the timeline entry payload.
   - This makes the backend stateless for large files and keeps upload traffic off the API server.

10. **AI/RAG subsystem**
   - The backend has a dedicated `rag/` pipeline for project-scoped assistant answers.
   - When a timeline entry is created, it is embedded and indexed in ChromaDB along with metadata such as project ID, links, and attachments.
   - When a user asks a question, the backend embeds the query, retrieves top matches filtered by the same project, and sends the context to Mistral LLM for the answer.
   - The response includes both a natural-language answer and structured `sources` so the frontend can render clickable references.

11. **Chat history subsystem**
   - Chat history is separate from the RAG store and is kept in Redis via Upstash.
   - History is keyed by `chat:{project_id}:{user_id}` with a 3-day TTL, which makes it temporary and user/project-specific.
   - The timeline chatbot hydrates from `/projects/{id}/chat/history`, appends new turns via `/projects/{id}/chat`, and can clear history with a delete endpoint.

12. **Operational and external integration boundaries**
   - Email is used for OTP registration and reports, with Gmail SMTP handling outbound messages from the backend.
   - CORS and frontend/backend origin separation matter because the frontend is often deployed independently and points at the backend through `VITE_API_URL`.
   - The backend also depends on environment-driven secrets for JWT, S3, Mistral, Redis, and mail credentials, so most infrastructure is configured outside the codebase.

13. **How to diagram the main runtime flow**
   - A user logs in or verifies OTP through the auth router, receives a JWT, and the frontend stores it locally.
   - After that, the dashboard and timeline fetch org/project state through authenticated API calls.
   - Timeline entries are persisted in SQLite, attachments in S3, embeddings in ChromaDB, and conversational context in Redis.
   - The AI chat flow is therefore a composition of four stores/services: relational source data, vector search, LLM generation, and short-lived chat memory.

14. **What is most important to preserve in an architecture diagram**
   - Show the frontend, backend API, and the four backend-side integrations separately: database, object storage, vector store, and cache.
   - Keep the AI pipeline distinct from normal CRUD flows, because it reads from timeline content and writes chat history but does not own primary business data.
   - Keep organization membership and project membership as separate access boundaries, since they govern nearly every protected operation.

Main entry points: [`backend/services`](https://github.com/metal-code/orbit/tree/main/backend/services) (Services), [`frontend/src/routes`](https://github.com/metal-code/orbit/tree/main/frontend/src/routes) (Routes), [`backend/routers`](https://github.com/metal-code/orbit/tree/main/backend/routers) (HTTP routers), [`backend/rag/pipeline.py`](https://github.com/metal-code/orbit/blob/main/backend/rag/pipeline.py) (RAG pipeline)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Frontend"]
  node_frontend_app_shell["App shell<br/>SSR shell<br/>[__root.tsx]"]
  node_frontend_route_tree["Route tree<br/>generated routing<br/>[routeTree.gen.ts]"]
  node_frontend_routes["Routes"]
  node_frontend_api["API client<br/>Axios layer<br/>[api.ts]"]
  node_frontend_state["Query runtime<br/>data hydration<br/>[router.tsx]"]
  node_frontend_dashboard["Dashboard UI<br/>app surface"]
  node_frontend_timeline["Timeline UI<br/>content surface"]
  node_frontend_chat["Chat panel<br/>assistant UI"]
  node_frontend_marketing["Marketing pages<br/>public surface<br/>[index.tsx]"]
  node_frontend_remotion["Remotion hero<br/>motion asset"]
end

subgraph group_backend["Backend"]
  node_backend_app["API app<br/>FastAPI entrypoint<br/>[main.py]"]
  node_backend_auth["Auth layer<br/>JWT deps<br/>[auth.py]"]
  node_backend_routers["HTTP routers<br/>REST routes"]
  node_backend_services["Services<br/>business logic"]
  node_backend_models[("Models")]
  node_backend_schemas["Schemas<br/>contracts"]
  node_backend_rag["RAG pipeline<br/>assistant pipeline<br/>[pipeline.py]"]
  node_backend_chat_history["Chat history<br/>Redis storage"]
end

subgraph group_external["External systems"]
  node_external_db[("SQLite<br/>relational store<br/>[devcycle.db]")]
  node_external_s3[("S3<br/>object storage<br/>[s3_service.py]")]
  node_external_vector[("ChromaDB<br/>vector store<br/>[vector_store.py]")]
  node_external_cache[("Redis<br/>chat cache")]
  node_external_llm(("Mistral AI<br/>LLM<br/>[llm.py]"))
  node_external_mail(("Gmail SMTP<br/>email<br/>[auth_service.py]"))
end

node_frontend_routes -->|"mounted in"| node_frontend_app_shell
node_frontend_route_tree -->|"describes"| node_frontend_routes
node_frontend_routes -->|"calls"| node_frontend_api
node_frontend_api -->|"HTTP/JSON"| node_backend_routers
node_frontend_state -->|"hydrates from"| node_frontend_api
node_frontend_dashboard -->|"composed in"| node_frontend_routes
node_frontend_timeline -->|"composed in"| node_frontend_routes
node_frontend_chat -->|"embedded in"| node_frontend_timeline
node_frontend_marketing -->|"uses"| node_frontend_remotion
node_backend_app -->|"registers"| node_backend_routers
node_backend_routers -->|"protects with"| node_backend_auth
node_backend_routers -->|"delegates to"| node_backend_services
node_backend_services -->|"reads/writes"| node_backend_models
node_backend_services -->|"validates with"| node_backend_schemas
node_backend_models -->|"persisted in"| node_external_db
node_backend_services -->|"uploads to"| node_external_s3
node_backend_rag -->|"retrieves from"| node_external_vector
node_backend_rag -->|"generates with"| node_external_llm
node_backend_chat_history -->|"stored in"| node_external_cache
node_backend_services -->|"invokes"| node_backend_rag
node_backend_services -->|"appends/reads"| node_backend_chat_history
node_backend_services -->|"sends"| node_external_mail

click node_frontend_app_shell "https://github.com/metal-code/orbit/blob/main/frontend/src/routes/__root.tsx"
click node_frontend_route_tree "https://github.com/metal-code/orbit/blob/main/frontend/src/routeTree.gen.ts"
click node_frontend_routes "https://github.com/metal-code/orbit/tree/main/frontend/src/routes"
click node_frontend_api "https://github.com/metal-code/orbit/blob/main/frontend/src/lib/api.ts"
click node_frontend_state "https://github.com/metal-code/orbit/blob/main/frontend/src/router.tsx"
click node_frontend_dashboard "https://github.com/metal-code/orbit/tree/main/frontend/src/components"
click node_frontend_timeline "https://github.com/metal-code/orbit/tree/main/frontend/src/components"
click node_frontend_chat "https://github.com/metal-code/orbit/blob/main/frontend/src/components/TimelineChatbot.tsx"
click node_frontend_marketing "https://github.com/metal-code/orbit/blob/main/frontend/src/routes/index.tsx"
click node_frontend_remotion "https://github.com/metal-code/orbit/tree/main/frontend/remotion"
click node_backend_app "https://github.com/metal-code/orbit/blob/main/backend/main.py"
click node_backend_auth "https://github.com/metal-code/orbit/blob/main/backend/dependencies/auth.py"
click node_backend_routers "https://github.com/metal-code/orbit/tree/main/backend/routers"
click node_backend_services "https://github.com/metal-code/orbit/tree/main/backend/services"
click node_backend_models "https://github.com/metal-code/orbit/tree/main/backend/models"
click node_backend_schemas "https://github.com/metal-code/orbit/tree/main/backend/schemas"
click node_backend_rag "https://github.com/metal-code/orbit/blob/main/backend/rag/pipeline.py"
click node_backend_chat_history "https://github.com/metal-code/orbit/blob/main/backend/services/chat_history_service.py"
click node_external_db "https://github.com/metal-code/orbit/blob/main/backend/devcycle.db"
click node_external_s3 "https://github.com/metal-code/orbit/blob/main/backend/services/s3_service.py"
click node_external_vector "https://github.com/metal-code/orbit/blob/main/backend/rag/vector_store.py"
click node_external_cache "https://github.com/metal-code/orbit/blob/main/backend/services/chat_history_service.py"
click node_external_llm "https://github.com/metal-code/orbit/blob/main/backend/rag/llm.py"
click node_external_mail "https://github.com/metal-code/orbit/blob/main/backend/services/auth_service.py"

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_frontend_app_shell,node_frontend_route_tree,node_frontend_routes,node_frontend_api,node_frontend_state,node_frontend_dashboard,node_frontend_timeline,node_frontend_chat,node_frontend_marketing,node_frontend_remotion toneBlue
class node_backend_app,node_backend_auth,node_backend_routers,node_backend_services,node_backend_models,node_backend_schemas,node_backend_rag,node_backend_chat_history toneAmber
class node_external_db,node_external_s3,node_external_vector,node_external_cache,node_external_llm,node_external_mail toneMint
```

## Components

### Frontend

TanStack Start / React app and UI composition

- [App shell](https://github.com/metal-code/orbit/blob/main/frontend/src/routes/__root.tsx): SSR shell · Top-level TanStack Start shell and route runtime · `frontend/src/routes/__root.tsx`
- [Route tree](https://github.com/metal-code/orbit/blob/main/frontend/src/routeTree.gen.ts): generated routing · Generated TanStack Router metadata · `frontend/src/routeTree.gen.ts`
- [Routes](https://github.com/metal-code/orbit/tree/main/frontend/src/routes): file routes · Public, auth, dashboard, and project timeline screens · `frontend/src/routes`
- [API client](https://github.com/metal-code/orbit/blob/main/frontend/src/lib/api.ts): Axios layer · Centralized HTTP client with JWT injection and 401 handling · `frontend/src/lib/api.ts`
- [Query runtime](https://github.com/metal-code/orbit/blob/main/frontend/src/router.tsx): data hydration · TanStack Query integration for prefetching and hydration · `frontend/src/router.tsx`
- [Dashboard UI](https://github.com/metal-code/orbit/tree/main/frontend/src/components): app surface · Authenticated project and organization workspace · `frontend/src/components`
- [Timeline UI](https://github.com/metal-code/orbit/tree/main/frontend/src/components): content surface · Entry creation, detail inspection, and project timeline view · `frontend/src/components`
- [Chat panel](https://github.com/metal-code/orbit/blob/main/frontend/src/components/TimelineChatbot.tsx): assistant UI · Project-scoped chatbot and history hydration · `frontend/src/components/TimelineChatbot.tsx`
- [Marketing pages](https://github.com/metal-code/orbit/blob/main/frontend/src/routes/index.tsx): public surface · Landing, about, and report pages plus hero media · `frontend/src/routes/index.tsx`
- [Remotion hero](https://github.com/metal-code/orbit/tree/main/frontend/remotion): motion asset · Separate Remotion runtime for landing-page hero video · `frontend/remotion`

### Backend

FastAPI API, services, data model, and RAG pipeline

- [API app](https://github.com/metal-code/orbit/blob/main/backend/main.py): FastAPI entrypoint · ASGI application entrypoint and router assembly · `backend/main.py`
- [Auth layer](https://github.com/metal-code/orbit/blob/main/backend/dependencies/auth.py): JWT deps · Bearer auth, OTP registration, and access control dependencies · `backend/dependencies/auth.py`
- [HTTP routers](https://github.com/metal-code/orbit/tree/main/backend/routers): REST routes · Auth, organizations, projects, timeline, upload, chat, history, and report endpoints · `backend/routers`
- [Services](https://github.com/metal-code/orbit/tree/main/backend/services): business logic · Orchestration for auth, orgs, projects, timeline, uploads, and chat history · `backend/services`
- [Models](https://github.com/metal-code/orbit/tree/main/backend/models): SQLAlchemy models · Users, organizations, projects, membership, timeline entries, links, attachments, and pending registrations · `backend/models`
- [Schemas](https://github.com/metal-code/orbit/tree/main/backend/schemas): contracts · Request and response shapes for API payloads · `backend/schemas`
- [RAG pipeline](https://github.com/metal-code/orbit/blob/main/backend/rag/pipeline.py): assistant pipeline · Embedding, retrieval, and LLM answer generation for project chat · `backend/rag/pipeline.py`
- [Chat history](https://github.com/metal-code/orbit/blob/main/backend/services/chat_history_service.py): Redis storage · Temporary project/user chat memory with TTL · `backend/services/chat_history_service.py`

### External systems

Infrastructure and third-party services used by the backend

- [SQLite](https://github.com/metal-code/orbit/blob/main/backend/devcycle.db): relational store · Primary persistent database for app state · `backend/devcycle.db`
- [S3](https://github.com/metal-code/orbit/blob/main/backend/services/s3_service.py): object storage · Direct-upload file storage via presigned URLs · `backend/services/s3_service.py`
- [ChromaDB](https://github.com/metal-code/orbit/blob/main/backend/rag/vector_store.py): vector store · Embeddings and project-scoped semantic retrieval · `backend/rag/vector_store.py`
- [Redis](https://github.com/metal-code/orbit/blob/main/backend/services/chat_history_service.py): chat cache · Upstash-backed short-lived chat memory store · `backend/services/chat_history_service.py`
- [Mistral AI](https://github.com/metal-code/orbit/blob/main/backend/rag/llm.py): LLM · Generates answers from retrieved project context · `backend/rag/llm.py`
- [Gmail SMTP](https://github.com/metal-code/orbit/blob/main/backend/services/auth_service.py): email · Outbound OTP and report delivery · `backend/services/auth_service.py`

## Connections

- Routes → App shell: mounted in · Routes render inside the top-level shell
- Route tree → Routes: describes · Generated route metadata feeds file routes
- Routes → API client: calls · Screens use the shared HTTP client
- API client → HTTP routers: HTTP/JSON · Authenticated requests go to backend endpoints
- Query runtime → API client: hydrates from · Query runtime shares the API client
- Dashboard UI → Routes: composed in · Dashboard surface is assembled from route components
- Timeline UI → Routes: composed in · Timeline surface is assembled from route components
- Chat panel → Timeline UI: embedded in · Chat panel is part of project timeline UX
- Marketing pages → Remotion hero: uses · Landing page hero relies on the separate Remotion asset runtime
- API app → HTTP routers: registers · ASGI app mounts the HTTP routers
- HTTP routers → Auth layer: protects with · Routes use dependency-based auth checks
- HTTP routers → Services: delegates to · Routers stay thin and call service layer
- Services → Models: reads/writes · Services manipulate persistent domain entities
- Services → Schemas: validates with · Services exchange typed request/response data
- Models → SQLite: persisted in · Relational state lives in SQLite
- Services → S3: uploads to · Presigned upload flow stores files directly in S3
- RAG pipeline → ChromaDB: retrieves from · RAG searches indexed timeline embeddings
- RAG pipeline → Mistral AI: generates with · Retrieved context is sent to the LLM
- Chat history → Redis: stored in · Temporary chat memory is kept in Redis
- Services → RAG pipeline: invokes · Chat endpoints delegate answer generation to the RAG pipeline
- Services → Chat history: appends/reads · Chat services hydrate and update conversation history
- Services → Gmail SMTP: sends · OTP and report emails are delivered through SMTP
