Files
dreamweaver/README.md

216 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DreamWeaver 梦语织机
AI 儿童故事生成应用,面向 3-8 岁儿童与家长,支持关键词生成故事、绘本页生成、封面图生成、语音朗读、孩子档案、故事宇宙与 Provider 管理。
当前仓库优先服务一个目标:本地 Docker 环境中稳定跑通完整产品闭环,便于求职演示和后续迭代。
## 技术栈
- 后端FastAPI、SQLAlchemy async、PostgreSQL、Celery、Redis
- 前端Vue 3、TypeScript、Pinia、Vue Router、Tailwind CSS、Vite
- 认证OAuth 2.0 + JWT httpOnly cookie本地演示支持 dev login
- AI文本、图片、TTS、绘本结构生成均通过 adapter/provider router 接入
## 仓库结构
```text
backend/ FastAPI 后端、Celery 任务、数据库迁移
frontend/ 用户端 Vue 应用
admin-frontend/ 管理端 Vue 应用
docs/ 当前产品、规划与技术文档
docker-compose.yml
```
## 环境变量文件
仓库里可能同时出现两个被 git 忽略的 env 文件,它们职责不同:
- `backend/.env`:应用运行配置。后端 API、管理后端、Celery worker、Celery beat 都读取这个文件AI key、OAuth key、`SECRET_KEY``DATABASE_URL`、Provider 列表都放这里。
- 根目录 `.env`:仅供 Docker Compose 做构建覆盖。这里只放 `PYTHON_BASE_IMAGE``NODE_BASE_IMAGE``NGINX_BASE_IMAGE``NPM_REGISTRY` 等镜像源/registry 变量,不放后端密钥,也不放 AI/OAuth key。
后端代码会按绝对路径读取 `backend/.env`,因此无论你在仓库根目录运行 `uvicorn`,还是 `cd backend` 后运行,读到的都是同一个应用配置文件。`backend/.env.example``backend/.env` 的模板;根目录 `.env` 没有模板也不是必需文件,只有在需要替换 Docker 基础镜像、npm registry 或端口时才创建。
## 本地 Docker 演示
1. 准备环境文件:
```bash
cp backend/.env.example backend/.env
```
本地求职演示建议在 `backend/.env` 中使用:
```env
DEBUG=true
ENABLE_DEMO_PROVIDERS=true
TEXT_PROVIDERS=["demo", "gemini", "openai"]
IMAGE_PROVIDERS=["demo", "cqtai"]
TTS_PROVIDERS=["edge_tts", "minimax", "elevenlabs"]
STORYBOOK_PROVIDERS=["demo", "storybook_primary"]
```
`SECRET_KEY` 必须设置为强随机值。`backend/.env` 已被 git 忽略,不要提交真实密钥。
Docker 演示默认使用 `backend/.env` 中的容器内连接地址:
```env
DATABASE_URL=postgresql+asyncpg://dreamweaver:dreamweaver_password@db:5432/dreamweaver_db
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/0
REDIS_URL=redis://redis:6379/0
```
2. 启动完整本地栈:
```bash
docker compose up -d --build
```
3. 访问入口:
- 用户端http://localhost:52080
- 本地开发登录http://localhost:52080/auth/dev/signin
- 管理端http://localhost:52888默认演示账号来自 `backend/.env`
- 后端健康检查http://localhost:52000/health
- 管理后端健康检查http://localhost:52800/health
4. 常用命令:
```bash
docker compose ps
docker compose logs -f backend
./scripts/demo_smoke.sh
SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
SMOKE_VOICE=1 ./scripts/demo_smoke.sh
SMOKE_REAL_ASR=1 ./scripts/demo_smoke.sh
docker compose down
docker compose down -v
```
`scripts/demo_smoke.sh` 会检查健康状态、本地登录、统一生成后台任务、主记录落库、资产重试、故事列表和 Provider 能力分层。默认跳过 TTS、语音共创和真实 ASR演示前需要验证朗读链路时使用 `SMOKE_AUDIO=1`,需要验证 Voice Studio Alpha 时使用 `SMOKE_VOICE=1`,需要用真实 OpenAI ASR key 验收上传转写时使用 `SMOKE_REAL_ASR=1`
语音共创的 ASR 能力已纳入 Provider 分层。默认 `ASR_PROVIDERS=["demo"]` 会使用 `transcript_hint` 或文本上传作为本地演示转写;需要真实转写时可设置 `ASR_PROVIDERS=["openai_asr", "demo"]` 并配置 `OPENAI_API_KEY`
真实 ASR 验收建议在 `backend/.env` 中确认:
```env
ASR_PROVIDERS=["openai_asr", "demo"]
OPENAI_API_KEY=sk-...
OPENAI_API_BASE=
VOICE_TRANSCRIPTION_MODE=provider
VOICE_TRANSCRIPTION_MODEL=gpt-4o-mini-transcribe
VOICE_TRANSCRIPTION_LANGUAGE=zh
```
改完 `backend/.env` 后重启 API/worker若后台 Provider 表改过 ASR provider还需要调用 `POST /admin/providers/reload` 并重启 API 进程,确保运行中缓存使用新配置。`SMOKE_REAL_ASR=1` 会自动开启 `SMOKE_VOICE=1`,在 macOS 上默认用 `say`/`afconvert` 生成一段短音频;其他环境可传入 `REAL_ASR_AUDIO_FILE=/path/to/sample.m4a`
真实 ASR smoke 失败时脚本会打印上传接口响应、Voice Session 事件和 Admin ASR analytics。常见失败包括 `OPENAI_API_KEY 未配置`、401/403 key 无效或项目无权限、429/insufficient_quota 额度不足、404/model_not_found 模型名不可用、连接超时或 `OPENAI_API_BASE` 指向错误,以及音频文件格式不被转写接口接受。
## 手动开发
后端:
```bash
cd backend
pip install -e ".[dev]"
alembic upgrade head
uvicorn app.main:app --reload --port 8000
```
本机直接跑后端时,仍然修改 `backend/.env`,只是把数据库和 Redis 地址换成宿主机端口版本:
```env
DATABASE_URL=postgresql+asyncpg://dreamweaver:dreamweaver_password@localhost:52432/dreamweaver_db
CELERY_BROKER_URL=redis://localhost:52379/0
CELERY_RESULT_BACKEND=redis://localhost:52379/0
REDIS_URL=redis://localhost:52379/0
```
Celery
```bash
cd backend
celery -A app.core.celery_app worker --loglevel=info
celery -A app.core.celery_app beat --loglevel=info
```
用户前端:
```bash
cd frontend
npm install
npm run dev
```
管理前端:
```bash
cd admin-frontend
npm install
npm run dev
```
## 质量检查
```bash
cd backend
pytest
ruff check app tests
cd ../frontend
npm run build
cd ../admin-frontend
npm run build
```
当前已知情况:完整后端测试可通过;全量 ruff 可通过。前端生产构建建议优先通过 Docker 验证,确保与本地演示环境一致。
## 核心接口
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | `/auth/dev/signin` | 本地开发登录,仅 `DEBUG=true` 可用 |
| GET | `/auth/github/signin` | GitHub OAuth 登录 |
| GET | `/auth/google/signin` | Google OAuth 登录 |
| GET | `/auth/session` | 当前会话 |
| POST | `/api/generations` | 提交后台生成任务,立即返回 `generation_job_id` |
| GET | `/api/generations/{story_id}` | 统一读取生成结果 |
| POST | `/api/generations/{story_id}/retry-assets` | 统一重试封面/语音资源 |
| GET | `/api/generations/jobs/{job_id}` | 查询生成任务事件流 |
| GET | `/api/generations/{story_id}/jobs` | 查询故事生成与重试历史 |
| GET | `/api/generations/{story_id}/provider-stats` | 查询 Provider 调用聚合指标 |
| GET | `/api/generations/ops-summary` | 查询最近任务运行概览、失败摘要和超时阈值 |
| GET | `/api/generations/provider-analytics` | 查询当前用户跨故事 Provider 运营摘要,支持 `days` / `capability` 筛选 |
| GET | `/api/audio/{story_id}/status` | 查询音频缓存状态,不触发生成 |
| DELETE | `/api/audio/{story_id}/cache` | 清理故事音频缓存 |
| GET | `/api/stories` | 故事列表 |
| GET | `/api/stories/{story_id}` | 故事详情 |
| DELETE | `/api/stories/{story_id}` | 删除故事 |
| GET/POST/PUT/DELETE | `/admin/providers` | Provider 管理,需开启管理后台 |
| GET | `/admin/providers/capabilities` | Provider 能力分层说明text/image/tts/storybook/asr需开启管理后台 |
## 文档入口
- `docs/product/job-search-relaunch-prd.md`:求职版产品重启 PRD
- `docs/product/unified-generation-workflow-prd.md`:统一生成工作流 PRD
- `docs/planning/week-1-execution-backlog.md`:短期执行 backlog
- `docs/planning/week-2-execution-backlog.md`:下一阶段执行 backlog
- `docs/planning/week-2-to-4-execution-backlog.md`Week 2 到 Week 4 总执行 backlog
- `docs/planning/demo-checklist.md`:求职演示检查清单
- `docs/planning/demo-package.md`:求职版 Demo 包装页
- `docs/planning/demo-validation-log.md`:本地 Docker 演示验证记录
- `docs/planning/interview-pitch.md`3 分钟项目讲解稿
- `docs/planning/week-1-sprint-review.md`Week 1 复盘总结
- `docs/planning/week-4-sprint-review.md`Week 4 复盘和生产化 backlog
- `docs/technical/architecture.md`:求职版架构说明
- `docs/technical/api-compatibility.md`:旧生成 API 兼容层策略
- `docs/technical/environment-configuration.md`:环境变量文件职责与 Docker/本机切换约定
- `docs/technical/generation-job-state.md`Generation Job 状态落库决策
- `docs/technical/memory-system-dev.md`:记忆系统技术说明
- `docs/technical/provider-routing.md`Provider 能力与路由策略说明
## 当前取舍
仓库只保留一个 Docker Compose 入口:`docker-compose.yml`。生产部署、HA 演练、旧 Claude 原型和历史归档已从主仓库移除,避免干扰当前求职演示主线。统一生成接口现在会先创建后台任务,再由 Celery worker 负责真正的故事/绘本生成;因此本地开发或 Docker 演示时需要保证 `worker` 服务可用。音频缓存默认按 `STORY_AUDIO_CACHE_TTL_DAYS=30` 做后台清理Celery beat 会每日执行一次 prune生成任务默认按 `GENERATION_JOB_STALE_MINUTES=60` 判定卡住,后台会定时自动收敛为失败态,避免故事长期显示“永远在跑”。