Files
Neo-ZQYY/apps/backend/README.md
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

256 lines
14 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.
# apps/backend — FastAPI 后端
为微信小程序和管理后台提供 RESTful API连接 `zqyy_app` 业务数据库,直连 `etl_feiqiu` ETL 库只读访问 `app.v_*` RLS 视图。
## 技术栈
- Python 3.10+ / FastAPI 0.115+ / Uvicorn
- PostgreSQLpsycopg2 直连,纯 SQL无 ORM
- JWT 认证python-jose + bcrypt
- WebSocket实时日志推送
- neozqyy-shared共享枚举、金额精度、时间工具
## 目录结构
```
apps/backend/
├── app/
│ ├── main.py # FastAPI 入口lifespan 管理 + 路由注册)
│ ├── config.py # 配置加载(根 .env < .env.local < 环境变量)
│ ├── database.py # 数据库连接zqyy_app 读写 + etl_feiqiu 只读 RLS
│ ├── auth/ # 认证模块
│ │ ├── dependencies.py # FastAPI 依赖注入CurrentUser
│ │ └── jwt.py # JWT 签发/验证/密码哈希
│ ├── routers/ # 18 个路由模块(详见 API 参考)
│ ├── schemas/ # Pydantic 请求/响应模型
│ ├── services/ # 业务逻辑层
│ ├── middleware/ # 中间件ResponseWrapper 全局响应包装)
│ ├── ai/ # AI 模块DashScope Application API + 8 个应用)
│ │ ├── config.py # AIConfig — 环境变量加载DASHSCOPE_*
│ │ ├── dashscope_client.py # DashScope Application API 统一封装
│ │ ├── dispatcher.py # AIDispatcher — 事件调度 + 调用链编排
│ │ ├── circuit_breaker.py # 熔断器(按 app_id 独立)
│ │ ├── rate_limiter.py # 限流器(用户/门店维度)
│ │ ├── budget_tracker.py # Token 预算追踪(日/月限额)
│ │ ├── run_log_service.py # AI 运行日志 CRUD
│ │ ├── exceptions.py # 异常层级DashScopeError 基类)
│ │ ├── cache_service.py # AI 缓存读写biz.ai_cache + status 状态控制)
│ │ ├── conversation_service.py # 对话管理session_id 双轨)
│ │ ├── schemas.py # AI 相关 SchemaSSEEvent 等)
│ │ ├── apps/ # 8 个 AI 应用app1_chat ~ app8_consolidation
│ │ ├── prompts/ # Prompt 模板app2/app8 独立模板)
│ │ └── data_fetchers/ # 共享数据获取层NS2 新增)
│ │ ├── member_data.py # 客户消费/会员卡/备注数据
│ │ ├── assistant_data.py # 助教信息/服务记录
│ │ └── page_context.py # 页面上下文文本化10 种入口)
│ └── ws/ # WebSocket实时日志
├── tests/ # 后端测试
├── pyproject.toml # 依赖声明
└── README.md
```
## 启动
```bash
# 安装依赖(在 monorepo 根目录)
uv sync --all-packages
# 启动开发服务器
cd apps/backend
uv run uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
```
API 文档自动生成于:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
## 架构概览
### 全局响应包装与 Schema 规范RNS1.0
后端通过 ASGI 中间件和 Pydantic 基类实现统一的响应格式:
- `ResponseWrapperMiddleware``middleware/response_wrapper.py`):所有 JSON 成功响应2xx自动包装为 `{ "code": 0, "data": <原始响应体> }`SSE`text/event-stream`)和非 JSON 响应透传不包装
- `http_exception_handler` / `unhandled_exception_handler`:异常统一格式化为 `{ "code": <HTTP状态码>, "message": <错误详情> }`,未捕获异常返回 500 并记录完整堆栈
- `CamelModel``schemas/base.py`):所有小程序 API 响应 schema 的基类,`alias_generator=to_camel` 自动将 snake_case 字段转为 camelCase 输出,同时通过 `populate_by_name=True` 接受两种格式输入
### 双数据库连接
| 连接 | 数据库 | 用途 | 函数 |
|------|--------|------|------|
| 业务读写 | `zqyy_app` | 用户、队列、调度、执行日志 | `get_connection()` |
| ETL 只读 | `etl_feiqiu` | 数据查看器、游标监控 | `get_etl_readonly_connection(site_id)` |
ETL 只读连接自动设置 `default_transaction_read_only = on` 和 RLS `app.current_site_id`,确保门店数据隔离。
### 认证体系
后端支持两套认证:
1. 管理后台认证(`/api/auth/*`):用户名 + 密码 → JWT
2. 小程序认证(`/api/xcx-auth/*`):微信 code → openid → JWT
3. 租户管理后台认证(`/api/tenant/auth/*`):用户名 + 密码 → JWT`aud=tenant-admin`,与小程序完全隔离)
JWT 令牌分两种:
- 完整令牌:已审批用户,包含 `user_id` + `site_id` + `roles`
- 受限令牌(`limited=True`):待审批用户,仅允许访问申请相关端点
依赖注入:
- `get_current_user`:要求完整令牌
- `get_current_user_or_limited`:允许受限令牌
### 配置加载
优先级(低 → 高):根 `.env` → 应用 `.env.local` → 环境变量
关键配置项:
- `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `APP_DB_NAME` — 业务数据库
- `ETL_DB_*` — ETL 数据库(缺省复用业务库参数)
- `JWT_SECRET_KEY` — JWT 签名密钥(生产必须设置)
- `CORS_ORIGINS` — 允许的跨域来源
- `ETL_PROJECT_PATH` — ETL CLI 工作目录
- `WX_APPID` / `WX_SECRET` — 微信小程序配置
- `WX_DEV_MODE` — 开发模式(启用 mock 登录)
- `BUSINESS_DAY_START_HOUR` — 营业日分割点(默认 8 点)
### 后台服务
应用启动时通过 lifespan 拉起两个后台服务:
- `TaskQueue`:任务执行队列(从 `task_queue` 表消费,按 site_id 隔离)
- `Scheduler`:定时调度器(从 `scheduled_tasks` 表读取配置,自动入队)
同时注册触发器 job handler
- `task_generator`:任务生成器(每日凌晨 4:00
- `task_expiry_check`:任务过期检查(每小时)
- `recall_completion_check`召回完成检测ETL 数据更新后)
- `note_reclassify_backfill`:备注重分类回填(召回完成后)
## 路由总览
| 前缀 | 模块 | 说明 | 认证 |
|------|------|------|------|
| `/api/auth` | `auth.py` | 管理后台登录/刷新令牌 | 无 |
| `/api/xcx-auth` | `xcx_auth.py` | 小程序微信登录/申请/状态/店铺切换 | 部分 |
| `/api/xcx/tasks` | `xcx_tasks.py` | 小程序任务列表/详情/置顶/放弃/恢复 | JWT |
| `/api/xcx/notes` | `xcx_notes.py` | 小程序备注 CRUD | JWT |
| `/api/xcx/performance` | `xcx_performance.py` | 小程序绩效概览/明细 | JWT |
| `/api/xcx/config` | `xcx_config.py` | 小程序配置(项目类型筛选器等) | JWT |
| `/api/xcx/board` | `xcx_board.py` | 小程序三看板(助教/客户/财务) | JWT |
| `/api/admin/applications` | `admin_applications.py` | 管理端申请审核 | JWT |
| `/api/business-day` | `business_day.py` | 营业日配置查询 | JWT |
| `/api/tasks` | `tasks.py` | 任务注册表/Flow 定义/配置验证 | JWT |
| `/api/execution` | `execution.py` | 任务执行/队列管理/历史/日志 | JWT |
| `/api/schedules` | `schedules.py` | 调度任务 CRUD + 启停 | JWT |
| `/api/db` | `db_viewer.py` | ETL 数据库只读查看器 | JWT |
| `/api/etl-status` | `etl_status.py` | ETL 游标/执行记录监控 | JWT |
| `/api/env-config` | `env_config.py` | 环境变量查看/编辑 | JWT |
| `/api/xcx-test` | `xcx_test.py` | MVP 全链路验证 | 无 |
| `/api/wx-callback` | `wx_callback.py` | 微信消息推送回调 | 签名验证 |
| `/api/retention-clue` | `member_retention_clue.py` | 维客线索 CRUD | JWT |
| `/api/tenant/auth` | `tenant_auth.py` | 租户管理员登录/刷新令牌 | 无 |
| `/api/tenant` | `tenant_users.py` | 租户用户审核/管理(申请列表/关联建议/审核/用户编辑/绑定) | 租户JWT |
| `/api/tenant/excel` | `tenant_excel.py` | 租户 Excel 上传/校验/冲突/确认/记录/模板下载 | 租户JWT |
| `/api/tenant` | `tenant_clues.py` | 租户维客线索管理(客户搜索/线索CRUD/隐藏显示) | 租户JWT |
| `/api/tenant/site-admins` | `tenant_site_admins.py` | 店铺管理员 CRUD列表/创建/编辑/删除/重置密码,仅 tenant_admin | 租户JWT |
| `/api/admin` | `admin_tenant_admins.py` | 管理端租户管理员 CRUD列表/创建/编辑/删除/重置密码) | JWT+管理员 |
| `/api/admin` | `admin_registry.py` | 注册体系管理(租户列表/店铺列表/简写ID/店铺同步) | JWT+管理员 |
| `/api/admin/ai` | `admin_ai.py` | AI 监控后台Dashboard/调度状态/调用明细/缓存/预算/批量/告警13 端点) | JWT+管理员 |
| `/api/admin/dev-trace` | `admin_dev_trace.py` | 开发调试全链路日志(日期/请求列表/详情/清理/设置/覆盖率8 端点) | JWT+管理员 |
| `/api/admin/task-engine` | `admin_task_engine.py` | P18 任务引擎运营看板(转移日志分页+历史、待审核任务分页+重新分配+关闭、参数管理 CRUD9 端点) | JWT+管理员 |
| `/api/xcx/chat` | `xcx_chat.py` | 小程序 CHAT 对话/消息/发送/SSE 流式 | JWT |
| `/api/admin/db-health` | `admin_db_health.py` | 数据库健康监控4 库连接池/大小/慢查询) | JWT |
| `/api/admin/triggers` | `admin_triggers.py` | 触发器统一视图biz/ai/etl 三源聚合) | JWT |
| `/api/trigger-jobs` | `trigger_jobs.py` | 触发器任务管理(列表/详情/PATCH 配置编辑) | JWT |
| `/api/ops` | `ops_panel.py` | 运维面板(服务启停/Git/系统信息) | 无 |
| `/ws/logs` | `ws/logs.py` | WebSocket 实时日志推送 | — |
| `/health` | `main.py` | 健康检查 | 无 |
> 详细 API 端点说明见 [`docs/API-REFERENCE.md`](docs/API-REFERENCE.md)
## 服务层
| 模块 | 职责 |
|------|------|
| `wechat.py` | 微信 `code2session` 接口调用 |
| `matching.py` | 用户申请时的人员匹配(助教/员工) |
| `application.py` | 用户入驻申请的创建/审批/拒绝 |
| `role.py` | 用户权限查询/门店角色检查 |
| `scheduler.py` | 定时调度引擎cron 解析 + next_run 计算) |
| `task_executor.py` | ETL CLI 子进程执行 + 日志广播 |
| `task_queue.py` | 任务队列管理(入队/消费/重排) |
| `task_registry.py` | ETL 任务/Flow/DWD 表静态注册表 |
| `cli_builder.py` | ETL CLI 命令构建器 |
| `task_generator.py` | 任务生成器(四级漏斗 + 保底 relationship_building独立连接 |
| `task_manager.py` | 任务管理(置顶/放弃/状态变更) |
| `task_expiry.py` | 任务过期检查与处理 |
| `task_manager.py` | 任务管理CRUD + 列表扩展 + 详情) |
| `performance_service.py` | 绩效概览 + 明细ETL 直连查询) |
| `note_service.py` | 备注服务CRUD + 星星评分) |
| `fdw_queries.py` | ETL 查询集中封装(直连 ETL 库 + 门店隔离 RLS含区域日粒度查询`get_finance_overview_area`/`get_finance_revenue_area`)和缓存读写(`get_finance_board_cache`/`set_finance_board_cache` |
| `note_reclassifier.py` | 备注重分类(召回完成后回填) |
| `recall_detector.py` | 召回完成检测ETL 数据更新触发) |
| `trigger_scheduler.py` | 触发器调度器cron/interval/event |
| `chat_service.py` | CHAT 模块业务逻辑(对话管理/消息持久化/referenceCard |
| `ai/admin_service.py` | AI 监控后台聚合服务Dashboard 统计/批量执行/告警管理) |
| `ai/cleanup_service.py` | AI 数据清理服务90 天保留 + 缓存上限 20000/App |
| `admin_task_engine.py` | P18 任务引擎运营看板路由(转移日志/待审核任务/参数管理9 端点) |
## AI 模块NS2 Prompt 细化)
8 个千问 AI 应用,通过百炼平台调用 Qwen3.5-Plus 模型。分三层架构:
```
应用层apps/app1_chat ~ app8_consolidation
↓ 调用
数据获取层data_fetchers/ ← NS2 新增
↓ 查询
基础设施层database.py / cache_service.py / dashscope_client.py
```
### 数据获取层(`app/ai/data_fetchers/`
NS2 新增的共享模块,封装 FDW 查询逻辑,供多个应用复用:
| 函数 | 数据来源 | 消费方 |
|------|---------|--------|
| `fetch_member_consumption_data()` | ETL FDW 视图(结算/商品/会员卡/到店) | App3/6/7 |
| `fetch_member_notes()` | `biz.notes` | App4/6 |
| `fetch_assistant_info()` | ETL FDW 视图(助教维度/月度汇总) | App4/5 |
| `fetch_service_history()` | ETL FDW 视图(服务日志/亲密度) | App4/5 |
| `build_page_text()` | 多数据源(按 contextType 路由) | App1 |
关键约束:
- 金额口径使用 `items_sum`,禁止 `consume_money`
- 所有 FDW 查询通过 `SET LOCAL app.current_site_id` 实现 RLS 隔离
- 部分数据获取失败不阻断 Prompt 生成(错误降级)
### 页面上下文App1
App1 通用对话支持 10 种页面入口,通过 `contextType` 路由到对应的文本化函数:
`task-detail` / `customer-detail` / `coach-detail` / `task-list` / `customer-service-records` / `board-finance` / `board-customer` / `board-coach` / `performance` / `my-profile`
每种入口自动获取页面数据并格式化为结构化中文文本,注入 system prompt。
## 依赖
```
fastapi>=0.115
uvicorn[standard]>=0.34
psycopg2-binary>=2.9
python-dotenv>=1.0
python-jose[cryptography]>=3.3
bcrypt>=4.0
psutil>=5.9
neozqyy-sharedworkspace 引用)
```
## Roadmap
- [ ] RBAC 权限中间件(基于 `auth.role_permissions` 表)
- [x] 全局响应包装中间件 + CamelModel 基类RNS1.0
- [ ] 数据看板 API助教业绩、财务日报、客户分析
- [ ] 任务审批流 API
- [ ] 消息推送(微信模板消息/订阅消息)
- [ ] API 限流与审计日志