finyx_data_ai/.cursorrules
2026-01-11 07:48:19 +08:00

557 lines
15 KiB
Plaintext
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.

# Finyx Data AI - Cursor 开发规则
## 📋 项目概述
本项目是数据资产盘点系统的后端 API 服务,使用 FastAPI 框架开发,提供数据资产盘点、场景挖掘和报告生成等功能。
## 🏗️ 技术栈
- **Web 框架**: FastAPI 0.104+
- **数据验证**: Pydantic 2.0+
- **异步支持**: asyncio, httpx
- **大模型**: 通义千问 (DashScope)、OpenAI
- **日志**: Loguru
- **文档处理**: pandas, openpyxl, python-docx, pdfplumber
- **Python 版本**: 3.10+
## 📁 项目结构规范
```
app/
├── api/ # API 路由(按模块组织)
│ ├── v1/ # API v1 版本
│ │ ├── inventory/ # 数据盘点模块
│ │ ├── value/ # 场景挖掘模块
│ │ └── delivery/ # 报告生成模块
│ └── common/ # 通用路由
├── core/ # 核心模块(配置、异常、响应格式)
├── models/ # 数据模型层ORM如需要
├── schemas/ # 数据模式层Pydantic 模型)
├── services/ # 业务逻辑层
├── utils/ # 工具函数
└── main.py # 应用入口
```
### 目录使用规范
- **`api/`**: 只包含路由定义和请求处理,不包含业务逻辑
- **`schemas/`**: 定义所有 Pydantic 模型(请求、响应)
- **`services/`**: 包含业务逻辑实现(可选的,复杂逻辑建议放这里)
- **`utils/`**: 通用工具函数,应该是无状态的
- **`core/`**: 核心配置和基础类,不应该频繁修改
## 💻 代码风格规范
### 1. 导入顺序
```python
# 标准库
import os
from typing import Optional, List
from pathlib import Path
# 第三方库
from fastapi import FastAPI, UploadFile, File
from pydantic import BaseModel, Field
import pandas as pd
# 本地模块
from app.core.config import settings
from app.core.response import success_response, error_response
from app.utils.logger import logger
```
### 2. 类型注解
- **必须使用类型注解**:所有函数参数和返回值
- 使用 `Optional[T]` 表示可选类型
- 使用 `List[T]`, `Dict[K, V]` 等明确容器类型
```python
async def process_file(
file: UploadFile,
project_id: str,
file_type: Optional[str] = None
) -> dict:
"""处理文件"""
pass
```
### 3. 文档字符串Docstring
- 所有公共函数和类必须有文档字符串
- 使用 Google 风格或 NumPy 风格
- 说明参数、返回值和可能的异常
```python
async def parse_document(file_path: str, file_type: str) -> List[TableInfo]:
"""
解析文档文件,提取表结构信息
Args:
file_path: 文件路径
file_type: 文件类型excel/word/pdf
Returns:
表信息列表
Raises:
FileParseException: 文件解析失败时抛出
"""
pass
```
## 🔌 API 开发规范
### 1. 路由定义
- 使用路由装饰器定义路径和 HTTP 方法
- 使用 `response_model` 指定响应模型
- 添加标签tags用于 API 文档分类
```python
from app.core.response import APIResponse
@router.post(
"/parse-document",
response_model=APIResponse[ParseDocumentResponse],
tags=["数据盘点"],
summary="文档解析接口",
description="解析上传的数据字典文档,提取表结构信息"
)
async def parse_document(request: ParseDocumentRequest):
"""文档解析接口"""
pass
```
### 2. 请求和响应模型
- **所有请求和响应必须使用 Pydantic 模型**
- 模型定义在 `app/schemas/` 目录下
- 使用 `Field` 添加字段描述和验证
```python
from pydantic import BaseModel, Field
from typing import Optional, List
class ParseDocumentRequest(BaseModel):
"""文档解析请求模型"""
project_id: str = Field(..., description="项目ID")
file_type: Optional[str] = Field(None, description="文件类型,可选,自动识别")
class ParseDocumentResponse(BaseModel):
"""文档解析响应模型"""
tables: List[TableInfo] = Field(..., description="表列表")
total_tables: int = Field(..., description="总表数")
```
### 3. 响应格式
- **统一使用 `success_response()` 和 `error_response()`**
- 不要直接返回字典或 JSONResponse特殊情况除外
```python
from app.core.response import success_response, error_response
# ✅ 正确
return success_response(
data={"result": "..."},
message="操作成功"
)
# ❌ 错误
return {"success": True, "data": {...}}
```
### 4. 异常处理
- **使用自定义异常类**(在 `app/core/exceptions.py` 中定义)
- 让全局异常处理器捕获,不要手动返回错误响应
- 记录异常日志
```python
from app.core.exceptions import FileUploadException, FileParseException
from app.utils.logger import logger
# ✅ 正确
if not validate_file(file):
raise FileUploadException("文件验证失败", error_detail="文件格式不支持")
try:
result = parse_file(file_path)
except Exception as e:
logger.exception(f"文件解析失败: {str(e)}")
raise FileParseException("文件解析失败", error_detail=str(e))
```
## 🤖 大模型接口开发规范
### 1. 使用 LLM 客户端
- **统一使用 `app/utils/llm_client.py` 中的 `llm_client`**
- 不要直接调用大模型 API
- 处理超时和重试(已在客户端中实现)
```python
from app.utils.llm_client import llm_client
# ✅ 正确
response = await llm_client.call(
prompt=user_prompt,
system_prompt=system_prompt,
temperature=0.3,
model="qwen-max"
)
result = llm_client.parse_json_response(response)
# ❌ 错误
# 直接调用 httpx 或 requests
```
### 2. 提示词构建
- 提示词应该清晰、结构化
- 使用模板字符串或格式化函数
- 明确输出格式要求JSON Schema
```python
SYSTEM_PROMPT = """你是数据资产管理专家..."""
def build_prompt(tables: List[TableInfo], context: str) -> str:
"""构建提示词"""
tables_info = format_tables_info(tables)
return f"""
请分析以下数据资产:
{tables_info}
业务背景:{context}
请以 JSON 格式输出结果。
"""
```
### 3. 响应解析和验证
- 使用 `llm_client.parse_json_response()` 解析 JSON
- 验证返回数据的完整性和正确性
- 处理解析错误
```python
try:
response_text = await llm_client.call(prompt)
result = llm_client.parse_json_response(response_text)
# 验证数据
validate_result(result)
except json.JSONDecodeError as e:
logger.error(f"JSON 解析失败: {e}")
raise LLMAPIException("大模型返回格式错误")
```
## 📄 文件处理规范
### 1. 文件上传
- **使用 `app/utils/file_handler.py` 中的工具函数**
- 验证文件类型和大小
- 保存到指定目录并返回路径
- 清理临时文件
```python
from app.utils.file_handler import save_upload_file, cleanup_temp_file
# ✅ 正确
file_path = await save_upload_file(file, project_id)
try:
# 处理文件
result = process_file(file_path)
finally:
# 清理临时文件
cleanup_temp_file(file_path)
```
### 2. 文件类型检测
- 使用 `detect_file_type()` 函数
- 支持的文件类型excel, word, pdf, csv
```python
from app.utils.file_handler import detect_file_type
file_type = detect_file_type(file.filename)
```
## 📝 日志使用规范
### 1. 使用日志记录器
- **统一使用 `app/utils/logger.py` 中的 `logger`**
- 不同级别的日志:
- `logger.info()` - 信息日志(正常流程)
- `logger.warning()` - 警告日志(异常但不影响功能)
- `logger.error()` - 错误日志(需要关注)
- `logger.exception()` - 异常日志(带堆栈信息)
```python
from app.utils.logger import logger
logger.info(f"开始处理文件: {file_path}")
logger.warning(f"文件格式可能不标准: {file_type}")
logger.error(f"文件解析失败: {error}")
logger.exception("未处理的异常") # 自动包含堆栈信息
```
### 2. 日志内容
- 包含关键信息文件路径、项目ID、错误详情等
- 不要记录敏感信息API Key、密码等
- 使用 f-string 格式化
## ⚙️ 配置管理规范
### 1. 使用配置对象
- **统一使用 `app/core/config.py` 中的 `settings`**
- 不要直接使用 `os.getenv()`
- 配置值通过环境变量设置
```python
from app.core.config import settings
# ✅ 正确
api_key = settings.DASHSCOPE_API_KEY
max_size = settings.MAX_UPLOAD_SIZE
# ❌ 错误
api_key = os.getenv("DASHSCOPE_API_KEY")
```
## 🧪 测试规范
### 1. 测试文件位置
- 测试文件放在 `tests/` 目录
- 测试文件名以 `test_` 开头
- 测试函数名以 `test_` 开头
### 2. 测试用例
- 覆盖正常情况和异常情况
- 使用 pytest 和 pytest-asyncio
- Mock 外部依赖(大模型 API、文件系统等
```python
import pytest
from fastapi.testclient import TestClient
from unittest.mock import patch, AsyncMock
@pytest.mark.asyncio
async def test_parse_document_success():
"""测试文档解析成功"""
with patch('app.services.document_parser.parse_excel') as mock_parse:
mock_parse.return_value = [table1, table2]
# 测试代码
pass
```
## 📚 文档规范
### 1. 代码注释
- 复杂逻辑必须有注释说明
- 函数参数和返回值说明在 docstring 中
- 使用中文注释(项目使用中文)
### 2. API 文档
- 使用 FastAPI 自动生成的文档
- 通过路由装饰器添加描述
- 使用 `summary` 和 `description` 参数
```python
@router.post(
"/api/v1/inventory/parse-document",
summary="文档解析",
description="解析上传的数据字典文档Excel/Word/PDF提取表结构信息",
response_description="解析结果,包含表列表和统计信息"
)
```
### 3. 文档文件管理规范
**⚠️ 重要规则:所有生成的文档文件必须统一放到 `docs/` 文件夹中**
#### 文档分类
- **项目文档**README、开发指南等放在项目根目录允许例外
- `README.md` - 项目说明
- `DEVELOPMENT.md` - 开发指南
- `QUICK_START.md` - 快速开始
- `API_OVERVIEW.md` - API 总览
- **接口开发文档****必须放在 `docs/` 文件夹中**
- `docs/01-parse-document.md` - 文档解析接口说明
- `docs/02-parse-sql-result.md` - SQL 结果解析接口说明
- `docs/03-parse-business-tables.md` - 业务表解析接口说明
- `docs/04-ai-analyze.md` - AI 分析接口说明
- `docs/05-scenario-recommendation.md` - 场景推荐接口说明
- `docs/06-scenario-optimization.md` - 场景优化接口说明
- `docs/07-generate-report.md` - 报告生成接口说明
- **项目进度和状态文档****必须放在 `docs/` 文件夹中**
- `docs/研发进度说明.md` - 研发进度汇总
- `docs/测试结果.md` - 测试结果报告
- `docs/技术架构.md` - 技术架构文档
- `docs/配置说明.md` - 配置说明文档
- **设计文档和技术文档****必须放在 `docs/` 文件夹中**
- `docs/数据资产盘点报告-大模型接口设计文档.md`
- `docs/数据库设计.md`
- `docs/API设计规范.md`
#### 规则要求
1. **所有新生成的文档(除项目根目录的必要文档外)都必须放在 `docs/` 文件夹中**
2. **不要直接在项目根目录创建文档文件**(如 `研发进度说明.md`、`测试结果.md` 等)
3. **如果需要在根目录放置文档,必须先评估是否应该放在 `docs/` 中**
4. **文档命名规范**
- 使用小写字母和连字符:`kebab-case.md`
- 中文文档可以使用中文名称:`研发进度说明.md`
- 技术文档建议使用英文:`api-design.md`
5. **文档组织**
- 相关文档放在同一目录
- 使用 `docs/README.md` 作为文档索引
- 大型文档可以创建子目录,如 `docs/api/`、`docs/architecture/`
#### 文档目录结构
```
docs/
├── README.md # 文档索引
├── 01-parse-document.md # 接口开发文档
├── 02-parse-sql-result.md
├── 03-parse-business-tables.md
├── 04-ai-analyze.md
├── 05-scenario-recommendation.md
├── 06-scenario-optimization.md
├── 07-generate-report.md
├── 研发进度说明.md # 项目状态文档
├── 数据资产盘点报告-大模型接口设计文档.md # 设计文档
└── [其他文档...]
```
#### 违反规则的后果
- ❌ **错误示例**:在项目根目录创建 `研发进度说明.md`
- ✅ **正确示例**:在 `docs/` 目录创建 `docs/研发进度说明.md`
**AI 助手在生成文档时必须遵守此规则,除非用户明确指定其他位置。**
## 🔒 安全规范
### 1. 输入验证
- 所有用户输入必须验证
- 使用 Pydantic 模型进行数据验证
- 验证文件类型、大小、路径等
### 2. 敏感信息
- 不要在代码中硬编码 API Key、密码等
- 使用环境变量存储敏感信息
- 不要在日志中记录敏感信息
### 3. 文件安全
- 验证文件扩展名(使用白名单)
- 限制文件大小
- 防止路径遍历攻击
- 及时清理临时文件
## 🚀 性能优化规范
### 1. 异步处理
- **文件 I/O 和网络请求必须使用 async/await**
- 批量操作考虑并发处理
- 耗时操作考虑异步任务队列
### 2. 错误重试
- 大模型 API 调用失败时自动重试(已在客户端实现)
- 其他网络请求考虑重试机制
- 使用指数退避策略
## 📦 依赖管理
### 1. 添加依赖
- 在 `requirements.txt` 中添加依赖
- 指定版本号(使用 `>=` 允许小版本更新)
- 更新后运行 `pip install -r requirements.txt`
### 2. 导入检查
- 确保所有导入的模块都在 `requirements.txt` 中
- 不要使用未声明的依赖
## ✅ 开发检查清单
开发新接口时,请确保:
- [ ] 请求和响应使用 Pydantic 模型定义
- [ ] 使用 `success_response()` 返回成功响应
- [ ] 使用自定义异常类抛出错误
- [ ] 添加日志记录(关键步骤)
- [ ] 验证输入数据(文件类型、大小等)
- [ ] 处理异常情况try-except
- [ ] 清理临时资源(文件、连接等)
- [ ] 添加 API 文档描述summary、description
- [ ] 编写单元测试(至少覆盖主要流程)
- [ ] 代码通过 lint 检查(无错误)
## 🎯 接口开发优先级
按照以下顺序开发接口:
1. **高优先级**(核心功能):
- `/api/v1/inventory/ai-analyze` - 数据资产智能识别
- `/api/v1/delivery/generate-report` - 完整报告生成
- `/api/v1/value/scenario-recommendation` - 潜在场景推荐
2. **中优先级**:
- `/api/v1/inventory/parse-document` - 文档解析
- `/api/v1/inventory/parse-business-tables` - 业务表解析
- `/api/v1/value/scenario-optimization` - 场景优化
3. **低优先级**:
- `/api/v1/inventory/parse-sql-result` - SQL 结果解析
## 📖 参考文档
- **开发文档**: `docs/` 目录下的各接口详细开发说明
- **开发指南**: `DEVELOPMENT.md`
- **API 总览**: `API_OVERVIEW.md`
- **框架总结**: `FRAMEWORK_SUMMARY.md`
## 🔄 代码审查重点
审查代码时关注:
1. **是否遵循项目结构规范**
2. **是否使用统一的响应格式和异常处理**
3. **是否添加了必要的日志记录**
4. **是否验证了输入数据**
5. **是否处理了异常情况**
6. **是否清理了临时资源**
7. **是否有适当的文档字符串**
8. **是否使用了类型注解**
---
**最后更新**: 2025-01-XX
**维护者**: Finyx AI Team