# 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