210 lines
7.5 KiB
Markdown
210 lines
7.5 KiB
Markdown
# ViGent2 后端开发规范
|
||
|
||
本文档定义后端开发的结构规范、接口契约与实现习惯。目标是让新功能按统一范式落地,旧逻辑在修复时逐步抽离。
|
||
|
||
---
|
||
|
||
## 1. 模块化与分层原则
|
||
|
||
每个业务功能放入 `app/modules/<feature>/`,以“薄路由 + 厚服务/流程”组织代码。
|
||
|
||
- **router.py**:只做参数校验、权限校验、调用 service/workflow、返回统一响应。
|
||
- **schemas.py**:Pydantic 请求/响应模型。
|
||
- **service.py**:业务逻辑与集成逻辑(非长流程)。
|
||
- **workflow.py**:长流程/重任务编排(视频生成、渲染、异步任务)。
|
||
- **__init__.py**:模块标记。
|
||
|
||
其它层级职责:
|
||
|
||
- **repositories/**:数据读写(Supabase),不包含业务逻辑。
|
||
- **services/**:外部依赖与基础能力(TTS、Storage、Remotion 等)。
|
||
- **core/**:配置、安全、依赖注入、统一响应。
|
||
|
||
---
|
||
|
||
## 2. 目录结构(当前约定)
|
||
|
||
```
|
||
backend/
|
||
├── app/
|
||
│ ├── core/ # config、deps、security、response
|
||
│ ├── modules/ # 业务模块(路由 + 逻辑)
|
||
│ │ ├── videos/ # 视频生成任务(router/schemas/service/workflow)
|
||
│ │ ├── materials/ # 素材管理(router/schemas/service)
|
||
│ │ ├── publish/ # 多平台发布
|
||
│ │ ├── auth/ # 认证与会话
|
||
│ │ ├── ai/ # AI 功能(标题标签生成、多语言翻译)
|
||
│ │ ├── assets/ # 静态资源(字体/样式/BGM)
|
||
│ │ ├── ref_audios/ # 声音克隆参考音频(router/schemas/service)
|
||
│ │ ├── generated_audios/ # 预生成配音管理(router/schemas/service)
|
||
│ │ ├── login_helper/ # 扫码登录辅助
|
||
│ │ ├── tools/ # 工具接口(router/schemas/service)
|
||
│ │ ├── payment/ # 支付宝付费开通(router/schemas/service)
|
||
│ │ └── admin/ # 管理员功能
|
||
│ ├── repositories/ # Supabase 数据访问
|
||
│ ├── services/ # 外部服务集成
|
||
│ │ ├── uploader/ # 平台发布器(douyin/weixin)
|
||
│ │ ├── qr_login_service.py
|
||
│ │ ├── publish_service.py
|
||
│ │ ├── remotion_service.py
|
||
│ │ ├── storage.py
|
||
│ │ └── ...
|
||
│ └── tests/
|
||
├── assets/ # 字体 / 样式 / bgm
|
||
├── user_data/ # 用户隔离数据(Cookie 等)
|
||
├── scripts/
|
||
└── requirements.txt
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 接口契约规范(统一响应)
|
||
|
||
所有 JSON API 返回统一结构:
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "ok",
|
||
"data": { },
|
||
"code": 0
|
||
}
|
||
```
|
||
|
||
- 正常响应使用 `success_response`。
|
||
- 错误通过 `HTTPException` 抛出,统一由全局异常处理返回 `{success:false, message, code}`。
|
||
- 不再使用 `detail` 作为前端错误文案(前端已改为读 `message`)。
|
||
|
||
### `/api/videos/generate` 参数契约(关键约定)
|
||
|
||
- `custom_assignments` 每项使用 `material_path/start/end/source_start/source_end?`,并以时间轴可见段为准。
|
||
- `output_aspect_ratio` 仅允许 `9:16` / `16:9`,默认 `9:16`。
|
||
- 标题显示模式参数:
|
||
- `title_display_mode`: `short` / `persistent`(默认 `short`)
|
||
- `title_duration`: 默认 `4.0`(秒),仅 `short` 模式生效
|
||
- 片头副标题参数:
|
||
- `secondary_title`: 副标题文字(可选,限 20 字),仅在视频画面中显示,不参与发布标题
|
||
- `secondary_title_style_id` / `secondary_title_font_size` / `secondary_title_top_margin`: 副标题样式配置
|
||
- workflow/remotion 侧需保持字段透传一致,避免前后端语义漂移。
|
||
|
||
---
|
||
|
||
## 4. 认证与权限
|
||
|
||
- 认证方式:**HttpOnly Cookie** (`access_token`)。
|
||
- `get_current_user` / `get_current_user_optional` 位于 `core/deps.py`。
|
||
- Session 单设备校验使用 `repositories/sessions.py`。
|
||
|
||
---
|
||
|
||
## 5. 任务与状态
|
||
|
||
- 视频生成任务通过 `modules/videos/workflow.py` 统一编排。
|
||
- 任务状态通过 `modules/videos/task_store.py` 读写,**不要直接维护全局 dict**。
|
||
- 默认使用 Redis(`REDIS_URL`),不可用自动回退内存。
|
||
|
||
---
|
||
|
||
## 6. 文件与存储
|
||
|
||
- 所有文件上传/下载/删除/移动通过 `services/storage.py`。
|
||
- 需要重命名时使用 `move_file`,避免直接读写 Storage。
|
||
|
||
### Cookie 存储(用户隔离)
|
||
|
||
多平台扫码登录产生的 Cookie 按用户隔离存储:
|
||
|
||
```
|
||
backend/user_data/{user_uuid}/cookies/
|
||
├── douyin_cookies.json
|
||
├── weixin_cookies.json
|
||
└── ...
|
||
```
|
||
|
||
- `publish_service.py` 中通过 `_get_cookies_dir(user_id)` / `_get_cookie_path(user_id, platform)` 定位
|
||
- 会话 key 格式:`"{user_id}_{platform}"`,确保多用户并发登录互不干扰
|
||
- 登录成功后 Cookie 自动保存到对应路径,发布时自动加载
|
||
|
||
---
|
||
|
||
## 7. 代码约定
|
||
|
||
- 只在 router 做校验与响应拼装。
|
||
- 业务逻辑写在 service/workflow。
|
||
- 数据库访问写在 repositories。
|
||
- 统一使用 `loguru` 打日志。
|
||
|
||
---
|
||
|
||
## 8. 开发流程建议
|
||
|
||
- **新增功能**:先建模块,**必须**包含 `router.py + schemas.py + service.py`,不允许 router-only。
|
||
- **修复 Bug**:顺手把涉及的逻辑抽到对应 service/workflow(渐进式改造)。
|
||
- **改旧模块**:改动哪部分就拆哪部分,不要求一次重构整个文件。
|
||
- **核心流程变更**:必跑冒烟(登录/生成/发布)。
|
||
|
||
> **渐进原则**:新代码高标准,旧代码逐步改。不做大规模一次性重构,避免引入回归风险。
|
||
|
||
---
|
||
|
||
## 9. 常用环境变量
|
||
|
||
- `SUPABASE_URL` / `SUPABASE_KEY`
|
||
- `SUPABASE_PUBLIC_URL`
|
||
- `REDIS_URL`
|
||
- `GLM_API_KEY`
|
||
- `LATENTSYNC_*`
|
||
- `CORS_ORIGINS` (CORS 白名单,默认 *)
|
||
|
||
### MuseTalk / 混合唇形同步
|
||
- `MUSETALK_GPU_ID` (GPU 编号,默认 0)
|
||
- `MUSETALK_API_URL` (常驻服务地址,默认 http://localhost:8011)
|
||
- `MUSETALK_BATCH_SIZE` (推理批大小,默认 32)
|
||
- `MUSETALK_VERSION` (v15)
|
||
- `MUSETALK_USE_FLOAT16` (半精度,默认 true)
|
||
- `LIPSYNC_DURATION_THRESHOLD` (秒,>=此值用 MuseTalk,默认 120)
|
||
|
||
### 微信视频号
|
||
- `WEIXIN_HEADLESS_MODE` (headful/headless-new)
|
||
- `WEIXIN_CHROME_PATH` / `WEIXIN_BROWSER_CHANNEL`
|
||
- `WEIXIN_USER_AGENT` / `WEIXIN_LOCALE` / `WEIXIN_TIMEZONE_ID`
|
||
- `WEIXIN_FORCE_SWIFTSHADER`
|
||
- `WEIXIN_TRANSCODE_MODE` (reencode/faststart/off)
|
||
|
||
### 抖音
|
||
- `DOUYIN_HEADLESS_MODE` (headful/headless-new,默认 headless-new)
|
||
- `DOUYIN_CHROME_PATH` / `DOUYIN_BROWSER_CHANNEL`
|
||
- `DOUYIN_USER_AGENT` (默认 Chrome/144)
|
||
- `DOUYIN_LOCALE` / `DOUYIN_TIMEZONE_ID`
|
||
- `DOUYIN_FORCE_SWIFTSHADER`
|
||
- `DOUYIN_DEBUG_ARTIFACTS` / `DOUYIN_RECORD_VIDEO` / `DOUYIN_KEEP_SUCCESS_VIDEO`
|
||
|
||
### 支付宝
|
||
- `ALIPAY_APP_ID` / `ALIPAY_PRIVATE_KEY_PATH` / `ALIPAY_PUBLIC_KEY_PATH`
|
||
- `ALIPAY_NOTIFY_URL` / `ALIPAY_RETURN_URL`
|
||
- `ALIPAY_SANDBOX` (沙箱模式,默认 false)
|
||
- `PAYMENT_AMOUNT` (会员价格,默认 999.00)
|
||
- `PAYMENT_EXPIRE_DAYS` (会员有效天数,默认 365)
|
||
|
||
---
|
||
|
||
## 10. Playwright 发布调试
|
||
|
||
- 诊断日志落盘:`backend/app/debug_screenshots/weixin_network.log` / `douyin_network.log`
|
||
- 关键失败截图:`backend/app/debug_screenshots/weixin_*.png` / `douyin_*.png`
|
||
- 视频号建议使用 headful + xvfb-run(避免 headless 解码/指纹问题)
|
||
|
||
---
|
||
|
||
## 11. 最小新增模块示例
|
||
|
||
```
|
||
app/modules/foo/
|
||
├── router.py
|
||
├── schemas.py
|
||
├── service.py
|
||
└── workflow.py
|
||
```
|
||
|
||
router 仅调用 service/workflow 并返回 `success_response`。
|