- FastAPI backend with SQLModel, Alembic migrations, AgentScope agents - Next.js 15 frontend with React 19, Tailwind, Zustand, React Flow - Multi-provider AI system (DashScope, Kling, MiniMax, Volcengine, OpenAI, etc.) - All HTTP clients migrated from sync requests to async httpx - Admin-managed API keys via environment variables - SSRF vulnerability fixed in ensure_url()
126 lines
6.1 KiB
Markdown
126 lines
6.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Pixel is an AI-powered platform for creating comics and videos from scripts. It uses multi-agent systems (AgentScope) and multiple AI providers for image/video/audio generation.
|
|
|
|
## Repository Structure
|
|
|
|
- `backend/` — FastAPI (Python 3.12+), SQLModel/SQLAlchemy, Alembic migrations, AgentScope agents
|
|
- `frontend/` — Next.js 15 (App Router), React 19, Tailwind CSS, Zustand, @xyflow/react (canvas), TanStack Query
|
|
|
|
## Common Commands
|
|
|
|
### Backend
|
|
|
|
```bash
|
|
cd backend
|
|
uv sync # Install dependencies
|
|
uv run uvicorn src.main:app --reload --port 8000 # Start dev server
|
|
./start.sh # Alternative start script
|
|
alembic upgrade head # Apply DB migrations
|
|
alembic revision --autogenerate -m "desc" # Create migration
|
|
|
|
# Tests (pytest with asyncio_mode=auto)
|
|
pytest # All tests
|
|
pytest tests/test_models.py # Single test file
|
|
pytest -k "test_name" # Single test by name
|
|
pytest --cov=src # With coverage
|
|
|
|
# Code quality
|
|
black src/ && isort src/ # Format
|
|
flake8 src/ && mypy src/ # Lint
|
|
```
|
|
|
|
### Frontend
|
|
|
|
```bash
|
|
cd frontend
|
|
pnpm install # Install dependencies
|
|
pnpm dev # Start dev server (localhost:3000)
|
|
pnpm build # Production build
|
|
pnpm lint # ESLint
|
|
pnpm type-check # tsc --noEmit
|
|
pnpm format # ESLint --fix
|
|
|
|
# Tests
|
|
pnpm test # Vitest (watch mode)
|
|
pnpm test:run # Vitest (single run)
|
|
pnpm test:coverage # With coverage
|
|
pnpm e2e # Playwright E2E tests
|
|
|
|
# Regenerate API types after backend changes
|
|
pnpm gen:api
|
|
```
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
docker-compose up -d # Start all services (backend, frontend, redis, postgres)
|
|
docker-compose down # Stop services
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Backend Three-Layer Pattern
|
|
|
|
All backend code follows: **API Layer** → **Service Layer** → **Repository Layer**
|
|
|
|
- **API** (`src/api/`): FastAPI routers, request validation, response formatting. All endpoints prefixed with `/api/v1`.
|
|
- **Services** (`src/services/`): Business logic. Key services: `project_service`, `task_service`, `storyboard_service`, `storage_service`.
|
|
- **Repositories** (`src/repositories/`): Data access via SQLModel. Use `AsyncBaseRepository` (from `base_async.py`) for new code; the sync `BaseRepository` is deprecated.
|
|
- **Models** (`src/models/`): `entities.py` has SQLModel table definitions; `schemas/` has Pydantic request/response schemas.
|
|
- **Mappers** (`src/mappers/`): Convert between DB entities and API schemas.
|
|
|
|
### AI Provider System
|
|
|
|
Providers are registered via JSON config files in `src/config/services/`. The `ModelRegistry` (in `src/services/provider/registry.py`) is a thread-safe factory registry. Model IDs use composite format: `provider/model_key` (e.g., `dashscope/qwen-image`).
|
|
|
|
Provider implementations live in `src/services/provider/<provider_name>/`. Each provider module has an `image.py`, `video.py`, etc. Provider types: dashscope, volcengine, kling, minimax, modelscope, midjourney, openai, google.
|
|
|
|
The `ModelRegistry.get()` method creates fresh instances each call (factory pattern) to avoid shared state. Supports variant resolution and fallback models.
|
|
|
|
### Task Management
|
|
|
|
The `UnifiedTaskManager` (`src/services/task_manager/`) handles async generation tasks with priority queues, concurrency control, exponential backoff retries, and Prometheus metrics. Tasks are persisted in `TaskDB` with statuses: pending, processing, success, failed, timeout, retrying.
|
|
|
|
### Agent Engine
|
|
|
|
`src/services/agent_engine/` contains an AgentScope-based multi-agent system for script analysis and creative workflows. Skills are organized under `skills/` with film production (storyboarding, cinematography, screenwriting, sound design) and general (canvas workflow, project management, creative generation) categories.
|
|
|
|
### Frontend Architecture
|
|
|
|
- **App Router** (`src/app/`): Pages organized by feature — admin, canvas, login, register, etc.
|
|
- **State**: Zustand stores in `src/lib/store/` — `canvasStore.ts` (with slices: nodes, edges, groups, history, selection, persistence), `authStore.ts`, `modelStore.ts`, `uiStore.ts`.
|
|
- **API Client**: Auto-generated from OpenAPI spec into `src/lib/api/`. Services in `src/lib/api/services/` wrap the generated client. Auth token resolved from localStorage via `src/lib/client.ts`.
|
|
- **Canvas**: React Flow based infinite canvas (`src/components/canvas/`). Canvas state persisted via `persistenceSlice`.
|
|
- **UI Components**: Radix UI primitives in `src/components/ui/`, styled with Tailwind + class-variance-authority.
|
|
|
|
### API Proxy
|
|
|
|
In development, Next.js rewrites (`next.config.mjs`) proxy `/api/*`, `/files/*`, `/uploads/*`, `/chat/*`, `/health` to the backend at `API_URL` (default `http://localhost:8000`). In production, set `NEXT_PUBLIC_API_URL` for direct browser-to-backend calls.
|
|
|
|
### Database
|
|
|
|
- **Dev**: SQLite (default, no config needed)
|
|
- **Prod**: PostgreSQL 15+ via `DATABASE_URL`
|
|
- **ORM**: SQLModel (Pydantic v2 + SQLAlchemy)
|
|
- **Migrations**: Alembic in `backend/alembic/`
|
|
- **Cache**: Optional Redis for caching and rate limiting
|
|
|
|
### Middleware Stack (backend)
|
|
|
|
Applied in order: error handler → request tracking → response formatter → security headers → security → rate limiter → performance → metrics → tracing → GZip → CORS.
|
|
|
|
## Key Conventions
|
|
|
|
- Backend uses `uv` as package manager, not pip/poetry
|
|
- Frontend uses `pnpm`, not npm/yarn
|
|
- All generation endpoints return a `task_id`; poll `GET /api/v1/tasks/{task_id}` for results
|
|
- Model IDs must use composite format: `provider/model_key` — never pass a separate `provider` parameter
|
|
- JSON fields in SQLite use `sa_column=Column(JSON)` on SQLModel fields
|
|
- Timestamps stored as Unix floats (not datetime objects) with `TimestampMixin` for ISO conversion
|
|
- Soft delete pattern: `deleted_at` field, not physical deletion
|