diff --git a/README.md b/README.md index 5e9c18d..e7d5974 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,15 @@ 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. 准备环境文件: @@ -42,6 +51,15 @@ 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 @@ -64,14 +82,30 @@ 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 和语音共创;演示前需要验证朗读链路时使用 `SMOKE_AUDIO=1`,需要验证 Voice Studio Alpha 时使用 `SMOKE_VOICE=1`。 +`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` 指向错误,以及音频文件格式不被转写接口接受。 + ## 手动开发 后端: @@ -83,6 +117,15 @@ 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 @@ -162,6 +205,7 @@ npm run build - `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 能力与路由策略说明 diff --git a/admin-frontend/Dockerfile b/admin-frontend/Dockerfile index d222861..5104db7 100644 --- a/admin-frontend/Dockerfile +++ b/admin-frontend/Dockerfile @@ -1,23 +1,26 @@ -# Build Stage -FROM node:18-alpine AS build-stage - -WORKDIR /app - -COPY package*.json ./ -RUN npm install - -COPY . . -RUN npm run build - -# Production Stage -FROM nginx:alpine AS production-stage - -# 复制构建产物到 Nginx -COPY --from=build-stage /app/dist /usr/share/nginx/html - -# 复制自定义 Nginx 配置 (处理 SPA 路由) -COPY nginx.conf /etc/nginx/conf.d/default.conf - -EXPOSE 80 - -CMD ["nginx", "-g", "daemon off;"] +# Build Stage +ARG NODE_BASE_IMAGE=node:18-alpine +ARG NGINX_BASE_IMAGE=nginx:alpine +FROM ${NODE_BASE_IMAGE} AS build-stage + +WORKDIR /app + +ARG NPM_REGISTRY=https://registry.npmjs.org/ +COPY package*.json ./ +RUN npm ci --registry="${NPM_REGISTRY}" --no-audit --no-fund + +COPY . . +RUN npm run build + +# Production Stage +FROM ${NGINX_BASE_IMAGE} AS production-stage + +# 复制构建产物到 Nginx +COPY --from=build-stage /app/dist /usr/share/nginx/html + +# 复制自定义 Nginx 配置 (处理 SPA 路由) +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/admin-frontend/src/views/AdminProviders.vue b/admin-frontend/src/views/AdminProviders.vue index 6941859..28d2d6e 100644 --- a/admin-frontend/src/views/AdminProviders.vue +++ b/admin-frontend/src/views/AdminProviders.vue @@ -157,12 +157,20 @@