docs: sync workflow progress and weekend handoff

This commit is contained in:
2026-04-17 18:44:43 +08:00
parent a97a2fe005
commit fea4ef012f
11 changed files with 2712 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
# Provider 系统开发文档
## 当前版本功能 (v0.2.0)
### 已完成功能
1. **CQTAI nano 图像适配器** (`app/services/adapters/image/cqtai.py`)
- 异步生成 + 轮询获取结果
- 支持 nano-banana / nano-banana-pro 模型
- 支持多种分辨率和画面比例
- 支持图生图 (filesUrl)
2. **密钥加密存储** (`app/services/secret_service.py`)
- Fernet 对称加密,密钥从 SECRET_KEY 派生
- Provider API Key 自动加密存储
- 密钥管理 API (CRUD)
3. **指标收集系统** (`app/services/provider_metrics.py`)
- 调用成功率、延迟、成本统计
- 时间窗口聚合查询
- 已集成到 provider_router
4. **熔断器功能** (`app/services/provider_metrics.py`)
- 连续失败 3 次触发熔断
- 60 秒后自动恢复尝试
- 健康状态持久化到数据库
5. **管理后台前端** (`app/admin_app.py`)
- 独立端口部署 (8001)
- Vue 3 + Tailwind CSS 单页应用
- Provider CRUD 管理
- 密钥管理界面
- Basic Auth 认证
### 配置说明
```bash
# 启动主应用
uvicorn app.main:app --port 8000
# 启动管理后台 (独立端口)
uvicorn app.admin_app:app --port 8001
```
环境变量:
```
CQTAI_API_KEY=your-cqtai-api-key
ENABLE_ADMIN_CONSOLE=true
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your-secure-password
```
---
## 下一版本优化计划 (v0.3.0)
### 高优先级
#### 1. 智能负载分流 (方案 B)
**目标**: 主渠道压力大时自动分流到后备渠道
**实现方案**:
- 监控指标: 并发数、响应延迟、错误率
- 分流阈值配置:
```python
class LoadBalanceConfig:
max_concurrent: int = 10 # 并发超过此值时分流
max_latency_ms: int = 5000 # 延迟超过此值时分流
max_error_rate: float = 0.1 # 错误率超过 10% 时分流
```
- 分流策略: 加权轮询,根据健康度动态调整权重
**涉及文件**:
- `app/services/provider_router.py` - 添加负载均衡逻辑
- `app/services/provider_metrics.py` - 添加并发计数器
- `app/db/admin_models.py` - 添加 LoadBalanceConfig 模型
#### 2. Storybook 适配器
**目标**: 生成可翻页的分页故事书
**实现方案**:
- 参考 Gemini AI Story Generator 格式
- 输出结构:
```python
class StorybookPage:
page_number: int
text: str
image_prompt: str
image_url: str | None
class Storybook:
title: str
pages: list[StorybookPage]
cover_url: str | None
```
- 集成文本 + 图像生成流水线
**涉及文件**:
- `app/services/adapters/storybook/` - 新建目录
- `app/api/stories.py` - 添加 storybook 生成端点
### 中优先级
#### 3. 成本追踪系统
**目标**: 记录实际消费,支持预算控制
**实现方案**:
- 成本记录表:
```python
class CostRecord:
user_id: str
provider_id: str
capability: str # text/image/tts
estimated_cost: Decimal
actual_cost: Decimal | None
timestamp: datetime
```
- 预算配置:
```python
class BudgetConfig:
user_id: str
daily_limit: Decimal
monthly_limit: Decimal
alert_threshold: float = 0.8 # 80% 时告警
```
- 超预算处理: 拒绝请求 / 降级到低成本 provider
**涉及文件**:
- `app/db/admin_models.py` - 添加 CostRecord, BudgetConfig
- `app/services/cost_tracker.py` - 新建
- `app/api/admin_providers.py` - 添加成本查询 API
#### 4. 指标可视化
**目标**: 管理后台展示供应商指标图表
**实现方案**:
- 添加指标查询 API:
- GET /admin/metrics/summary - 汇总统计
- GET /admin/metrics/timeline - 时间线数据
- GET /admin/metrics/providers/{id} - 单个供应商详情
- 前端使用 Chart.js 或 ECharts 展示
### 低优先级
#### 5. 多租户 Provider 配置
**目标**: 每个租户可配置独立 provider 列表和 API Key
**实现方案**:
- 租户配置表:
```python
class TenantProviderConfig:
tenant_id: str
provider_type: str
provider_ids: list[str] # 按优先级排序
api_key_override: str | None # 加密存储
```
- 路由时优先使用租户配置,回退到全局配置
#### 6. Provider 健康检查调度器
**目标**: 定期主动检查 provider 健康状态
**实现方案**:
- Celery Beat 定时任务
- 每 5 分钟检查一次所有启用的 provider
- 更新 ProviderHealth 表
#### 7. 适配器热加载
**目标**: 支持运行时动态加载新适配器
**实现方案**:
- 适配器插件目录: `app/services/adapters/plugins/`
- 启动时扫描并注册
- 提供 API 触发重新扫描
---
## API 变更记录
### v0.2.0 新增
| Method | Route | Description |
|--------|-------|-------------|
| GET | `/admin/secrets` | 列出所有密钥名称 |
| POST | `/admin/secrets` | 创建/更新密钥 |
| DELETE | `/admin/secrets/{name}` | 删除密钥 |
| GET | `/admin/secrets/{name}/verify` | 验证密钥有效性 |
### 计划中 (v0.3.0)
| Method | Route | Description |
|--------|-------|-------------|
| GET | `/admin/metrics/summary` | 指标汇总 |
| GET | `/admin/metrics/timeline` | 时间线数据 |
| POST | `/api/storybook/generate` | 生成分页故事书 |
| GET | `/admin/costs` | 成本统计 |
| POST | `/admin/budgets` | 设置预算 |
---
## 适配器开发指南
### 添加新适配器
1. 创建适配器文件:
```python
# app/services/adapters/image/new_provider.py
from app.services.adapters.base import AdapterConfig, BaseAdapter
from app.services.adapters.registry import AdapterRegistry
@AdapterRegistry.register("image", "new_provider")
class NewProviderAdapter(BaseAdapter[str]):
adapter_type = "image"
adapter_name = "new_provider"
async def execute(self, prompt: str, **kwargs) -> str:
# 实现生成逻辑
pass
async def health_check(self) -> bool:
# 实现健康检查
pass
@property
def estimated_cost(self) -> float:
return 0.01 # USD
```
2. 在 `__init__.py` 中导入:
```python
# app/services/adapters/__init__.py
from app.services.adapters.image import new_provider as _new_provider # noqa: F401
```
3. 添加配置:
```python
# app/core/config.py
new_provider_api_key: str = ""
# app/services/provider_router.py
API_KEY_MAP["new_provider"] = "new_provider_api_key"
```
4. 更新 `.env.example`:
```
NEW_PROVIDER_API_KEY=
```

View File

@@ -0,0 +1,109 @@
# DreamWeaver 重构实施计划
## 1. 概述
本文档基于对当前架构的深入分析,制定了从稳定性、可维护性到可扩展性的分阶段重构计划。
**目标**
- **短期**:解决单点故障风险,优化开发体验,清理关键技术债。
- **中期**:提升系统高可用能力,增强监控与可观测性。
- **长期**:架构演进,支持大规模并发与复杂业务场景。
---
## 2. 短期优化计划 (1-2周)
**重点**:消除即时风险,提升部署效率。
### 2.1 统一镜像构建 (High Priority)
目前 `backend`, `backend-admin`, `worker`, `celery-beat` 重复构建 4 次,浪费资源且镜像版本可能不一致。
- **Action Items**:
- [x] 修改 `backend/Dockerfile` 为通用基础镜像。
- [x] 更新 `docker-compose.yml`,定义 `backend-base` 服务或使用 `image` 标签共享镜像。
- [x] 确保所有 Python 服务共用同一构建产物,仅启动命令不同。
### 2.2 修复 Provider 缓存与限流 (High Priority)
内存缓存 (`TTLCache`, `_latency_cache`) 在多进程/多实例下失效。
- **Action Items**:
- [x] 引入 Redis 作为共享缓存后端。
- [x] 重构 `_load_provider_cache`,将 Provider 配置缓存至 Redis。
- [x] 重构 `stories.py` 中的限流逻辑,使用 `redis-cell` 或简单的 Redis 计数器替代 `TTLCache`
### 2.3 拆分 `stories.py` (Medium Priority)
`app/api/stories.py` 超过 600 行,包含 API 定义、业务逻辑、验证逻辑,维护困难。
- **Action Items**:
- [x] 创建 `app/services/story_service.py`迁移生成、润色、PDF生成等核心逻辑。
- [x] 创建 `app/schemas/story_schemas.py`,迁移 Pydantic 模型(`GenerateRequest`, `StoryResponse` 等)。
- [x] API 层 `stories.py` 仅保留路由定义和依赖注入,调用 Service 层。
---
## 3. 中期优化计划 (1-2月)
**重点**:高可用 (HA) 与系统韧性。
### 3.1 数据库高可用 (Critical)
当前 PostgreSQL 为单点,且 Admin/User 混合使用。
- **Action Items**:
- [ ] 部署 PostgreSQL 主从复制 (Master-Slave)。
- [ ] 配置 `PgBouncer` 或 SQLAlchemy 读写分离,减轻主库压力。
- [ ] 实施数据库自动备份策略 (如 `pg_dump` 定时上传 S3)。
### 3.2 消息队列高可用 (Critical)
Redis 单点故障将导致 Celery 任务全盘停摆。
- **Action Items**:
- [ ] 迁移至 Redis Sentinel 或 Redis Cluster 模式。
- [ ] 更新 Celery 配置以支持 Sentinel/Cluster 连接串。
### 3.3 增强可观测性 (Important)
目前仅有简单的日志,缺乏系统级指标。
- **Action Items**:
- [ ] 集成 Prometheus Client暴露 `/metrics` 端点。
- [ ] 部署 Grafana + Prometheus监控 API 延迟、QPS、Celery 队列积压情况。
- [ ] 完善 `ProviderMetrics`,增加可视化大盘,实时监控 AI 供应商的成本与成功率。
### 3.4 Phase 3 最小可执行任务清单 (MVP)
目标:在不大改业务代码的前提下,于一个迭代内完成高可用基础设施闭环。
- [x] PostgreSQL 主从:新增 `docker-compose.ha.yml`,包含 1 主 1 从与健康检查。
- [x] PostgreSQL 备份:新增每日备份任务(`pg_dump`)与 7 天保留策略。
- [x] Redis Sentinel新增 1 主 2 哨兵最小拓扑,并验证故障切换。
- [x] Celery 连接:更新 Celery broker/result backend 配置,支持 Sentinel 连接串。
- [x] 回归验证:执行一次故事生成 + 异步任务链路worker/beat冒烟测试。
- [x] 运行手册补充故障切换与恢复步骤文档PostgreSQL/Redis/Celery
---
## 4. 长期架构演进 (季度规划)
**重点**:业务解耦与规模化。
### 4.1 统一 API 网关
- **当前**前端直连后端端口CORS 配置分散。
- **演进**:引入 Traefik 或 Nginx 作为统一网关管理路由、SSL、全局限流、统一鉴权。
### 4.2 前端工程合并
- **当前**User App 和 Admin Console 是完全独立的两个项目,但在组件和工具链上高度重复。
- **演进**:使用一种 Monorepo 策略或基于路由的单一应用策略,共享组件库和类型定义,减少维护成本。
### 4.3 事件驱动架构完善
- **当前**:部分业务逻辑耦合在 API 中。
- **演进**:扩展事件总线,将“阅读记录”、“成就解锁”、“通知推送”等非核心链路完全异步化,通过 Domain Events 解耦。
---
## 5. 实施路线图
| 阶段 | 时间估算 | 关键里程碑 |
| :--- | :--- | :--- |
| **Phase 1: 基础夯实** | Week 1-2 | Docker 构建优化上线Redis 替代内存缓存。 |
| **Phase 2: 代码重构** | Week 3-4 | `stories.py` 拆分完成Service 层建立。 |
| **Phase 3: 高可用建设** | Month 2 | 数据库与 Redis 实现主备/集群模式。 |
| **Phase 4: 监控体系** | Month 2 | Grafana 监控大盘上线,关键指标报警配置完毕。 |

View File

@@ -0,0 +1,52 @@
# `stories.py` 拆分分析 (Phase 2 准备)
## 当前职责
`app/api/stories.py` (591 行) 承担了以下职责:
| 职责 | 行数 | 描述 |
|---|---|---|
| Pydantic 模型 | ~50 行 | `GenerateRequest`, `StoryResponse`, `FullStoryResponse` 等 |
| 验证逻辑 | ~40 行 | `_validate_profile_and_universe` |
| 路由 + 业务 | ~300 行 | `generate_story`, `generate_story_full`, `generate_story_stream` |
| 绘本逻辑 | ~170 行 | `generate_storybook_api` (含并行图片生成) |
| 成就查询 | ~30 行 | `get_story_achievements` |
## 缺失端点
测试中引用但 **未实现** 的端点(这些应在拆分时一并补充):
- `GET /api/stories` — 故事列表 (分页)
- `GET /api/stories/{id}` — 故事详情
- `DELETE /api/stories/{id}` — 故事删除
- `POST /api/image/generate/{id}` — 封面图片生成
- `GET /api/audio/{id}` — 语音朗读
## 建议拆分结构
```
app/
├── schemas/
│ └── story_schemas.py # [NEW] Pydantic 模型
├── services/
│ └── story_service.py # [NEW] 核心业务逻辑
└── api/
├── stories.py # [SLIM] 路由定义 + 依赖注入
└── stories_storybook.py # [NEW] 绘本相关端点 (可选)
```
### `story_schemas.py`
- 迁移所有 Pydantic 模型
- 包括 `GenerateRequest`, `StoryResponse`, `FullStoryResponse`, `StorybookRequest`, `StorybookResponse`
### `story_service.py`
- `validate_profile_and_universe()` — 验证逻辑
- `create_story()` — 故事入库
- `generate_and_save_story()` — 生成 + 保存联合操作
- `generate_storybook_with_images()` — 绘本并行图片生成
- 补充: `list_stories()`, `get_story()`, `delete_story()`
### `stories.py` (瘦路由层)
- 仅保留 `@router` 装饰器和依赖注入
- 调用 service 层完成业务逻辑
- 预计 150-200 行