| # 项目优化方案 |
|
|
| ## 问题回顾 |
| 在之前的检查中,我们发现了以下主要问题: |
| 1. **前端与后端集成问题**:前端页面(如策略列表、回测结果)目前使用模拟数据,未与后端 API 实际集成。 |
| 2. **后端安全隐患**:后端 API 认证机制被暂时移除,存在安全风险。 |
| 3. **API 响应模型问题**:`get_stock_selections` API 的响应模型定义不明确,可能影响文档和客户端解析。 |
|
|
| ## 优化方案总览 |
| 本次优化将围绕以下核心目标展开: |
| 1. **实现前后端数据流打通**:确保前端从后端获取真实数据。 |
| 2. **强化后端安全性**:恢复并完善认证授权机制。 |
| 3. **提升 API 质量**:修正 API 响应模型,确保其规范性。 |
| 4. **建立开发规范**:引入一致性检查,确保代码质量和可维护性。 |
| 5. **初步性能优化**:为关键数据流引入缓存机制。 |
|
|
| ## 细化优化方案 |
|
|
| ### 1. 前端与后端集成优化 |
| **目标**:将前端的模拟数据替换为真实的后端 API 调用。 |
|
|
| **具体任务**: |
| 1. **统一 API 服务层**: |
| * 在 `qsss-web/src/lib/api.ts` 中定义所有后端 API 请求函数。 |
| * 使用 `fetch` 或 `axios`(如果项目中已引入)进行 HTTP 请求。 |
| * 统一处理认证 token 的传递(例如,从 `NextAuth.js` 的 `getSession` 获取)。 |
| * 统一处理 API 错误,例如通过 `try-catch` 捕获异常并抛出自定义错误,或使用 `toast` 提示。 |
| * **示例 (`qsss-web/src/lib/api.ts`)**: |
| ```typescript |
| // qsss-web/src/lib/api.ts |
| import { getSession } from 'next-auth/react'; // 假设使用 NextAuth.js |
| |
| const API_BASE_URL = process.env.NEXT_PUBLIC_BACKEND_URL || '/api/proxy'; // 后端API基础URL,优先使用环境变量,否则使用代理 |
| |
| async function fetchApi(endpoint: string, options?: RequestInit) { |
| const session = await getSession(); // 获取用户会话 |
| const headers = { |
| 'Content-Type': 'application/json', |
| ...(session?.accessToken && { Authorization: `Bearer ${session.accessToken}` }), // 如果有token,添加认证头 |
| ...options?.headers, |
| }; |
| |
| const response = await fetch(`${API_BASE_URL}${endpoint}`, { |
| ...options, |
| headers, |
| }); |
| |
| if (!response.ok) { |
| const errorData = await response.json(); |
| throw new Error(errorData.detail || 'API 请求失败'); // 抛出后端返回的错误信息 |
| } |
| return response.json(); |
| } |
| |
| // 获取策略列表 |
| export const getStrategies = async (page: number, pageSize: number, search: string) => { |
| return fetchApi(`/strategies?skip=${(page - 1) * pageSize}&limit=${pageSize}&search=${search}`); |
| }; |
| |
| // 运行回测 |
| export const runBacktest = async (strategyId: string, backtestParams: any) => { |
| return fetchApi(`/strategies/${strategyId}/backtest`, { |
| method: 'POST', |
| body: JSON.stringify(backtestParams), |
| }); |
| }; |
| // ... 其他API函数 |
| ``` |
| 2. **修改 `qsss-web/src/app/strategies/page.tsx`**: |
| * 移除 `fetchStrategies` 模拟函数。 |
| * 在 `StrategiesPage` 组件中,使用 `getStrategies` API 函数获取数据。 |
| * 处理加载状态和错误状态,例如使用 `useState` 和 `useEffect` 或 `React Query` / `SWR`。 |
| 3. **修改 `qsss-web/src/app/backtest/page.tsx`**: |
| * 移除模拟数据和 `setTimeout` 逻辑。 |
| * 在 `handleBacktestSubmit` 函数中,调用 `runBacktest` API 函数。 |
| * 更新加载状态和错误处理。 |
| 4. **检查并完善 API 代理 (`qsss-web/src/app/api/proxy/route.ts`)**: |
| * 确保代理路由正确配置,将前端请求转发到后端服务。 |
| * **关键点**:`process.env.NEXT_PUBLIC_BACKEND_URL` 环境变量必须在部署时正确配置为后端服务的实际 URL。 |
| |
| ### 2. 后端安全性提升 |
| **目标**:恢复并加强后端 API 的认证和授权机制。 |
|
|
| **具体任务**: |
| 1. **恢复认证依赖**: |
| * 在 `backend/app/api/v1/endpoints/strategies.py` 中,取消注释所有需要认证的端点上的 `current_user: User = Depends(get_current_user)`。 |
| * 确保 `app.core.deps.py` 中的 `get_current_user` 函数能够正确验证 JWT token 并返回当前用户。 |
| 2. **权限细化**: |
| * 对于 `create_strategy`, `update_strategy`, `delete_strategy` 等操作,除了认证外,还需确保用户具有相应的权限(例如,只能修改或删除自己创建的策略,或者管理员可以操作所有策略)。代码中已包含此逻辑,需确保其正确启用。 |
| 3. **开发环境认证覆盖(可选但推荐)**: |
| * 为了方便开发和调试,可以考虑在开发环境中提供一个临时的认证覆盖机制,例如通过环境变量控制,避免每次调试都进行完整的认证流程。 |
| * **示例 (`backend/app/main.py` 或 `app/core/deps.py`)**: |
| ```python |
| # backend/app/core/deps.py (示例) |
| from app.models.user import User |
| |
| async def get_current_user_for_dev(): |
| # 仅在开发环境生效,返回一个模拟的管理员用户 |
| return User(id="dev_admin_user_id", username="dev_admin", is_admin=True) |
| |
| # 在 main.py 中根据环境选择依赖 |
| # if os.getenv("APP_ENV") == "development": |
| # app.dependency_overrides[get_current_user] = get_current_user_for_dev |
| ``` |
| |
| ### 3. API 响应模型修正 |
| **目标**:为 `get_stock_selections` API 定义明确的响应模型。 |
|
|
| **具体任务**: |
| 1. **定义 `SelectionResponse` 结构**: |
| * 在 `backend/app/schemas/strategy.py` 中,确保 `SelectionResponse` 包含所有返回字段,特别是 `stock` 字段应引用 `StockResponse` 或其简化版本。 |
| * **示例 (`backend/app/schemas/strategy.py`)**: |
| ```python |
| # backend/app/schemas/strategy.py |
| from pydantic import BaseModel |
| from datetime import date |
| from typing import Optional |
| from app.schemas.stock import StockResponse # 假设有StockResponse |
| |
| class SelectionResponse(BaseModel): |
| id: str |
| strategy_id: str |
| user_id: str |
| selection_date: date |
| stock_id: str |
| stock_code: str |
| stock_name: str |
| rank: int |
| score: Optional[float] = None |
| reason: Optional[str] = None |
| # 添加从 stock_data 来的字段,例如: |
| latest_price: Optional[float] = None |
| change_percent: Optional[float] = None |
| # ... 其他行情数据字段 |
| |
| class Config: |
| from_attributes = True # 兼容 SQLAlchemy ORM |
| ``` |
| 2. **更新 `backend/app/api/v1/endpoints/strategies.py`**: |
| * 将 `get_stock_selections` 函数的 `response_model` 从 `None` 修改为 `List[SelectionResponse]`。 |
| * 确保函数内部返回的数据结构与 `SelectionResponse` 模型严格匹配。 |
| |
| ### 4. 整体项目一致性检查 |
| **目标**:确保代码风格、数据模型和功能实现的一致性。 |
|
|
| **具体任务**: |
| 1. **代码风格统一**: |
| * 前端:配置 ESLint 和 Prettier,并集成到开发流程中,确保所有 TypeScript/JavaScript 代码遵循统一风格。 |
| * 后端:配置 Black 和 Flake8,确保所有 Python 代码遵循 PEP 8 规范。 |
| 2. **数据模型同步**: |
| * 定期审查前端(TypeScript 接口)和后端(Pydantic Schema, SQLAlchemy Models)的数据模型定义,确保它们之间的一致性。 |
| * 考虑使用工具(如 `openapi-typescript`)从 OpenAPI 规范自动生成前端类型定义,减少手动同步的工作量和错误。 |
| 3. **移除所有模拟数据**: |
| * 在整个前端项目中搜索并移除所有硬编码的模拟数据和 `setTimeout` 模拟 API 延迟的代码。 |
|
|
| ### 5. 性能优化建议 |
| **目标**:为关键数据流引入初步的缓存机制,提升响应速度。 |
|
|
| **具体任务**: |
| 1. **前端数据缓存**: |
| * 在前端使用 `SWR` 或 `React Query` 等库管理数据获取和缓存。这些库可以自动处理数据去重、缓存、重新验证等,显著提升用户体验。 |
| * **示例 (`qsss-web/src/app/strategies/page.tsx` 中使用 SWR)**: |
| ```typescript |
| // qsss-web/src/app/strategies/page.tsx |
| import useSWR from 'swr'; |
| import { getStrategies } from '@/lib/api'; // 导入统一的API函数 |
| |
| const fetcher = ([page, pageSize, search]: [number, number, string]) => getStrategies(page, pageSize, search); |
| |
| const StrategiesPage: React.FC<StrategiesPageProps> = ({ searchParams }) => { |
| const page = parseInt(searchParams.page || '1', 10); |
| const pageSize = parseInt(searchParams.pageSize || '10', 10); |
| const search = searchParams.search || ''; |
| |
| const { data, error, isLoading } = useSWR(['strategies', page, pageSize, search], fetcher); |
| |
| if (error) return <div>加载失败: {error.message}</div>; |
| if (isLoading) return <div>加载策略中...</div>; |
| |
| return ( |
| <RequireAuth> |
| <div className="container mx-auto p-4"> |
| <StrategyListClientWrapper |
| initialData={data?.data || []} // SWR 返回的数据结构可能需要调整 |
| total={data?.total || 0} |
| page={page} |
| pageSize={pageSize} |
| search={search} |
| /> |
| </div> |
| </RequireAuth> |
| ); |
| }; |
| ``` |
| 2. **后端 API 缓存(Redis)**: |
| * 对于不经常变动或计算成本较高的 API 端点(如 `get_strategies`),引入 Redis 缓存。 |
| * 需要安装 `redis` 库,并在 FastAPI 应用中集成缓存逻辑。 |
| * **示例 (`backend/app/core/config.py` 配置 Redis)**: |
| ```python |
| # backend/app/core/config.py |
| REDIS_URL: Optional[str] = os.getenv("REDIS_URL", "redis://localhost:6379/0") |
| ``` |
| * **示例 (`backend/app/api/v1/endpoints/strategies.py` 使用缓存)**: |
| ```python |
| # backend/app/api/v1/endpoints/strategies.py |
| from fastapi_cache.decorator import cache # 假设使用 fastapi-cache |
| |
| @router.get("", response_model=List[StrategyResponse]) |
| @cache(expire=300) # 缓存5分钟 |
| async def get_strategies(...): |
| # ... 现有逻辑 |
| ``` |
| |
| ### 实施风险与应对 |
| 1. **前后端数据模型不匹配**: |
| * **风险**:API 接口定义与实际数据结构不一致,导致前端解析失败。 |
| * **应对**:在开发过程中,前端和后端开发人员应密切沟通,共享最新的数据模型定义。考虑使用 OpenAPI/Swagger 自动生成客户端代码或类型定义。 |
| 2. **认证集成复杂性**: |
| * **风险**:NextAuth.js 与 FastAPI JWT 认证集成可能存在细节问题。 |
| * **应对**:仔细阅读 NextAuth.js 和 FastAPI JWT 的官方文档,确保 token 的生成、传递和验证逻辑正确无误。 |
| 3. **性能优化过度或不足**: |
| * **风险**:过早优化可能引入不必要的复杂性;优化不足可能导致未来性能瓶颈。 |
| * **应对**:遵循“先测量,后优化”的原则。在解决核心功能问题后,再进行性能测试和有针对性的优化。 |
|
|
| ## 未完成开发内容 |
|
|
| * **市场数据集成**:仅提供模拟数据流,未集成真实市场数据 |
|
|
| ## 已完成开发 |
|
|
| **选股结果过滤功能** |
| * 后端:实现策略条件过滤逻辑 |
| * 前端:完成条件传递和动态表格更新 |
| * 修复:解决变量冲突和类型错误 |
|
|
| **投资组合功能** |
| * 后端:实现Portfolio CRUD API端点 |
| * 前端:完成投资组合管理页面 |
| * 类型:统一前后端Portfolio模型 |
| * 导航:侧边栏添加投资组合入口 |
| * 修复:解决前端导入和后端UUID/JSON错误 |
|
|
| **仪表盘真实数据集成** |
| * 后端:实现市场指标、新闻、组合摘要API |
| * 前端:完成三大组件数据集成 |
| * 移除所有模拟数据逻辑 |
|
|
| ## 整体进度评估 |
|
|
| 已完成大部分核心功能,正在进行性能优化和细节完善。 |
|
|