Next.js React FastAPI Python Deepseek License
AI-powered multi-color flow cytometry panel design tool for immunologists and flow cytometry researchers.
PanelAgent combines deterministic algorithms with Large Language Model (LLM) evaluation to generate physically valid flow cytometry panels grounded in real antibody inventory data. It helps researchers design optimal antibody panels by considering spectral overlap, fluorochrome brightness, and experimental requirements.
- Background
- Features
- Tech Stack
- Architecture
- Getting Started
- Admin Interface
- Usage
- Project Structure
- API Reference
- Development
- Docker Deployment
- Contributing
- License
Flow cytometry panel design is a complex task requiring expertise in immunology, fluorescence spectroscopy, and instrument configuration. Researchers must balance multiple constraints:
- Spectral overlap between fluorochromes
- Antibody availability and quality
- Marker expression patterns on target cells
- Instrument detector configurations
PanelAgent addresses these challenges by providing an intelligent assistant that:
- Understands experimental goals through natural language descriptions
- Generates physically valid panels based on available antibody inventory
- Evaluates panel quality considering spectral characteristics
- Tracks antibody quality issues through a quality registry system
Describe your experimental goals in natural language and receive AI-recommended marker combinations tailored to your research needs.
Generate multi-color flow cytometry panels automatically based on:
- Available antibody inventory (human/mouse)
- Target markers and fluorochromes
- Spectral compatibility constraints
- Instrument channel configurations
Evaluate existing panels for:
- Spectral overlap issues
- Fluorochrome brightness compatibility
- Spillover spreading calculations
- Viability and data quality predictions
Track and manage antibody quality issues:
- Record lot-specific quality problems
- Project quality scores for specific markers
- View quality history and trends
- Export quality data for analysis
Get intelligent marker suggestions based on:
- Cell type identification requirements
- Functional marker requirements
- Lineage marker combinations
- Literature-based recommendations
Visualize fluorochrome spectral characteristics:
- Excitation/emission spectra
- Detector channel mappings
- Relative brightness comparisons
| Layer | Technology |
|---|---|
| User Frontend | Next.js 16.2.1, React 19.2.4, TypeScript |
| Admin Frontend | Next.js 16.2.1, React 19.2.4, TypeScript |
| UI Framework | shadcn/ui (Base UI + Tailwind CSS 4) |
| Charts | Recharts 3.8.1 |
| AI Integration | Vercel AI SDK, OpenAI API |
| Backend | FastAPI 0.115+, Python 3.13+ |
| Data Processing | Pandas, NumPy, SciPy |
| Reverse Proxy | Nginx (gateway) |
| Testing | Playwright (E2E), Pytest |
PanelAgent uses a dual-frontend architecture with a shared backend:
┌──────────────────┐
│ Gateway (nginx) │
│ localhost:8080 │
└────────┬─────────┘
│
┌───────────────┼───────────────┐
│ │ │
/admin/* /api/v1/* /*
│ │ │
┌────────▼──────┐ │ ┌────────▼──────┐
│ Admin Frontend │ │ │ User Frontend │
│ localhost:3001 │ │ │ localhost:3000 │
└────────┬──────┘ │ └────────┬──────┘
│ │ │
└──────────────┼───────────────┘
│
┌────────▼─────────┐
│ Backend │
│ localhost:8000 │
└──────────────────┘
| Service | Port | URL | Purpose |
|---|---|---|---|
| Backend | 8000 | http://localhost:8000 |
FastAPI REST API |
| User Frontend | 3000 | http://localhost:3000 |
User-facing Next.js app |
| Admin Frontend | 3001 | http://localhost:3001 |
Admin Next.js app |
| Gateway | 8080 | http://localhost:8080 |
Nginx reverse proxy (all services) |
The nginx gateway routes requests based on URL prefix:
| Browser Path | Routes To | Backend API Path |
|---|---|---|
/ |
User Frontend (3000) | — |
/exp-design |
User Frontend (3000) | — |
/panel-design |
User Frontend (3000) | — |
/quality-registry |
User Frontend (3000) | — |
/api/v1/* |
User Frontend (3000) → Backend (8000) | /api/v1/* |
/admin/login |
Admin Frontend (3001) | — |
/admin/settings |
Admin Frontend (3001) | — |
/admin/history |
Admin Frontend (3001) | — |
/admin/api/v1/* |
Admin Frontend (3001) → Backend (8000) | /api/v1/admin/* |
- Node.js 18+ and npm/pnpm
- Python 3.13+
- OpenAI API access (or compatible API endpoint)
- Docker (optional, for containerized deployment)
- Clone the repository:
git clone https://github.com/your-org/PanelAgent.git
cd PanelAgent- Install backend dependencies:
cd backend
pip install -r requirements.txt- Install user frontend dependencies:
cd frontend
npm install- Install admin frontend dependencies:
cd admin-frontend
npm installCreate environment files with your configuration:
Backend (backend/.env or root .env):
# OpenAI API Configuration OPENAI_API_BASE=https://api.openai.com/v1 OPENAI_API_KEY=sk-your-api-key OPENAI_MODEL_NAME=gpt-4o # Admin Authentication ADMIN_PASSWORD=your-secure-admin-password ADMIN_SESSION_SECRET=your-session-secret # auto-generated if omitted
User Frontend (frontend/.env.local):
# Backend API URL (internal) BACKEND_INTERNAL_URL=http://127.0.0.1:8000 # Public backend URL (if different) BACKEND_PUBLIC_URL=http://localhost:8000
Admin Frontend (admin-frontend/.env.local):
# Backend API URL (internal)
BACKEND_INTERNAL_URL=http://127.0.0.1:8000| Variable | Service | Required | Description |
|---|---|---|---|
OPENAI_API_KEY |
Backend | Yes | OpenAI API key for LLM features |
OPENAI_API_BASE |
Backend | No | Custom API endpoint (default: OpenAI) |
OPENAI_MODEL_NAME |
Backend | No | Model to use (default: gpt-4o) |
ADMIN_PASSWORD |
Backend | Yes | Password for admin login |
ADMIN_SESSION_SECRET |
Backend | No | Session encryption key (auto-generated if missing) |
BACKEND_INTERNAL_URL |
Frontend/Admin | Yes | Backend URL for server-side API calls |
BACKEND_PUBLIC_URL |
Frontend | No | Public-facing backend URL |
Start all services at once:
make dev-all
Or start individual services:
make dev-backend # Backend on port 8000 make dev-frontend # User frontend on port 3000 make dev-admin-frontend # Admin frontend on port 3001
Terminal 1 — Backend:
cd backend
uvicorn app.main:app --reload --port 8000Terminal 2 — User Frontend:
cd frontend
npm run devTerminal 3 — Admin Frontend:
cd admin-frontend
npm run dev -- --port 3001docker compose build docker compose up -d
This starts all services including the nginx gateway on port 8080.
| Interface | URL |
|---|---|
| User App (direct) | http://localhost:3000 |
| Admin App (direct) | http://localhost:3001/login |
| All services (gateway) | http://localhost:8080 |
| Admin (via gateway) | http://localhost:8080/admin/login |
| API (via gateway) | http://localhost:8080/api/v1/ |
The admin interface provides system management capabilities separate from the user-facing application.
- Via gateway:
http://localhost:8080/admin/login - Direct:
http://localhost:3001/login
Log in using the password configured via the ADMIN_PASSWORD environment variable. The session is managed server-side with cookies.
| Page | Path | Description |
|---|---|---|
| Login | /admin/login |
Admin authentication |
| Settings | /admin/settings |
LLM model configuration, API keys |
| History | /admin/history |
Panel generation history and audit |
| Quality Registry | /admin/quality-registry |
Review, resolve, and manage quality issues |
All admin API endpoints are prefixed with /api/v1/admin/ and require authentication:
| Endpoint | Method | Description |
|---|---|---|
/api/v1/admin/auth/login |
POST | Admin login |
/api/v1/admin/auth/logout |
POST | Admin logout |
/api/v1/admin/auth/session |
GET | Check session status |
/api/v1/admin/settings/llm |
GET/PUT | LLM configuration |
/api/v1/admin/panel-history |
GET | Panel history list |
/api/v1/admin/panel-history/{id} |
GET | Panel history detail |
/api/v1/admin/quality-registry/* |
Various | Quality issue management |
Navigate to /exp-design and describe your experiment:
I want to identify T cell subsets in human blood, including CD4+ and CD8+ populations,
and assess their activation state and memory phenotype.
The AI will suggest appropriate markers and generate a panel design strategy.
Use /panel-design to:
- Select target species (human/mouse)
- Specify required markers
- Set fluorochrome preferences
- Generate panels with the "Generate" button
- Review panel recommendations
Access /quality-registry to:
- View existing quality records
- Add new quality issues for antibody lots
- Filter by marker, catalog number, or issue type
- Export data for analysis
PanelAgent/
├── frontend/ # User-facing Next.js application (port 3000)
│ ├── src/
│ │ ├── app/ # App Router pages
│ │ │ ├── page.tsx # Dashboard home
│ │ │ ├── exp-design/ # AI experimental design
│ │ │ ├── panel-design/ # Panel generation
│ │ │ └── quality-registry/ # Quality registry
│ │ ├── components/ # React components
│ │ │ ├── ui/ # shadcn/ui components
│ │ │ └── spectra-chart.tsx # Spectral visualization
│ │ └── lib/ # Utilities and hooks
│ │ ├── api/ # OpenAPI-generated client
│ │ └── hooks/ # Custom React hooks
│ ├── public/ # Static assets
│ └── package.json
│
├── admin-frontend/ # Admin Next.js application (port 3001)
│ ├── src/
│ │ ├── app/ # App Router pages
│ │ │ ├── login/ # Admin login
│ │ │ ├── settings/ # System settings
│ │ │ ├── history/ # Panel history
│ │ │ └── quality-registry/ # Quality management
│ │ ├── components/ # Admin-specific components
│ │ └── lib/ # Admin utilities
│ └── package.json
│
├── backend/ # FastAPI application (port 8000)
│ ├── app/
│ │ ├── api/v1/endpoints/ # API route handlers
│ │ │ ├── panels.py # Panel operations
│ │ │ ├── quality_registry.py # Quality CRUD
│ │ │ ├── recommendations.py # Marker suggestions
│ │ │ └── spectra.py # Spectral data
│ │ ├── services/ # Business logic
│ │ ├── schemas/ # Pydantic models
│ │ └── core/ # Configuration
│ └── requirements.txt
│
├── gateway/ # Nginx reverse proxy (port 8080)
│ └── nginx.conf # Gateway routing configuration
│
├── inventory/ # Antibody inventory CSVs
│ ├── human_inventory.csv
│ └── mouse_inventory.csv
│
├── data/ # Static reference data
│ ├── channel_mapping.csv # Instrument channels
│ ├── fluorochrome_brightness.csv
│ └── spectra/ # Spectral data files
│
├── docs/ # Documentation
│ └── route-ownership-matrix.md
│
├── tests/ # Python tests
├── docker-compose.yml # Multi-service Docker stack
├── Dockerfile.backend # Backend container image
├── Dockerfile.frontend # Frontend container image (shared)
├── Makefile # Project commands
└── .agents/ # Agent skill configurations
| Endpoint | Method | Description |
|---|---|---|
/api/v1/panels/generate |
POST | Generate a new panel |
/api/v1/panels/diagnose |
POST | Diagnose panel issues |
/api/v1/panels/evaluate |
POST | Evaluate panel quality |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/quality-registry/issues |
POST | Submit a quality issue |
/api/v1/quality-registry/candidates/lookup |
POST | Lookup antibody candidates |
/api/v1/quality-registry/candidates/confirm |
POST | Confirm candidate selection |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/recommendations/markers |
POST | Get marker recommendations |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/spectra |
GET | List available spectra |
/api/v1/spectra/{marker} |
GET | Get specific spectrum data |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/health |
GET | Health check |
All admin endpoints require session authentication.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/admin/auth/login |
POST | Admin login |
/api/v1/admin/auth/logout |
POST | Admin logout |
/api/v1/admin/auth/session |
GET | Check session status |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/admin/settings/llm |
GET | Get LLM configuration |
/api/v1/admin/settings/llm |
PUT | Update LLM configuration |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/admin/panel-history |
GET | List panel history entries |
/api/v1/admin/panel-history/{id} |
GET | Get panel history detail |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/admin/quality-registry/issues |
GET | List all quality issues |
/api/v1/admin/quality-registry/issues/{id} |
GET | Get issue detail |
/api/v1/admin/quality-registry/issues/{id} |
PUT | Update an issue |
/api/v1/admin/quality-registry/issues/{id}/history |
GET | Issue audit history |
/api/v1/admin/quality-registry/review-queue |
GET | Get review queue |
/api/v1/admin/quality-registry/review-queue/{id}/resolve |
POST | Resolve an issue |
# Dev servers make dev-backend # Start backend server (port 8000) make dev-frontend # Start user frontend (port 3000) make dev-admin-frontend # Start admin frontend (port 3001) make dev-all # Start all three services # Quality checks make test-backend # Run Python tests (pytest) make lint-backend # Lint Python code (ruff) make lint-frontend # Lint user frontend TypeScript (eslint) make lint-admin-frontend # Lint admin frontend TypeScript (eslint) make typecheck-frontend # User frontend TypeScript type check make typecheck-admin-frontend # Admin frontend TypeScript type check make generate-client # Generate OpenAPI client make e2e-frontend # Run Playwright E2E tests make check-all # Run all quality gates
When backend API changes, regenerate the frontend client:
make generate-client
This creates TypeScript types and API client from the FastAPI OpenAPI schema.
Backend tests:
cd backend
pytest tests/Frontend E2E tests:
cd frontend
npm run test:e2e# Build all images docker compose build # Start all services docker compose up -d # Check status docker compose ps # View logs docker compose logs -f # Stop docker compose down
docker compose logs -f backend docker compose logs -f frontend docker compose logs -f admin-frontend docker compose logs -f gateway
| Service | URL |
|---|---|
| User App | http://localhost:3000 |
| Admin App | http://localhost:3001 |
| Backend API | http://localhost:8000 |
| Gateway (all-in-one) | http://localhost:8080 |
The nginx gateway on port 8080 provides unified access:
http://localhost:8080/→ User frontendhttp://localhost:8080/admin/→ Admin frontendhttp://localhost:8080/api/v1/→ Backend API (via user frontend proxy)http://localhost:8080/admin/api/v1/→ Admin API (via admin frontend proxy)
PanelAgent is designed to be portable across laboratories. When migrating to a new lab, you need to replace lab-specific data while keeping the general-purpose computation logic intact.
Step 1: 替换数据层 — 替换抗体库存 CSV + 确认通道映射
Step 2: 修改配置层 — 管理员密码 + API Key + CORS + 物种映射
Step 3: 清理历史层 — 删除 SQLite 库 + 清空质量登记数据
| # | Item | File(s) | Action Required |
|---|---|---|---|
| 1 | Antibody inventory CSVs | inventory/*.csv |
Replace with new lab's antibody database (human + mouse) |
| 2 | Admin password | docker-compose.yml |
Change ADMIN_PASSWORD — the default is insecure |
| 3 | Session secret | docker-compose.yml |
Change ADMIN_SESSION_SECRET or leave blank for auto-generation |
| 4 | AI API credentials | .env |
Fill in API key, base URL, and model name |
| 5 | CORS origins | docker-compose.yml |
Add new lab's deployment IPs/domains to BACKEND_CORS_ORIGINS |
| 6 | Dev origin whitelist | frontend/.env.local |
Add developers' machine IPs to ALLOWED_DEV_ORIGINS |
| 7 | Species→filename mapping | backend/app/core/config.py |
Update SPECIES_INVENTORY_MAP to match actual CSV filenames |
| 8 | Historical data cleanup | data/admin_console.sqlite3, data/quality_registry/ |
Delete SQLite DB, clear issues/audit/projection files |
| Category | Files | Reason |
|---|---|---|
| Spectral data | spectral_data.json |
Fluorochrome spectra are inherent physical properties — valid worldwide |
| Brightness ratings | fluorochrome_brightness.json |
Relative brightness (PE=×ばつ2) is a known ranking |
| All algorithms | panel_generator.py, data_preprocessing.py |
Panel generation logic is laboratory-agnostic |
| All backend code | backend/ |
API, services, schemas are all generic |
| All frontend code | frontend/, admin-frontend/ |
UI is fully reusable |
| Infrastructure | docker-compose.yml, gateway/nginx.conf |
Architecture reusable; only parameter values change |
| Scenario | Need to Check |
|---|---|
| Different cytometer model | channel_mapping.json — may need full rewrite |
| Different CSV column names | data_preprocessing.py — column_mapping logic |
| Non-human/non-mouse species | panel_generator.py — _infer_marker_type() hardcoded lists |
| English interface language | llm_api_client.py system prompt + all frontend UI text |
| Different server ports | docker-compose.yml ports mapping |
A detailed, AI-Agent-friendly migration guide is available at docs/MIGRATION.md. This document is structured for coding assistants (like Claude, Cursor, etc.) to read and execute migration steps interactively.
To perform migration with an AI agent:
# Ask your AI coding assistant to load the migration guide # The agent will: # 1. Walk through each required change # 2. Ask for new lab's specific data (CSV files, API key, etc.) # 3. Execute file modifications # 4. Validate the result
Contributions are welcome! Please follow these guidelines:
- Fork and branch: Create a feature branch from
main - Code quality: Run
make check-allbefore committing - Tests: Add tests for new functionality
- Documentation: Update relevant documentation
- Pull request: Submit PR with clear description
- Install development dependencies:
pip install -r backend/requirements.txt cd frontend && npm install cd admin-frontend && npm install
- Set up pre-commit hooks (optional):
pre-commit install
- Python: Follow PEP 8, enforced by Ruff
- TypeScript: ESLint + Prettier configuration
- Commits: Conventional commit messages preferred
This project is licensed under the MIT License - see the LICENSE file for details.
Maintainers: Pan Chongshi
Acknowledgments:
- OpenAI for GPT API access
- shadcn/ui for excellent component library
- FastAPI and Next.js communities