Files
group_fqcd_jr/README.md
2026-09-14 01:07:43 +08:00

487 lines
12 KiB
Markdown
Raw Permalink 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.
# 南方基金智能业务平台
本项目是一个基于 FastAPI 和 MVC+S 架构的金融业务 Agent 平台,当前包含以下三项核心业务:
1. 场外基金申购/赎回运营流程
2. 产品推介材料与宣传海报生成
3. 金融自然语言转 SQL(NL2SQL)查询
项目中的场外基金运营、产品推介材料与场内基金模拟交易相互隔离。场外业务使用独立的
`offsite_fund_*` 数据表和接口,不写入场内交易表。
## 一、技术栈
- Python `3.13`
- FastAPI、Uvicorn
- SQLAlchemy 2.x、Alembic
- MySQL、Redis
- Pydantic v2
- JWT + RBAC
- `python-pptx`、OpenPyXL、Pillow、Matplotlib
- 可选:阿里云 DocMind/OCR、DeepSeek、SMTP、Milvus、Neo4j
## 二、项目结构
```text
group_fqcd_jr/
├── app/
│ ├── api/controllers/ # HTTP 路由和请求参数校验
│ ├── api/schemas/ # 请求/响应模型
│ ├── core/ # 业务契约、配置和公共规则
│ ├── model/ # SQLAlchemy 数据模型
│ ├── service/ # 业务编排、规则和数据访问
│ ├── infrastructure/ # 数据库、缓存和外部基础设施适配
│ └── worker/ # 异步 Worker
├── data/ # 测试与演示数据集
├── docs/ # 架构、接口、数据库和业务说明
├── tests/ # 单元、契约、集成和环境测试
├── tools/ # 迁移、种子、检查和测试工具
├── alembic/ # 数据库迁移
├── hq.py # 南方基金行情数据适配模块
├── nl2sql_yc.py # 金融 NL2SQL 兼容入口和查询逻辑
├── .env.example # 环境变量模板
└── README.md
```
## 三、环境准备
项目要求 Python `>=3.13,<3.14`。建议使用独立虚拟环境:
```powershell
conda create -n jr_py313 python=3.13
conda activate jr_py313
pip install -r requirements.txt
```
复制配置文件:
```powershell
Copy-Item .env.example .env
```
然后根据本机环境修改 `.env`,至少配置:
```text
MYSQL_DSN
JWT_PRIVATE_KEY_PATH
JWT_PUBLIC_KEY_PATH
```
`.env`、JWT 私钥、模型密钥和真实外部服务凭据禁止提交到 Git。
## 四、启动服务
### 4.1 数据库迁移
请确保 MySQL 已启动,并且 `.env` 中的数据库连接可用:
```powershell
alembic upgrade head
python tools/audit_schema.py
```
### 4.2 启动 HTTP 服务
```powershell
python -m uvicorn app.main:app --host 127.0.0.1 --port 8099
```
服务地址:
```text
http://127.0.0.1:8099
```
OpenAPI 文档:
```text
http://127.0.0.1:8099/docs
```
### 4.3 启动 Worker
需要异步处理 Agent 运行或场外邮件时,另开终端:
```powershell
python -m app.worker
```
Worker 是否启用场外收信,取决于:
```text
OFFSITE_MAIL_WORKER_ENABLED
OFFSITE_IMAP_ENABLED
OFFSITE_WORKER_USER_ID
```
## 五、功能一:场外基金申购/赎回
### 5.1 功能说明
场外流程面向运营人员,主要处理:
```text
邮件接收
→ 附件保存
→ OCR/文档识别
→ 结构化字段提取
→ 申购/赎回规则计算
→ NL2SQL 查询资金和持仓数据
→ 运营人员确认
→ 创建通知
→ 发送或 dry-run
→ 审计和统计
```
支持的单据类型:
- `subscription`:申购
- `redemption`:赎回
- `summary`:汇总材料
- `other`:其他材料
系统保留原始邮件、附件、识别结果、查询记录、规则结果、人工修正记录和审计记录。
人工修正不会覆盖 Agent 原始识别值。
### 5.2 主要接口
基础路径:
```text
/api/v1/offsite-fund
```
| 方法 | 路径 | 用途 |
|---|---|---|
| `GET` | `/mails` | 分页查询场外邮件 |
| `GET` | `/mails/{mail_id}` | 查看邮件详情 |
| `POST` | `/mails/{mail_id}/deletions` | 软删除邮件 |
| `GET` | `/mails/{mail_id}/recognition-fields` | 查看 OCR 识别字段 |
| `PUT` | `/mails/{mail_id}/recognition-fields` | 保存 OCR 字段人工修正 |
| `GET` | `/documents/{task_id}/nl2sql-fields` | 查看 NL2SQL 返回字段 |
| `PUT` | `/documents/{task_id}/nl2sql-fields` | 保存 NL2SQL 字段人工修正 |
| `GET` | `/documents/{task_id}/rule-results` | 查看规则判定结果 |
| `POST` | `/documents/{task_id}/rule-results/recalculations` | 使用已有结果重新判定 |
| `GET` | `/mailbox-status` | 查看收件游标状态 |
| `POST` | `/mailbox-status/recoveries` | 恢复被阻塞的收件游标 |
| `GET` | `/attachments/{attachment_id}/file` | 预览或下载原始附件 |
| `POST` | `/documents/{task_id}/confirmations` | 运营人员确认单据 |
| `POST` | `/documents/{task_id}/recognition-retries` | 重试识别异常单据 |
| `POST` | `/documents/{task_id}/notifications` | 创建运营通知 |
| `POST` | `/notifications/{notification_id}/send` | 发送通知 |
| `POST` | `/settlement-statistics/recalculate` | 重算结算统计 |
触发场外单据 NL2SQL 核对的接口为:
```text
POST /api/tasks/{task_id}/trigger-agent-nl2sql
```
### 5.3 权限与安全
- 读取权限:`offsite:read`
- 写入权限:`offsite:write`
- 确认权限:`offsite:confirm`
- NL2SQL 权限:`offsite:nl2sql`
- 通知权限:`offsite:notify`
- 请求中的 `operator_id` 必须与 JWT 身份一致
- 所有写操作都进行权限校验、操作人校验、审计和状态流转校验
- 通知发送支持幂等,SMTP 默认关闭并使用 dry-run
## 六、功能二:产品推介材料与宣传海报生成
### 6.1 功能说明
该模块用于新产品的结构化资料整理和宣传材料生成。当前生成链路为:
```text
创建任务
→ 填写产品、经理、团队、策略、费用、业绩和风险资料
→ 上传经理照片、业绩数据、来源证据或模板
→ 合规检查
→ 生成 PPTX、宣传海报和可选 PDF
→ 审核
→ 发送给指定投顾
```
支持的输入附件:
- `manager_photo`:基金经理照片
- `performance_data`:CSV/XLSX 业绩数据
- `source_evidence`:来源证据
- `template_file`:材料模板
支持的输出格式:
- `pptx`
- `poster`
- `pdf`,需要配置 LibreOffice/`soffice` 等转换器
模块会执行风险披露、费用结构、业绩数据、输入完整性和生成文本合规检查。
合规阻断时返回具体 findings 和补齐建议,不继续生成材料。
### 6.2 主要接口
基础路径:
```text
/api/v1/fund-promotion-materials
```
| 方法 | 路径 | 用途 |
|---|---|---|
| `POST` | `/` | 创建推介材料任务 |
| `PUT` | `/{task_no}/inputs` | 保存结构化输入资料 |
| `POST` | `/{task_no}/attachments` | 上传照片、业绩文件或证据 |
| `POST` | `/{task_no}/generations` | 生成推介材料 |
| `GET` | `/{task_no}/compliance-checks` | 查看合规检查结果 |
| `GET` | `/{task_no}` | 查询任务和已审核材料 |
| `POST` | `/{task_no}/reviews` | 审核、驳回或要求修改 |
| `POST` | `/{task_no}/deliveries` | 发送给投顾 |
创建任务和写入操作必须提供请求头:
```text
Idempotency-Key: <唯一请求键>
```
### 6.3 权限与状态
主要权限:
- `promotion:write`
- `promotion:read`
- `promotion:review`
- `promotion:deliver`
材料任务状态包括:
```text
draft
→ input_ready
→ generating
→ generated
→ pending_review
→ approved
→ sent
```
异常状态包括:
```text
compliance_failed
rejected
failed
```
生成的文件默认保存到:
```text
data/promotion_materials/
```
## 七、功能三:金融 NL2SQL
### 7.1 功能说明
NL2SQL 将自然语言问题转换为经过权限、业务域、表白名单和只读校验的 SQL。
业务 Agent 不直接连接数据库,而是通过公共只读工具调用:
```text
业务 Agent
→ BaseAgent.call_tool
→ ToolExecutor
→ query_financial_data
→ 只读金融数据表
```
工具名称:
```text
query_financial_data
```
权限码:
```text
financial:nl2sql:read
```
### 7.2 支持范围
当前纳入查询范围的主要表:
```text
sys_customer_assignment
fin_customer_profile
fin_risk_assessment
fin_product
fin_fee_rule
fin_market_price
fin_nav_history
fin_holding
fin_transaction
fin_sim_order
fin_sim_account
fin_cash_ledger
client_facing_content
```
支持:
- 基金净值、行情和历史收益查询
- 费率和费用查询
- 客户风险测评和画像查询
- 持仓、交易、订单、账户和资金流水查询
- 历史范围查询
- 最多跨三个业务域查询
- 结果行数限制,默认 50,最大 200
- SQL dry-run
不支持或会被拒绝:
- 非白名单表
- 非 `SELECT` 查询
- 未通过客户数据范围校验的查询
- 当前快照表的历史时点查询
- 模糊且未确认查询范围、指标口径或时间条件的问题
### 7.3 调用示例
```python
result = await self.call_tool(
"query_financial_data",
{
"question": "查询基金代码 000001 最近 30 天的净值",
"dry_run": False,
"limit": 50,
},
intent="financial_query",
context=context,
)
```
模糊问题会返回:
```json
{
"status": "need_confirmation",
"message": "请确认查询范围、指标口径和时间条件。"
}
```
工具结果包含查询计划、SQL、参数、权限检查和执行摘要,并进入统一审计和运行持久化链路。
## 八、测试数据集
测试数据位于:
```text
data/
```
当前数据集概况:
| 类型 | 数量 | 用途 |
|---|---:|---|
| `.eml` | 13 | 场外邮件及附件识别 |
| `.csv` / `.xlsx` | 8 | 推介材料业绩数据 |
| `.png` / `.jpg` | 35 | 经理照片、宣传图和测试图片 |
| `.pptx` | 10 | 推介材料结构检查 |
| `.pdf` | 9 | PDF 文件有效性检查 |
测试数据只用于本地测试和演示,不应直接作为生产业务数据导入。
## 九、测试与代码检查
### 9.1 运行完整测试
普通单元和契约测试:
```powershell
python -m pytest tests/unit tests/contract -q -p no:cacheprovider
```
使用独立 MySQL 测试库并执行测试数据隔离:
```powershell
python -m tools.run_tests_on_test_db tests -p no:cacheprovider
```
### 9.2 运行三项功能定向测试
```powershell
python -m pytest `
tests/integration/test_offsite_fund_api.py `
tests/integration/test_offsite_nl2sql_fields.py `
tests/integration/test_offsite_notification_send.py `
tests/integration/test_promotion_material_api.py `
tests/unit/service/test_suitability_service.py `
tests/contract/test_financial_nl2sql_tool_contract.py `
-q -p no:cacheprovider
```
### 9.3 代码质量检查
```powershell
python -m ruff check app tests tools alembic
python -m mypy app
git diff --check
```
### 9.4 测试基线
最近一次项目回归记录:
```text
关键三项功能定向测试:85 passed
全量自动化测试:559 passed, 1 skipped
```
Redis、真实 IMAP/OCR/DeepSeek/SMTP、Neo4j、Milvus 和浏览器 E2E 是否能执行,
取决于本机服务和凭据配置。外部服务关闭或不可用时,测试使用本地数据集、Mock 或 dry-run。
## 十、配置开关
场外邮件和外部识别:
```text
OFFSITE_IMAP_ENABLED=false
OFFSITE_MAIL_WORKER_ENABLED=false
OFFSITE_OCR_ENABLED=false
OFFSITE_DEEPSEEK_ENABLED=false
OFFSITE_SMTP_ENABLED=false
OFFSITE_SMTP_DRY_RUN=true
```
产品推介材料:
```text
PROMOTION_MATERIAL_STORAGE_DIR=data/promotion_materials
PROMOTION_PDF_ENABLED=false
PROMOTION_PDF_CONVERTER_PATH=
```
启用真实服务前,请先完成网络、凭据、权限、数据脱敏和回滚方案确认。
## 十一、安全与开发约束
- 所有业务请求都应经过统一 JWT、RBAC、客户范围和审计链路。
- 不在业务 Agent 中自行读取密钥、直接连接数据库或绕过 `ToolExecutor`。
- 场外业务不能写入场内交易表。
- 数据库结构只能通过 Alembic 迁移修改。
- 不删除、重命名或复用已有表和字段;历史结构不足时新增字段、新表或兼容读写。
- 所有写接口应设计幂等键、状态机和重复提交保护。
- 真实外部服务默认关闭,测试优先使用本地数据、Mock 和 dry-run。
## 十二、相关文档
- `docs/MVC/MVC架构.md`:项目架构和目录职责
- `docs/00-新数据库基线设计.md`:数据库业务基线
- `docs/05-接口文档.md`:接口权威说明
- `docs/14-Agent组员统一接入说明书.md`:Agent 接入规范
- `docs/15-金融NL2SQL工具接入说明.md`:NL2SQL 工具规范
- `product_promotion_to_do_list.md`:推介材料模块开发记录
- `测试报告/2026-09-12.md`:三项功能数据集测试报告