# ViGent2 后端开发规范

本文档定义后端开发的结构规范、接口契约与实现习惯。目标是让新功能按统一范式落地，旧逻辑在修复时逐步抽离。

## 文档定位

- 本文档只定义后端开发规范与工程约束（分层职责、契约、流程、代码习惯）。
- 接口说明、部署运行与环境配置示例请查看 `Docs/BACKEND_README.md`。
- 历史变更请记录在 `Docs/DevLogs/` 与 `Docs/TASK_COMPLETE.md`，不要写入本规范文档。

---

## 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/xiaohongshu/bilibili）
│   │   ├── 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，本仓库当前 `.env` 配置 100)

### 微信视频号
- `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`

### 小红书
- `XIAOHONGSHU_HEADLESS_MODE` (headful/headless-new，默认 headless-new)
- `XIAOHONGSHU_CHROME_PATH` / `XIAOHONGSHU_BROWSER_CHANNEL`
- `XIAOHONGSHU_USER_AGENT`
- `XIAOHONGSHU_LOCALE` / `XIAOHONGSHU_TIMEZONE_ID`
- `XIAOHONGSHU_FORCE_SWIFTSHADER`
- `XIAOHONGSHU_DEBUG_ARTIFACTS`

### 支付宝
- `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` / `xiaohongshu_*.png`
- 视频号建议使用 headful + xvfb-run（避免 headless 解码/指纹问题）
- 发布专项实现细节（登录链路、成功判定、排障）统一维护在 `Docs/PUBLISH_DEPLOY.md`

---

## 11. 最小新增模块示例

```
app/modules/foo/
├── router.py
├── schemas.py
├── service.py
└── workflow.py
```

router 仅调用 service/workflow 并返回 `success_response`。
