22 KiB
22 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
项目概述
美家卡智影 (Meijiaka AI Video) - AI 视频创作平台。一个 AI 驱动的桌面应用,采用 Tauri + React + FastAPI 混合架构,用户可以通过 AI 生成脚本、创建数字人视频,自动生成字幕,最终本地合成完整的营销视频。
环境要求
| 组件 | 版本要求 |
|---|---|
| Python | 3.13+ (代码使用 ` |
| Node.js | 20+ |
| Rust | 1.70+ |
| Docker | 20+ (可选,用于数据库) |
核心设计理念:轻量云账号 + 全本地业务数据 - 云端只存储用户认证和使用日志,所有项目/脚本/媒体都存在用户本地。
架构
混合架构
- FastAPI 后端: 处理 AI 模型调用、用户认证、API 服务
- Tauri + React 前端: 桌面 UI,React 负责渲染,Tauri 提供系统能力
- Rust 后端: 通过 Tauri IPC 处理本地操作(FFmpeg 视频处理、文件系统访问)
存储策略
核心设计理念:轻量云账号 + 全本地业务数据 - 云端只存储用户认证和使用日志,所有项目/脚本/媒体都存在用户本地。
- 云端: PostgreSQL 只存储 2 张表:
users(用户账户)、model_usage_logs(用量统计)avatars表已废弃:数字人名片元数据现在纯本地存储avatars.json
- 本地: JSON 文件存储项目/脚本/分镜数据、数字人元数据,用户磁盘存储媒体文件,FFmpeg 处理视频合成
- 缓存/队列: Redis + Async Engine Scheduler 处理异步任务
混合通信模式
| 通信模式 | 使用场景 | 前端调用方式 |
|---|---|---|
| HTTP → FastAPI | AI 生成、认证、配置管理 | client.get/post/put/delete() |
| Tauri IPC → Rust | FFmpeg 视频处理、本地文件系统 | ipc.request() 或直接 invoke() |
通信模块:
tauri-app/src/api/client.ts- HTTP 客户端,自动处理 camelCase/snake_case 转换tauri-app/src/api/ipc.ts- IPC 客户端tauri-app/src/api/modules/localStorage.ts- 本地项目存储(走 IPC)tauri-app/src/api/modules/videoComposite.ts- 视频合成(走 IPC)
AI Provider 架构
后端 AI 模块采用多 Provider 设计:
app/ai/model_router.py- 模型路由器,支持自动降级app/ai/providers/base.py- 抽象基类app/ai/providers/*- 具体实现(OpenAI、火山引擎、KlingAI 等)app/ai/prompts/- 提示词模板文件
支持的 AI 平台:火山方舟(推荐)、OpenAI、百度文心一言、阿里云通义千问、KlingAI(数字人视频生成)。
模型配置文件:python-api/config/ai_models.yaml(支持热重载)
Token 管理
外部 API 认证 Token 使用 app/core/token_manager.py 统一管理:
- Token 缓存(避免重复生成)
- 自动刷新(Token 即将过期时自动刷新)
- 并发安全(双重检查锁定)
- 支持 JWT、OAuth2 等多种策略
数据流
- 脚本生成: 用户输入 → FastAPI AI 代理 → 标准化输出 → 前端保存到本地 JSON
- 数字人视频: 后端调用 KlingAI API → 返回视频 URL → 前端下载并本地存储
- 视频合成: 前端 → Tauri IPC → Rust 后端 → FFmpeg → 渲染最终视频文件
本地存储结构(用户机器)
~/Documents/Meijiaka/
├── config.json # 全局应用配置
├── projects/
│ └── {project_id}/
│ ├── meta.json # 项目元数据
│ ├── segments.json # 脚本/分镜数据
│ └── assets/ # 媒体文件
├── avatars/
│ └── {avatar_id}/
│ ├── meta.json # 数字人名片配置
│ └── source.mp4 # 源视频
└── cache/ # 临时文件
目录结构
ai-meijiaka/
├── python-api/ # FastAPI 后端服务
│ ├── app/
│ │ ├── api/v1/ # REST API 端点
│ │ ├── ai/ # AI 模型路由和 Provider
│ │ ├── ai/prompts/ # 提示词模板文件
│ │ ├── core/ # 安全、配置、异常处理
│ │ ├── db/ # 数据库配置
│ │ ├── models/ # SQLAlchemy 数据模型
│ │ ├── schemas/ # Pydantic 验证模型
│ │ ├── services/ # 业务逻辑和 AI 服务代理
│ │ ├── scheduler/ # Async Engine 统一异步调度器
│ │ ├── config.py # 配置管理
│ │ └── main.py # 应用入口
│ ├── config/ # AI 模型配置(YAML)
│ ├── tests/ # pytest 测试套件
│ ├── scripts/ # 管理和测试脚本
│ └── docker-compose.yml # Docker 服务编排
│
├── tauri-app/ # Tauri 桌面应用
│ ├── src/ # React 前端源码
│ │ ├── api/ # API 客户端和类型
│ │ │ ├── adapters/ # 前后端字段差异适配
│ │ │ ├── generated/ # OpenAPI 自动生成类型
│ │ │ └── modules/ # API 模块封装
│ │ ├── components/ # 可复用 React 组件
│ │ ├── pages/ # 页面组件(路由)
│ │ ├── store/ # Zustand 全局状态管理
│ │ ├── hooks/ # 自定义 React Hooks
│ │ └── utils/ # 前端工具函数
│ ├── src-tauri/ # Rust 后端
│ │ ├── src/
│ │ │ ├── lib.rs # Tauri 应用入口,命令注册
│ │ │ ├── commands/ # 按领域拆分的命令模块
│ │ │ │ ├── asset.rs # 资源文件操作
│ │ │ │ ├── auth_state.rs # 认证状态管理
│ │ │ │ ├── avatar.rs # 数字人头像管理
│ │ │ │ ├── product.rs # 产品相关
│ │ │ │ └── project.rs # 项目存储操作
│ │ │ ├── storage/ # 存储引擎分层
│ │ │ │ ├── mod.rs # 模块导出
│ │ │ │ ├── paths.rs # 路径计算
│ │ │ │ ├── engine.rs # 核心存储引擎(原子写+文件锁)
│ │ │ │ ├── auth.rs # 认证存储
│ │ │ │ ├── project.rs # 项目存储
│ │ │ │ ├── avatar.rs # 头像存储
│ │ │ │ └── cache.rs # 缓存存储
│ │ │ ├── ffmpeg_cmd.rs # FFmpeg 命令封装
│ │ │ ├── video_processing.rs # 视频合成逻辑
│ │ │ ├── api_proxy.rs # Python API 代理
│ │ │ ├── avatar_cache.rs # 头像视频缓存管理
│ │ │ └── utils.rs # 通用工具函数
│ │ ├── binaries/ # 嵌入的 FFmpeg 可执行文件
│ │ └── Cargo.toml # Rust 依赖配置
│ └── package.json # NPM 依赖和脚本
│
└── docs/ # 开发文档
常用命令
后端 (python-api)
项目使用 uv 进行依赖管理,并提供了 Makefile 封装常用命令:
cd python-api
# 使用 uv 和 Makefile(推荐)
make dev # 安装开发依赖并配置 pre-commit
make docker-run # 使用 Docker Compose 启动所有服务(db, redis, api, scheduler)
make run # 启动 FastAPI 开发服务器
make scheduler # 启动 Async Engine Scheduler
make lint # 运行代码检查 (ruff + mypy)
make format # 格式化代码
make test # 运行所有测试
make security # 运行安全扫描 (bandit + pip-audit)
# 手动方式
# 安装依赖
python -m venv venv && source venv/bin/activate
pip install -e ".[dev]"
# 启动 PostgreSQL + Redis(必需)
docker-compose up -d db redis
# 启动 FastAPI 开发服务器
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# 启动 Async Engine Scheduler(另开终端)
python -m app.scheduler.main
# 代码质量
black app/ # 格式化代码(行宽 100)
ruff check app/ # 代码检查
mypy app/ # 严格类型检查
bandit -c pyproject.toml -r app/ # 安全扫描
pip-audit # 依赖漏洞检测
python scripts/check_config_architecture.py # 检查配置架构一致性
# 导出 OpenAPI 文档到前端
python3 -c "
import logging
logging.disable(logging.WARNING)
from app.main import app
import json
print(json.dumps(app.openapi(), indent=2, ensure_ascii=False))
" > ../tauri-app/src/api/generated/openapi.json
# 测试
pytest # 运行所有测试
pytest tests/test_script.py -v # 运行单个测试文件
pytest --cov=app # 覆盖率报告
# Docker
docker-compose up -d # 启动所有服务(db, redis, api, scheduler)
# 端口占用检查
lsof -i :8080 # 检查 8080 端口占用
可用 Makefile 命令:
| 命令 | 用途 |
|---|---|
make help |
显示帮助信息 |
make install |
安装生产依赖(使用 lock 文件) |
make dev |
安装开发依赖并配置 pre-commit |
make update-lock |
更新 requirements.lock |
make lint |
运行代码检查 (ruff + mypy) |
make format |
格式化代码 (black + ruff) |
make format-check |
检查代码格式(不修改) |
make test |
运行测试 |
make test-cov |
运行测试并生成覆盖率报告 |
make security |
运行安全扫描 |
make run |
启动开发服务器 |
make scheduler |
启动 Async Engine Scheduler |
make docker-run |
Docker Compose 启动全部服务 |
make docker-down |
停止 Docker 服务 |
make clean |
清理缓存文件 |
make ci |
运行所有 CI 检查 |
前端 (tauri-app)
cd tauri-app
# 安装依赖
npm install
# 开发
npm run dev # 仅启动 Vite(不打开 Tauri 窗口)
npm run tauri dev # 完整 Tauri 桌面开发模式
# 构建
npm run build # 前端生产构建
npm run tauri build # 打包桌面应用(.dmg/.exe/.AppImage)
# 代码质量
npm run lint # ESLint 检查 JS/TS
npm run lint:fix # ESLint 自动修复
npm run format # Prettier 格式化代码
npm run stylelint # CSS 检查
# 测试
npm run test # 运行 Vitest
npm run test:coverage # 覆盖率报告
npm run test:ui # 打开 Vitest UI
# 类型生成
npm run gen:api # 从 OpenAPI schema 生成 TypeScript 类型
数据库迁移
项目使用 Alembic 进行数据库迁移:
cd python-api
# 生成新迁移(修改模型后)
alembic revision --autogenerate -m "description"
# 应用迁移
alembic upgrade head
# 回滚迁移
alembic downgrade -1
开发提示
- Tauri 调试: 使用
npm run tauri dev时,Rust 后端日志在终端输出,前端日志在浏览器控制台 - 本地项目路径: 项目数据保存在
~/Documents/Meijiaka/projects/{project_id}/ - 配置修改: AI 模型配置
python-api/config/ai_models.yaml支持热重载,无需重启服务 - 类型同步: 修改后端 API 后,记得重新导出 OpenAPI 并运行
npm run gen:api - Async Engine Scheduler: 系统使用 Slot-Based Scheduler 统一调度所有第三方异步任务:
video- 数字人视频生成(18 slots)avatar_clone- 形象克隆(2 slots)image- 图片生成(9 slots)subtitle- 字幕生成(5 slots)copy- 文案提取(5 slots)
- 任务状态: 任务状态唯一真相源为后端 Redis,
taskStore不持久化,启动时从后端GET /tasks查询 - 项目数据: 项目元数据和分镜数据通过 IPC 显式写入本地文件,不通过 Zustand persist 持久化
- 字幕渲染: 使用
assjs库进行 ASS/SSA 字幕预览渲染,WASM 和 Worker 文件通过 Vite 插件复制到public/目录,修改资源路径后需要检查插件配置
开发规范
后端 (Python)
- 格式化: Black (行宽: 100)
- 检查: Ruff
- 类型: MyPy (strict 模式)
- 架构: API → Service → CRUD → Model,禁止跨层调用
- 数据库: 始终使用异步 SQLAlchemy,事务在 API 层控制
- AI 集成: 无论使用什么提供者,输出 Schema 必须保持一致,在 Service 层标准化
- 提示词: 所有提示词放在
app/ai/prompts/单独文件,不硬编码 - 配置管理: 所有配置通过
from app.config import get_settings读取,禁止直接使用os.getenv(),所有配置项必须在Settings类中定义
配置管理强制规范
架构层级:
.env (Layer 1) ──→ Settings (Layer 2) ──→ 服务层 (Layer 3)
↑
唯一配置出口
强制规则:
- 所有服务必须使用
from app.config import get_settings读取配置 - 禁止在服务层、API 层直接使用
os.getenv()或os.environ.get() - 所有配置项必须在
app/config.py的Settings类中定义 - 敏感信息(API Keys、Secrets)必须通过环境变量注入
- 业务默认值可以硬编码在
Settings中
添加新配置流程:
- 在
app/config.py的Settings类中添加字段定义 - 使用
Field(default=..., description="...")提供默认值和说明 - 敏感信息使用
str | None = None类型 - 更新
.env.example文档
Rust (Tauri 后端)
- 格式化:
rustfmt(默认配置) - 检查:
cargo clippy(零警告) - 模块组织: 命令按领域拆分到
src/commands/{domain}.rs,在lib.rs中注册 - 存储分层: 存储逻辑按领域拆分到
src/storage/{domain}.rs - 命令参数: Tauri IPC 命令必须使用 Args 结构体接收参数:
#[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct SaveProjectMetaArgs { pub project_id: String, pub data: serde_json::Value, } - 禁止: 命令函数直接使用 camelCase 参数名(会产生
non_snake_case警告)
本地数据存储规范(Tauri/Rust)
分层架构:
Layer 1: 页面组件(Pages/Components) — 只操作 Store,禁止直接调用 IPC save
Layer 2: Zustand Store(内存状态) — Immer 不可变更新
Layer 3: PersistManager(持久化协调) — debounce 批量、flush 强制、错误上报
Layer 4: API 模块(localStorageApi 等) — 类型安全的 IPC 调用封装
Layer 5: Rust StorageEngine(文件系统) — sanitize + atomic_write + file_lock
强制规范:
- 禁止页面组件直接调用
localProjectApi.saveXxx()— 必须通过 Store → PersistManager - 禁止 Rust 命令函数直接
fs::write— 必须通过StorageEngine::atomic_write_json - 所有 ID 参数必须
sanitize_id— 路径参数白名单校验([a-zA-Z0-9_-]+) - 所有 JSON 写操作必须原子化 — 临时文件 +
fs::rename - RMW 操作必须加锁 —
with_file_lock或 Mutex
StorageEngine 核心能力:
sanitize_id(id)— ID 白名单校验,防御路径遍历sanitize_filename(name)— 提取纯文件名,拒绝目录组件atomic_write_json(path, value)— 先写.tmp再 rename,防崩溃截断with_file_lock(path, f)— 文件锁保护 RMW 操作read_json<T>(path)— 安全读取,文件不存在返回None,损坏返回Err
前端 (TypeScript/React)
- 类型: 严格 TypeScript 模式
- 组件: 函数组件 + Hooks
- 状态管理: Zustand 管理全局状态,Immer 处理不可变更新
- 数据获取: SWR 缓存,自动 localStorage 降级
- API 客户端: 从后端 OpenAPI schema 自动生成类型
- 命名风格: camelCase(自动与后端 snake_case 转换)
- 本地存储: 项目数据通过 Tauri IPC 保存到
~/Documents/Meijiaka/projects/
提交规范
feat: 新功能
fix: 修复
docs: 文档
refactor: 重构
test: 测试
chore: 构建/工具
环境配置
后端 (.env)
# 数据库
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/meijiaka
REDIS_URL=redis://localhost:6379/0
# JWT 认证
SECRET_KEY=your-secret-key-here
ACCESS_TOKEN_EXPIRE_MINUTES=10080
# AI 服务凭证
VOLCENGINE_API_KEY=your-volcengine-key
VOLCENGINE_CAPTION_APPID=your-caption-appid
VOLCENGINE_CAPTION_TOKEN=your-caption-token
OPENAI_API_KEY=sk-your-openai-key
KLINGAI_ACCESS_KEY=your-kling-access-key
KLINGAI_SECRET_KEY=your-kling-secret-key
# 七牛云存储(数字人视频持久化)
QINIU_ACCESS_KEY=your-qiniu-access-key
QINIU_SECRET_KEY=your-qiniu-secret-key
QINIU_VIDEO_BUCKET=media-bucket
QINIU_IMAGE_BUCKET=image-bucket
# CORS 配置
CORS_ORIGINS=http://localhost:1420,http://127.0.0.1:1420,http://localhost:8080
服务地址
- API: http://localhost:8080/api/v1
- 文档: http://localhost:8080/docs
- Vite 开发服务器: http://localhost:1420
关键开发文件
| 文件 | 用途 |
|---|---|
python-api/app/main.py |
FastAPI 应用入口 |
python-api/app/api/v1/*.py |
API 端点定义 |
python-api/app/ai/model_router.py |
AI 模型路由和降级 |
python-api/app/services/*.py |
业务逻辑和 AI 响应标准化 |
python-api/config/ai_models.yaml |
AI 模型配置 |
tauri-app/src/App.tsx |
主 React 组件 |
tauri-app/src/api/client.ts |
智能路由的 API 客户端 |
tauri-app/src/store/projectStore.ts |
项目状态管理 |
tauri-app/src-tauri/src/lib.rs |
Rust 命令注册 |
tauri-app/src-tauri/src/commands/project.rs |
项目存储 IPC 命令 |
tauri-app/src-tauri/src/storage/engine.rs |
核心存储引擎(原子写+校验) |
tauri-app/src-tauri/src/video_processing.rs |
FFmpeg 视频合成 |
tauri-app/src-tauri/src/avatar_cache.rs |
头像视频缓存管理 |
python-api/app/core/token_manager.py |
API Token 缓存与自动刷新 |
python-api/app/config.py |
Pydantic Settings 配置管理 |
tauri-app/src/pages/VideoCreation/SubtitleBurning.tsx |
字幕压制页面(ASS 字幕渲染) |
tauri-app/src/hooks/useAssJsRenderer.ts |
assjs 字幕渲染 Hook |
tauri-app/src/utils/assGenerator.ts |
ASS 字幕文件生成工具 |
额外开发文档
项目 docs/ 目录包含详细的深度开发文档:
| 文档 | 主题 |
|---|---|
docs/video-generation-flow.md |
完整视频生成流程说明 |
docs/kling-api-dev.md |
KlingAI 数字人视频 API 对接开发文档 |
docs/app-update-system.md |
应用自动更新系统设计 |
docs/anytocopy-integration.md |
版权素材集成说明 |
docs/anytocopy-api.md |
版权素材 API 文档 |
docs/volcengine-video-caption-api.md |
火山引擎字幕 API 对接 |
docs/qiniu-kodo-python-sdk-guide.md |
七牛云存储 SDK 集成指南 |
docs/database-design.md |
数据库设计文档 |
docs/unified-async-scheduler.md |
统一异步调度器设计 |
docs/semantic-refactoring-plan.md |
后端语义重构计划 |
docs/migrate-avatars-to-local.md |
头像数据迁移到本地说明 |
统一术语表(语义治理)
后端代码已完成语义治理重构,所有开发必须遵守统一术语表,禁止使用废弃别名。
整个后端划分为 6 个语义层级,每一层只使用属于该层的术语:
Layer 6: Presentation (API Schema / 前端适配层) → Segment, Human, Job, Script
Layer 5: Application (API 路由) → Segment, Human, Job, Project
Layer 4: Orchestration (Scheduler / SlotManager) → Job, JobRecord, Slot, Handler
Layer 3: Domain (Service / 业务逻辑) → Segment, Human, VideoComposition, Caption
Layer 2: Adapter (Provider Client) → KlingJob, KlingElement, VolcJob, ProviderTaskId
Layer 1: Infrastructure (DB / Redis / HTTP) → 底层技术术语
术语对照表
| 业务概念 | 官方术语 | 使用层级 | 禁止使用的别名 |
|---|---|---|---|
| 视频分镜 | Segment |
Layer 3-6 | shot, scene_desc |
| 数字人形象 | Human / Avatar |
Layer 3-6(DB 用 avatar,API 用 human_id) |
element, character |
| 调度器工作单元 | Job |
Layer 4 | task |
| 供应商侧任务 | ProviderJob |
Layer 2 | kling_task, volc_task |
| 供应商任务 ID | provider_task_id |
Layer 2-4 | kling_task_id, video_task_id, image_task_id |
| 分镜状态 | SegmentStatus |
Layer 3-4 | 裸字符串 |
| 调度器状态 | JobStatus |
Layer 4 | 裸字符串 |
| 形象克隆状态 | AvatarCloneStatus |
Layer 3 | 裸字符串 |
| Kling 原始状态 | KlingTaskStatus |
Layer 2 仅限 | 泄漏到 Layer 3+ |
分层禁令
- API 层 (
app/api/v1/):禁止出现element_id,kling_task_id,shot_type,omni - Scheduler 层 (
app/scheduler/):禁止出现task_id(应为job_id),禁止构造供应商 prompt 语法 - Service 层 (
app/services/):禁止出现<<<element_1>>>等供应商专用语法 - Provider 层 (
app/ai/providers/):允许使用element_id,kling_task_id,KlingTaskStatus
类型禁令
- 跨层传递的接口禁止裸用
dict[str, Any]。params、result、changes等字段必须使用 Pydantic 模型或 TypedDict - 状态字段禁止使用裸字符串,必须使用对应的
StrEnum - CRUD 层
obj_in禁止裸字典,必须使用CreateSchema/UpdateSchema