# cangiolo/sccloud architecture

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

- Interactive diagram: https://gitdiagram.com/cangiolo/sccloud
- Repository: https://github.com/cangiolo/sccloud
- Video tour (about a minute): https://gitdiagram.com/cangiolo/sccloud/video

## Overview

scCloud is a browser-based single-cell RNA-seq analysis application. Users authenticate, create projects, upload and inspect expression data, configure a pipeline, then review and download analysis results. The backend coordinates project and task APIs with R computation; pipeline execution includes quality control, clustering, annotation, and optional downstream analyses such as markers, enrichment, CellChat, trajectory, and inferCNV. MariaDB stores metadata, while Redis supports queued work and progress. The README documents capabilities beyond the sampled implementation excerpts, so those branches are shown at subsystem level.

Main entry points: [`frontend/src/app/lib/api.ts`](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/lib/api.ts) (API client), [`backend/app/main.py`](https://github.com/cangiolo/sccloud/blob/main/backend/app/main.py) (FastAPI app), [`backend/app/db/models.py`](https://github.com/cangiolo/sccloud/blob/main/backend/app/db/models.py) (Metadata models), [`backend/app/upload/router.py`](https://github.com/cangiolo/sccloud/blob/main/backend/app/upload/router.py) (Chunked upload)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web application"]
  node_authui["Sign-in UI<br/>[AuthModal.tsx]"]
  node_api_client["API client<br/>[api.ts]"]
  node_project_ui["Project dashboard<br/>[page.tsx]"]
  node_upload_ui["Upload interface"]
  node_analysis_ui["Pipeline form<br/>[PipelineForm.tsx]"]
  node_pipeline_view["Pipeline view<br/>[PipelineView.tsx]"]
  node_results_ui["Results viewer<br/>[ResultViewer.tsx]"]
  node_convert_ui["Format conversion<br/>[page.tsx]"]
end

subgraph group_api["Backend APIs"]
  node_app["FastAPI app<br/>[main.py]"]
  node_auth["Authentication<br/>[router.py]"]
  node_projects["Project management<br/>[router.py]"]
  node_upload["Chunked upload<br/>[router.py]"]
  node_conversion["Conversion API<br/>[router.py]"]
  node_tasks["Task API<br/>[router.py]"]
  node_pipeline["Pipeline API<br/>[router.py]"]
end

subgraph group_compute["Analysis execution"]
  node_executor["Pipeline executor<br/>[executor.py]"]
  node_bridge["R bridge<br/>[r_bridge.py]"]
  node_r_engine["R analysis engine"]
end

subgraph group_state["Persistence and queues"]
  node_metadata[("Metadata models<br/>[models.py]")]
  node_project_files[("Project data files")]
  node_redis["Redis queue"]
  node_progress["Progress syncer<br/>[progress_syncer.py]"]
end

node_user(("Researcher"))

node_user -->|"signs in"| node_authui
node_user -->|"manages projects"| node_project_ui
node_user -->|"uploads data"| node_upload_ui
node_user -->|"configures analysis"| node_analysis_ui
node_user -->|"reviews results"| node_results_ui
node_authui -->|"uses"| node_api_client
node_analysis_ui -->|"opens"| node_pipeline_view
node_analysis_ui -->|"creates pipeline"| node_api_client
node_pipeline_view -->|"submits tasks"| node_api_client
node_pipeline_view -->|"renders results"| node_results_ui
node_project_ui -->|"fetches projects"| node_api_client
node_upload_ui -.->|"uploads chunks"| node_api_client
node_convert_ui -->|"requests conversion"| node_api_client
node_api_client -->|"calls API"| node_app
node_app -->|"registers routes"| node_auth
node_app -->|"registers routes"| node_projects
node_app -->|"registers routes"| node_tasks
node_app -->|"registers routes"| node_pipeline
node_auth -->|"queries users"| node_metadata
node_projects -->|"reads project records"| node_metadata
node_projects -.->|"manages files"| node_project_files
node_upload -->|"checks projects"| node_metadata
node_upload -.->|"stores uploads"| node_project_files
node_upload -->|"inspects data"| node_r_engine
node_conversion -.->|"converts formats"| node_r_engine
node_tasks -->|"records tasks"| node_metadata
node_tasks -->|"requests computation"| node_r_engine
node_pipeline -->|"stores pipeline"| node_metadata
node_pipeline -->|"starts execution"| node_executor
node_executor -->|"updates status"| node_metadata
node_executor -->|"calls bridge"| node_bridge
node_bridge -->|"dispatches jobs"| node_r_engine
node_bridge -->|"queues heavy work"| node_redis
node_app -->|"starts syncer"| node_progress
node_progress -->|"syncs progress"| node_metadata
node_progress -.->|"reads progress"| node_redis

click node_authui "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/components/AuthModal.tsx"
click node_api_client "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/lib/api.ts"
click node_project_ui "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/page.tsx"
click node_upload_ui "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/components/FileUploadModal.tsx"
click node_analysis_ui "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/analysis/components/PipelineForm.tsx"
click node_pipeline_view "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/analysis/components/PipelineView.tsx"
click node_results_ui "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/components/ResultViewer.tsx"
click node_convert_ui "https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/convert/page.tsx"
click node_app "https://github.com/cangiolo/sccloud/blob/main/backend/app/main.py"
click node_auth "https://github.com/cangiolo/sccloud/blob/main/backend/app/auth/router.py"
click node_projects "https://github.com/cangiolo/sccloud/blob/main/backend/app/projects/router.py"
click node_upload "https://github.com/cangiolo/sccloud/blob/main/backend/app/upload/router.py"
click node_conversion "https://github.com/cangiolo/sccloud/blob/main/backend/app/convert/router.py"
click node_tasks "https://github.com/cangiolo/sccloud/blob/main/backend/app/tasks/router.py"
click node_pipeline "https://github.com/cangiolo/sccloud/blob/main/backend/app/pipeline/router.py"
click node_executor "https://github.com/cangiolo/sccloud/blob/main/backend/app/pipeline/executor.py"
click node_bridge "https://github.com/cangiolo/sccloud/blob/main/backend/app/utils/r_bridge.py"
click node_metadata "https://github.com/cangiolo/sccloud/blob/main/backend/app/db/models.py"
click node_progress "https://github.com/cangiolo/sccloud/blob/main/backend/app/utils/progress_syncer.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_authui,node_api_client,node_project_ui,node_upload_ui,node_analysis_ui,node_pipeline_view,node_results_ui,node_convert_ui toneBlue
class node_app,node_auth,node_projects,node_upload,node_conversion,node_tasks,node_pipeline toneAmber
class node_executor,node_bridge,node_r_engine toneMint
class node_metadata,node_project_files,node_redis,node_progress toneRose
class node_user toneIndigo
```

## Components

### Web application

- [Sign-in UI](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/components/AuthModal.tsx): `frontend/src/app/components/AuthModal.tsx`
- [API client](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/lib/api.ts): `frontend/src/app/lib/api.ts`
- [Project dashboard](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/page.tsx): `frontend/src/app/dashboard/page.tsx`
- [Upload interface](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/components/FileUploadModal.tsx): `frontend/src/app/components/FileUploadModal.tsx`
- [Pipeline form](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/analysis/components/PipelineForm.tsx): `frontend/src/app/dashboard/analysis/components/PipelineForm.tsx`
- [Pipeline view](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/analysis/components/PipelineView.tsx): `frontend/src/app/dashboard/analysis/components/PipelineView.tsx`
- [Results viewer](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/components/ResultViewer.tsx): `frontend/src/app/components/ResultViewer.tsx`
- [Format conversion](https://github.com/cangiolo/sccloud/blob/main/frontend/src/app/dashboard/convert/page.tsx): `frontend/src/app/dashboard/convert/page.tsx`

### Backend APIs

- [FastAPI app](https://github.com/cangiolo/sccloud/blob/main/backend/app/main.py): `backend/app/main.py`
- [Authentication](https://github.com/cangiolo/sccloud/blob/main/backend/app/auth/router.py): `backend/app/auth/router.py`
- [Project management](https://github.com/cangiolo/sccloud/blob/main/backend/app/projects/router.py): `backend/app/projects/router.py`
- [Chunked upload](https://github.com/cangiolo/sccloud/blob/main/backend/app/upload/router.py): `backend/app/upload/router.py`
- [Conversion API](https://github.com/cangiolo/sccloud/blob/main/backend/app/convert/router.py): `backend/app/convert/router.py`
- [Task API](https://github.com/cangiolo/sccloud/blob/main/backend/app/tasks/router.py): `backend/app/tasks/router.py`
- [Pipeline API](https://github.com/cangiolo/sccloud/blob/main/backend/app/pipeline/router.py): `backend/app/pipeline/router.py`

### Analysis execution

- [Pipeline executor](https://github.com/cangiolo/sccloud/blob/main/backend/app/pipeline/executor.py): `backend/app/pipeline/executor.py`
- [R bridge](https://github.com/cangiolo/sccloud/blob/main/backend/app/utils/r_bridge.py): `backend/app/utils/r_bridge.py`
- **R analysis engine**

### Persistence and queues

- [Metadata models](https://github.com/cangiolo/sccloud/blob/main/backend/app/db/models.py): `backend/app/db/models.py`
- **Project data files**
- **Redis queue**
- [Progress syncer](https://github.com/cangiolo/sccloud/blob/main/backend/app/utils/progress_syncer.py): `backend/app/utils/progress_syncer.py`

### Other components

- **Researcher**

## Connections

- Researcher → Sign-in UI: signs in
- Researcher → Project dashboard: manages projects
- Researcher → Upload interface: uploads data
- Researcher → Pipeline form: configures analysis
- Researcher → Results viewer: reviews results
- Sign-in UI → API client: uses (evidence: `frontend/src/app/components/AuthModal.tsx`)
- Pipeline form → Pipeline view: opens (evidence: `frontend/src/app/dashboard/analysis/page.tsx`)
- Pipeline form → API client: creates pipeline (evidence: `frontend/src/app/dashboard/analysis/components/PipelineForm.tsx`)
- Pipeline view → API client: submits tasks (evidence: `frontend/src/app/dashboard/analysis/components/PipelineView.tsx`)
- Pipeline view → Results viewer: renders results (evidence: `frontend/src/app/dashboard/analysis/components/PipelineView.tsx`)
- Project dashboard → API client: fetches projects (evidence: `frontend/src/app/dashboard/page.tsx`)
- Upload interface → API client: uploads chunks
- Format conversion → API client: requests conversion (evidence: `frontend/src/app/dashboard/convert/page.tsx`)
- API client → FastAPI app: calls API
- FastAPI app → Authentication: registers routes (evidence: `backend/app/main.py`)
- FastAPI app → Project management: registers routes (evidence: `backend/app/main.py`)
- FastAPI app → Task API: registers routes (evidence: `backend/app/main.py`)
- FastAPI app → Pipeline API: registers routes (evidence: `backend/app/main.py`)
- Authentication → Metadata models: queries users (evidence: `backend/app/auth/router.py`)
- Project management → Metadata models: reads project records (evidence: `backend/app/projects/router.py`)
- Project management → Project data files: manages files
- Chunked upload → Metadata models: checks projects (evidence: `backend/app/upload/router.py`)
- Chunked upload → Project data files: stores uploads
- Chunked upload → R analysis engine: inspects data (evidence: `backend/app/upload/router.py`)
- Conversion API → R analysis engine: converts formats
- Task API → Metadata models: records tasks (evidence: `backend/app/tasks/router.py`)
- Task API → R analysis engine: requests computation (evidence: `backend/app/tasks/router.py`)
- Pipeline API → Metadata models: stores pipeline (evidence: `backend/app/pipeline/router.py`)
- Pipeline API → Pipeline executor: starts execution (evidence: `backend/app/pipeline/router.py`)
- Pipeline executor → Metadata models: updates status (evidence: `backend/app/pipeline/executor.py`)
- Pipeline executor → R bridge: calls bridge (evidence: `backend/app/pipeline/executor.py`)
- R bridge → R analysis engine: dispatches jobs (evidence: `backend/app/utils/r_bridge.py`)
- R bridge → Redis queue: queues heavy work (evidence: `backend/app/utils/r_bridge.py`)
- FastAPI app → Progress syncer: starts syncer (evidence: `backend/app/main.py`)
- Progress syncer → Metadata models: syncs progress (evidence: `backend/app/utils/progress_syncer.py`)
- Progress syncer → Redis queue: reads progress
