diff --git a/CLAUDE.md b/CLAUDE.md index 0b2a0a43..e91100a0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,310 +1,879 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +本文件为 Claude Code (claude.ai/code) 提供在此代码库中工作的指导说明。 -## Project Overview +## 项目概览 -Hybrid React dashboard for financial/trading analysis with Flask backend. Built on Argon Dashboard Chakra PRO template. +混合式 React 仪表板,用于金融/交易分析,采用 Flask 后端。基于 Argon Dashboard Chakra PRO 模板构建。 -### Tech Stack +### 技术栈 -**Frontend** +**前端** - React 18.3.1 + Chakra UI 2.8.2 + Ant Design -- Redux Toolkit for state management -- React Router v6 with React.lazy() code splitting -- CRACO build system with aggressive webpack optimization -- Charts: ApexCharts, ECharts, Recharts, D3 -- Additional: Three.js, FullCalendar, Leaflet maps +- Redux Toolkit 用于状态管理 +- React Router v6 配合 React.lazy() 实现代码分割 +- CRACO 构建系统,具有激进的 webpack 优化 +- 图表库: ApexCharts、ECharts、Recharts、D3 +- 其他: Three.js、FullCalendar、Leaflet 地图 -**Backend** +**后端** - Flask + SQLAlchemy ORM -- ClickHouse (analytics) + MySQL/PostgreSQL (transactional) -- Flask-SocketIO for WebSocket real-time updates -- Celery + Redis for background jobs -- Tencent Cloud SMS + WeChat Pay integration +- ClickHouse(分析型数据库)+ MySQL/PostgreSQL(事务型数据库) +- Flask-SocketIO 实现 WebSocket 实时更新 +- Celery + Redis 处理后台任务 +- 腾讯云短信 + 微信支付集成 -## Development Commands +## 开发命令 -### Frontend Development +### 前端开发 ```bash -npm start # Start with mock data (.env.mock), proxies to localhost:5001 -npm run start:real # Start with real backend (.env.local) -npm run start:dev # Start with development config (.env.development) -npm run start:test # Starts both backend (app_2.py) and frontend (.env.test) concurrently -npm run dev # Alias for 'npm start' -npm run backend # Start Flask server only (python app_2.py) +npm start # 使用 mock 数据启动(.env.mock),代理到 localhost:5001 +npm run start:real # 使用真实后端启动(.env.local) +npm run start:dev # 使用开发配置启动(.env.development) +npm run start:test # 同时启动后端(app.py)和前端(.env.test) +npm run dev # 'npm start' 的别名 +npm run backend # 仅启动 Flask 服务器(python app.py) -npm run build # Production build with Gulp license headers -npm run build:analyze # Build with webpack bundle analyzer -npm test # Run React test suite with CRACO +npm run build # 生产环境构建,包含 Gulp 许可证头 +npm run build:analyze # 使用 webpack bundle analyzer 构建 +npm test # 运行 React 测试套件(CRACO) -npm run lint:check # Check ESLint rules (exits 0) -npm run lint:fix # Auto-fix ESLint issues -npm run clean # Remove node_modules and package-lock.json -npm run reinstall # Clean install (runs clean + install) +npm run lint:check # 检查 ESLint 规则(退出码 0) +npm run lint:fix # 自动修复 ESLint 问题 +npm run clean # 删除 node_modules 和 package-lock.json +npm run reinstall # 清洁安装(运行 clean + install) ``` -### Backend Development +### 后端开发 ```bash -python app.py # Main Flask server -python simulation_background_processor.py # Background task processor for trading simulations -pip install -r requirements.txt # Install Python dependencies +python app.py # 主 Flask 服务器 +python simulation_background_processor.py # 交易模拟的后台任务处理器 +pip install -r requirements.txt # 安装 Python 依赖 ``` -### Deployment +### 部署 ```bash -npm run deploy # Deploy from local (scripts/deploy-from-local.sh) -npm run rollback # Rollback to previous version +npm run deploy # 从本地部署(scripts/deploy-from-local.sh) +npm run rollback # 回滚到上一个版本 ``` -## Architecture +## 架构 -### Application Entry Flow +### 应用入口流程 ``` src/index.js -└── src/App.js (root component) +└── src/App.js(根组件) ├── AppProviders (src/providers/AppProviders.js) - │ ├── ReduxProvider (store from src/store/) - │ ├── ChakraProvider (theme from src/theme/) + │ ├── ReduxProvider(store 来自 src/store/) + │ ├── ChakraProvider(主题来自 src/theme/) │ ├── NotificationProvider (src/contexts/NotificationContext.js) │ └── AuthProvider (src/contexts/AuthContext.js) ├── AppRoutes (src/routes/index.js) - │ ├── MainLayout routes (with navbar/footer) - │ └── Standalone routes (auth pages, fullscreen views) - └── GlobalComponents (modal overlays, global UI) + │ ├── MainLayout 路由(带导航栏/页脚) + │ └── 独立路由(认证页面、全屏视图) + └── GlobalComponents(模态框覆盖层、全局 UI) ``` -### Routing Architecture (Modular Design) -Routing is **declarative** and split across multiple files in `src/routes/`: +### 路由架构(模块化设计) +路由采用**声明式**设计,并拆分到 `src/routes/` 中的多个文件: -- **index.js** - Main router (combines config + renders routes) -- **routeConfig.js** - Route definitions (path, component, protection, layout, children) -- **lazy-components.js** - React.lazy() imports for code splitting -- **homeRoutes.js** - Nested home page routes -- **constants/** - Protection modes, layout mappings -- **utils/** - Route rendering logic (wrapWithProtection, renderRoute) +- **index.js** - 主路由器(组合配置 + 渲染路由) +- **routeConfig.js** - 路由定义(路径、组件、保护模式、布局、子路由) +- **lazy-components.js** - React.lazy() 导入,用于代码分割 +- **homeRoutes.js** - 嵌套的首页路由 +- **constants/** - 保护模式、布局映射 +- **utils/** - 路由渲染逻辑(wrapWithProtection、renderRoute) -Route protection modes (PROTECTION_MODES): -- `PUBLIC` - No authentication required -- `MODAL` - Shows auth modal if not logged in -- `REDIRECT` - Redirects to /auth/sign-in if not logged in +路由保护模式(PROTECTION_MODES): +- `PUBLIC` - 无需认证 +- `MODAL` - 未登录时显示认证模态框 +- `REDIRECT` - 未登录时重定向到 /auth/sign-in -### Frontend Directory Structure +### 前端目录结构 ``` src/ -├── App.js - Root component (providers + routing) -├── providers/ - Provider composition (AppProviders.js) -├── routes/ - Modular routing system (see above) -├── layouts/ - Page layouts (MainLayout, Auth) -├── views/ - Page components (Community, TradingSimulation, etc.) -├── components/ - Reusable UI components -├── contexts/ - React contexts (Auth, Notification, Sidebar) -├── store/ - Redux store + slices (auth, posthog, stock, industry, etc.) -├── services/ - API layer (axios wrappers) -├── utils/ - Utility functions (apiConfig, priceFormatters, logger) -├── constants/ - App constants (animations, etc.) -├── hooks/ - Custom React hooks -├── theme/ - Chakra UI theme customization -└── mocks/ - MSW handlers for development - ├── handlers/ - Request handlers by domain (auth, stock, company, etc.) - ├── data/ - Mock data files - └── browser.js - MSW setup (starts when REACT_APP_ENABLE_MOCK=true) +├── App.js - 根组件(providers + 路由) +├── providers/ - Provider 组合(AppProviders.js) +├── routes/ - 模块化路由系统(见上文) +├── layouts/ - 页面布局(MainLayout、Auth) +├── views/ - 页面组件(Community、TradingSimulation 等) +├── components/ - 可复用 UI 组件 +├── contexts/ - React contexts(Auth、Notification、Sidebar) +├── store/ - Redux store + slices(auth、posthog、stock、industry 等) +├── services/ - API 层(axios 封装) +├── utils/ - 工具函数(apiConfig、priceFormatters、logger) +├── constants/ - 应用常量(animations 等) +├── hooks/ - 自定义 React hooks +├── theme/ - Chakra UI 主题定制 +└── mocks/ - 开发用 MSW handlers + ├── handlers/ - 按领域划分的请求处理器(auth、stock、company 等) + ├── data/ - Mock 数据文件 + └── browser.js - MSW 设置(当 REACT_APP_ENABLE_MOCK=true 时启动) ``` -### Backend Structure +### 后端结构 ``` -app.py - Flask server (routes, auth, business logic) -simulation_background_processor.py - Celery worker for trading simulations -concept_api.py - Concept/industry analysis API -wechat_pay.py / wechat_pay_config.py - WeChat payment integration -tdays.csv - Trading days calendar (loaded at startup) -requirements.txt - Python dependencies +app.py - Flask 服务器(路由、认证、业务逻辑) +simulation_background_processor.py - 交易模拟的 Celery worker +concept_api.py - 概念/行业分析 API +wechat_pay.py / wechat_pay_config.py - 微信支付集成 +tdays.csv - 交易日历(启动时加载) +requirements.txt - Python 依赖 ``` -### State Management Strategy -- **Redux Toolkit**: Global state (auth modal, posthog, stock data, industry data, subscriptions, community data) -- **React Context**: Cross-cutting concerns (AuthContext, NotificationContext, SidebarContext) -- **Component State**: Local UI state (forms, toggles, etc.) +### 状态管理策略 +- **Redux Toolkit**: 全局状态(认证模态框、posthog、股票数据、行业数据、订阅、社区数据) +- **React Context**: 跨切面关注点(AuthContext、NotificationContext、SidebarContext) +- **组件状态**: 本地 UI 状态(表单、开关等) -### Real-time Updates -- Flask-SocketIO for WebSocket connections -- Example: Community event notifications push via WebSocket -- Client: `socket.io-client` library +### 实时更新 +- Flask-SocketIO 用于 WebSocket 连接 +- 示例:社区事件通知通过 WebSocket 推送 +- 客户端:`socket.io-client` 库 -## Configuration +## 配置 -### Environment Files +### 环境文件 ``` -.env.mock - Mock mode (default): MSW intercepts all API calls, no backend needed -.env.development - Dev mode: Connects to dev backend -.env.test - Test mode: Used by 'npm run start:test' (backend + frontend together) -.env.production - Production build config +.env.mock - Mock 模式(默认):MSW 拦截所有 API 调用,无需后端 +.env.development - 开发模式:连接到开发后端 +.env.test - 测试模式:用于 'npm run start:test'(后端 + 前端一起) +.env.production - 生产环境构建配置 ``` -**Key environment variables:** -- `REACT_APP_ENABLE_MOCK=true` - Enable MSW mocking -- `REACT_APP_API_URL` - Backend URL (empty string = use relative paths or MSW) +**关键环境变量:** +- `REACT_APP_ENABLE_MOCK=true` - 启用 MSW mocking +- `REACT_APP_API_URL` - 后端 URL(空字符串 = 使用相对路径或 MSW) -### MSW (Mock Service Worker) Setup -MSW is used for API mocking during development: +### MSW (Mock Service Worker) 设置 +MSW 用于开发期间的 API mocking: -1. **Activation**: Set `REACT_APP_ENABLE_MOCK=true` in env file -2. **Worker file**: `public/mockServiceWorker.js` (auto-generated) -3. **Handlers**: `src/mocks/handlers/` (organized by domain: auth, stock, company, etc.) -4. **Mode**: `onUnhandledRequest: 'warn'` - unhandled requests pass through to backend +1. **激活方式**:在 env 文件中设置 `REACT_APP_ENABLE_MOCK=true` +2. **Worker 文件**:`public/mockServiceWorker.js`(自动生成) +3. **Handlers**:`src/mocks/handlers/`(按领域组织:auth、stock、company 等) +4. **模式**:`onUnhandledRequest: 'warn'` - 未处理的请求会传递到后端 -When MSW is active, the dev server proxy is disabled (MSW intercepts first). +当 MSW 激活时,开发服务器代理被禁用(MSW 优先拦截)。 -### Path Aliases (craco.config.js) -All aliases resolve to `src/` subdirectories: +### 路径别名 (craco.config.js) +所有别名解析到 `src/` 子目录: ``` @/ → src/ -@components/ → src/components/ -@views/ → src/views/ @assets/ → src/assets/ +@components/ → src/components/ +@constants/ → src/constants/ @contexts/ → src/contexts/ +@data/ → src/data/ +@hooks/ → src/hooks/ @layouts/ → src/layouts/ +@lib/ → src/lib/ +@mocks/ → src/mocks/ +@providers/ → src/providers/ +@routes/ → src/routes/ @services/ → src/services/ @store/ → src/store/ -@utils/ → src/utils/ -@hooks/ → src/hooks/ +@styles/ → src/styles/ @theme/ → src/theme/ -@mocks/ → src/mocks/ -@constants/ → src/constants/ +@utils/ → src/utils/ +@variables/ → src/variables/ +@views/ → src/views/ ``` -### Webpack Optimizations (craco.config.js) -**Performance features:** -- Filesystem cache (50-80% rebuild speedup) -- Aggressive code splitting by library: - - `react-vendor` - React core (priority 30) - - `charts-lib` - echarts, d3, apexcharts, recharts (priority 25) - - `chakra-ui` - Chakra UI + Emotion (priority 23) - - `antd-lib` - Ant Design (priority 22) - - `three-lib` - Three.js (priority 20) - - `calendar-lib` - moment, date-fns, FullCalendar (priority 18) -- ESLint plugin removed from build (20-30% speedup) -- Babel caching enabled -- moment locale stripping (IgnorePlugin) -- Source maps: disabled in production, `eval-cheap-module-source-map` in dev +### Webpack 优化 (craco.config.js) +**性能特性:** +- 文件系统缓存(重新构建速度提升 50-80%) +- 按库激进的代码分割: + - `react-vendor` - React 核心(优先级 30) + - `charts-lib` - echarts、d3、apexcharts、recharts(优先级 25) + - `chakra-ui` - Chakra UI + Emotion(优先级 23) + - `antd-lib` - Ant Design(优先级 22) + - `three-lib` - Three.js(优先级 20) + - `calendar-lib` - moment、date-fns、FullCalendar(优先级 18) +- 从构建中移除 ESLint 插件(速度提升 20-30%) +- 启用 Babel 缓存 +- moment locale 剥离(IgnorePlugin) +- Source maps:生产环境禁用,开发环境使用 `eval-cheap-module-source-map` -**Dev server:** -- Port 3000 (kills existing process on prestart) -- Proxy (when MSW disabled): `/api` → `http://49.232.185.254:5001` -- Bundle analyzer: `ANALYZE=true npm run build:analyze` +**开发服务器:** +- 端口 3000(prestart 时杀死现有进程) +- 代理(当 MSW 禁用时):`/api` → `http://49.232.185.254:5001` +- Bundle 分析器:`ANALYZE=true npm run build:analyze` -### Build Process -1. `npm run build` compiles with CRACO + webpack optimizations -2. Gulp task (`gulp licenses`) adds Creative Tim license headers to JS/HTML -3. Output: `build/` directory +### 构建流程 +1. `npm run build` 使用 CRACO + webpack 优化编译 +2. Gulp 任务(`gulp licenses`)为 JS/HTML 添加 Creative Tim 许可证头 +3. 输出:`build/` 目录 -**Node compatibility:** +**Node 兼容性:** ```bash NODE_OPTIONS='--openssl-legacy-provider --max_old_space_size=4096' ``` -## Development Workflow +## 开发工作流 -### Working with Routes -To add a new route: +### 路由开发 +添加新路由的步骤: -1. Add lazy import in `src/routes/lazy-components.js` -2. Add route config in `src/routes/routeConfig.js` with: - - `path` - URL path - - `component` - From lazyComponents +1. 在 `src/routes/lazy-components.js` 中添加 lazy import +2. 在 `src/routes/routeConfig.js` 中添加路由配置: + - `path` - URL 路径 + - `component` - 来自 lazyComponents - `protection` - MODAL/REDIRECT/PUBLIC - - `layout` - 'main' (with nav) or 'none' (fullscreen) -3. Routes automatically render with Suspense + ErrorBoundary (handled by PageTransitionWrapper) + - `layout` - 'main'(带导航栏)或 'none'(全屏) +3. 路由自动使用 Suspense + ErrorBoundary 渲染(由 PageTransitionWrapper 处理) -### Component Organization Patterns -Based on recent refactoring (see README.md for details): +### 组件组织模式 +基于最近的重构(详见 README.md): -**Atomic Design Pattern:** -- **Atoms** - Basic UI elements (buttons, badges, inputs) -- **Molecules** - Combinations of atoms (cards, forms) -- **Organisms** - Complex components (lists, panels) +**原子设计模式:** +- **Atoms(原子)** - 基础 UI 元素(按钮、徽章、输入框) +- **Molecules(分子)** - 原子的组合(卡片、表单) +- **Organisms(有机体)** - 复杂组件(列表、面板) -**Example structure for large components (1000+ lines):** +**大型组件示例结构(1000+ 行):** ``` src/views/Community/components/ ├── EventCard/ -│ ├── index.js - Smart wrapper (routes compact vs detailed) -│ ├── CompactEventCard.js - Compact view -│ ├── DetailedEventCard.js - Detailed view -│ ├── EventTimeline.js - Atomic component -│ ├── EventImportanceBadge.js - Atomic component +│ ├── index.js - 智能包装器(路由紧凑 vs 详细视图) +│ ├── CompactEventCard.js - 紧凑视图 +│ ├── DetailedEventCard.js - 详细视图 +│ ├── EventTimeline.js - 原子组件 +│ ├── EventImportanceBadge.js - 原子组件 │ └── ... ``` -**Utility extraction:** -- Extract reusable logic to `src/utils/` (e.g., `priceFormatters.js`) -- Extract shared constants to `src/constants/` (e.g., `animations.js`) +**工具提取:** +- 将可复用逻辑提取到 `src/utils/`(如 `priceFormatters.js`) +- 将共享常量提取到 `src/constants/`(如 `animations.js`) -### API Integration -**Service layer** (`src/services/`): -- Use `getApiBase()` from `src/utils/apiConfig.js` for base URL -- Example: `${getApiBase()}/api/endpoint` -- In mock mode, MSW intercepts; in dev/prod, hits backend +### API 集成 +**服务层**(`src/services/`): +- 使用 `src/utils/apiConfig.js` 中的 `getApiBase()` 获取基础 URL +- 示例:`${getApiBase()}/api/endpoint` +- 在 mock 模式下,MSW 拦截;在开发/生产环境下,请求后端 -**Adding new API endpoints:** -1. Add service function in `src/services/` (or inline in component) -2. If using MSW: Add handler in `src/mocks/handlers/{domain}.js` -3. Import handler in `src/mocks/handlers/index.js` +**添加新的 API 端点:** +1. 在 `src/services/` 中添加服务函数(或在组件中内联) +2. 如果使用 MSW:在 `src/mocks/handlers/{domain}.js` 中添加 handler +3. 在 `src/mocks/handlers/index.js` 中导入 handler -### Redux State Management -**Existing slices** (`src/store/slices/`): -- `authModalSlice` - Auth modal state -- `posthogSlice` - PostHog analytics -- `stockSlice` - Stock data -- `industrySlice` - Industry/concept data -- `subscriptionSlice` - User subscriptions -- `communityDataSlice` - Community content +### Redux 状态管理 +**现有 slices**(`src/store/slices/`): +- `authModalSlice` - 认证模态框状态 +- `posthogSlice` - PostHog 分析 +- `stockSlice` - 股票数据 +- `industrySlice` - 行业/概念数据 +- `subscriptionSlice` - 用户订阅 +- `communityDataSlice` - 社区内容 -**Adding new slice:** -1. Create `src/store/slices/yourSlice.js` -2. Import and add to `src/store/index.js` -3. Access via `useSelector`, dispatch via `useDispatch` +**添加新 slice:** +1. 创建 `src/store/slices/yourSlice.js` +2. 在 `src/store/index.js` 中导入并添加 +3. 通过 `useSelector` 访问,通过 `useDispatch` 派发 -## Backend Architecture +## 后端架构 -### Flask Application (app.py) -- **Authentication**: Flask-Login + session management -- **Database**: SQLAlchemy models + ClickHouse client -- **Background jobs**: Celery tasks for async processing -- **Real-time**: Flask-SocketIO for WebSocket events -- **Trading days**: `tdays.csv` loaded into memory at startup (global `trading_days` variable) +### Flask 应用 (app.py) +- **认证**: Flask-Login + session 管理 +- **数据库**: SQLAlchemy 模型 + ClickHouse 客户端 +- **后台任务**: Celery 任务用于异步处理 +- **实时通信**: Flask-SocketIO 用于 WebSocket 事件 +- **交易日**: `tdays.csv` 在启动时加载到内存(全局 `trading_days` 变量) -### Key Backend Patterns -- **ClickHouse**: Used for high-volume analytics queries (stock data, time series) -- **MySQL/PostgreSQL**: Used for transactional data (users, orders, subscriptions) -- **Celery**: Background processor runs in separate process (`simulation_background_processor.py`) -- **CORS**: Enabled for frontend communication +### 后端关键模式 +- **ClickHouse**: 用于高容量分析查询(股票数据、时间序列) +- **MySQL/PostgreSQL**: 用于事务性数据(用户、订单、订阅) +- **Celery**: 后台处理器在单独进程中运行(`simulation_background_processor.py`) +- **CORS**: 已启用,用于前端通信 -### API Proxy Configuration -When not in mock mode, frontend proxies to backend: -- `/api` → `http://49.232.185.254:5001` (main API) -- `/concept-api` → `http://49.232.185.254:6801` (concept analysis API) +### API 代理配置 +非 mock 模式时,前端代理到后端: +- `/api` → `http://49.232.185.254:5001`(主 API) +- `/concept-api` → `http://49.232.185.254:6801`(概念分析 API) -## Important Notes +## 重要说明 -### Code Splitting Strategy -Heavy pages are lazy-loaded to reduce initial bundle size: -- Community, TradingSimulation, Company pages use `React.lazy()` -- Webpack splits large libraries into separate chunks -- Check bundle size with `npm run build:analyze` +### 代码分割策略 +重量级页面进行懒加载以减小初始 bundle 大小: +- Community、TradingSimulation、Company 页面使用 `React.lazy()` +- Webpack 将大型库拆分为独立 chunks +- 使用 `npm run build:analyze` 检查 bundle 大小 -### Error Boundaries -- **Layout-level**: Each layout (MainLayout, Auth) has its own ErrorBoundary -- **Page-level**: PageTransitionWrapper wraps each route with ErrorBoundary -- **Strategy**: Errors are isolated to prevent entire app crashes +### 错误边界 +- **布局级**:每个布局(MainLayout、Auth)都有自己的 ErrorBoundary +- **页面级**:PageTransitionWrapper 为每个路由包裹 ErrorBoundary +- **策略**:错误被隔离,防止整个应用崩溃 -### PostHog Analytics -- Initialized in Redux (`posthogSlice`) -- Configured during app startup in `App.js` -- Used for user behavior tracking +### PostHog 分析 +- 在 Redux 中初始化(`posthogSlice`) +- 在 `App.js` 中应用启动时配置 +- 用于用户行为追踪 -### Performance Considerations -- **Large components**: If component exceeds ~500 lines, consider refactoring (see README.md) -- **Re-renders**: Use `React.memo`, `useMemo`, `useCallback` for expensive operations -- **Bundle size**: Monitor with webpack-bundle-analyzer -- **Caching**: Webpack filesystem cache speeds up rebuilds significantly \ No newline at end of file +### 性能考虑 +- **大型组件**:如果组件超过 ~500 行,考虑重构(见 README.md) +- **重渲染**:对昂贵操作使用 `React.memo`、`useMemo`、`useCallback` +- **Bundle 大小**:使用 webpack-bundle-analyzer 监控 +- **缓存**:Webpack 文件系统缓存显著加速重新构建 + +--- + +## 技术路径与开发指南 + +本章节定义了项目的技术方向、架构原则和开发标准。所有开发工作都应遵循这些指南。 + +### 技术栈决策与演进路线 + +#### 当前技术选型及理由 + +**前端框架栈:** +- **React 18.3.1**: 成熟的生态系统、并发渲染特性、广泛的社区支持 +- **Chakra UI 2.8.2**: 主UI库,优先考虑可访问性、主题定制能力强、基于 Emotion 的样式系统 +- **Ant Design**: 辅助UI库,用于复杂的数据密集型组件(表格、表单),弥补 Chakra UI 的不足 +- **Redux Toolkit**: 可预测的全局状态管理、优秀的 DevTools 集成、完善的 TypeScript 支持 + +**构建与开发工具:** +- **CRACO**: 允许在不 eject 的情况下自定义 webpack 配置 +- **MSW (Mock Service Worker)**: 在网络层进行 API mock,提供更真实的开发体验,加快开发迭代 +- **Webpack 5**: 利用文件系统缓存,重新构建速度提升 50-80% + +**图表库(多库策略):** +- **ApexCharts**: 主要用于金融/交易图表(K线图、折线图) +- **ECharts**: 用于复杂的交互式可视化和大数据集渲染 +- **Recharts**: 轻量级选项,用于仪表板中的简单图表 +- **D3.js**: 底层控制,用于自定义可视化 +- **选型理由**: 不同图表类型有不同的最优库,多库策略提供灵活性 + +**后端技术栈:** +- **Flask + SQLAlchemy**: Python 生态系统与金融/数据科学工作流契合度高 +- **ClickHouse**: 针对时序分析查询优化(股票数据、交易指标) +- **MySQL/PostgreSQL**: 传统关系型数据库,用于事务性数据,提供 ACID 保证 +- **Celery + Redis**: 处理长时间运行的后台任务(交易模拟、报表生成) + +#### 计划中的技术演进 + +**短期(未来 3-6 个月):** +- **React Query / TanStack Query**: 逐步从 Redux 迁移到 React Query 管理服务端状态 + - 优势: 自动缓存、后台自动刷新、乐观更新 + - 策略: 从新功能开始,然后迁移现有 API 调用 + - Redux 将继续用于客户端状态(UI 状态、模态框等) + +- **Vite 迁移**: 考虑从 CRACO/webpack 迁移到 Vite,提升开发体验 + - 优势: HMR 速度提升 10-50 倍,配置更简单 + - 风险: 可能需要大量重构构建配置 + - 决策节点: React Query 迁移稳定后 + +**中期(6-12 个月):** +- **React 19**: 生态系统稳定后升级 + - 关注点: Chakra UI 和 Ant Design 的兼容性 + - 新特性利用: Server Components(如适用)、改进的 Suspense + +- **TypeScript 迁移**: 逐步为关键路径添加 TypeScript + - 优先级: API 服务层 → Redux slices → 共享组件 → 视图组件 + - 新文件使用 `.ts`/`.tsx`,遗留代码保持 `.js`/`.jsx`(渐进式迁移) + +**长期(12+ 个月):** +- **Monorepo 结构**: 如果项目规模扩大,考虑 Nx 或 Turborepo +- **微前端架构**: 如果团队规模扩大,考虑模块联邦(Module Federation) + +#### 废弃/避免使用的技术 + +- **Moment.js**: 正在逐步淘汰,改用 `date-fns` 或原生 `Intl.DateTimeFormat` + - 当前已配置 webpack `IgnorePlugin` 以移除 locale 文件 + - 新的日期处理代码请使用 `date-fns` + +- **jQuery**: 新代码中禁止使用(与 React 虚拟 DOM 冲突) + +- **Class 组件**: 所有新组件必须使用函数式组件 + Hooks + +### 架构设计原则 + +#### 1. 组件设计原则 + +**原子设计层级:** +``` +原子组件 (Atoms, 1-50 行) + ↓ 组合成 +分子组件 (Molecules, 50-150 行) + ↓ 组合成 +有机体组件 (Organisms, 150-500 行) + ↓ 组合成 +模板/视图 (Templates/Views, 500+ 行,但主要是组合) +``` + +**单一职责原则:** +- 每个组件应该只做一件事,并做好 +- 如果组件超过 500 行,很可能做了太多事情 → 需要重构 +- 将逻辑提取到自定义 hooks、工具函数或子组件中 + +**组合优于配置:** +```jsx +// 推荐: 可组合 + + 标题 + 内容 + + +// 避免: 过多的 props + +``` + +**就近原则(Co-location):** +``` +ComponentName/ +├── index.js - 主导出文件 +├── ComponentName.js - 实现代码 +├── ComponentName.test.js - 测试 +├── hooks/ - 组件专用 hooks +│ └── useComponentLogic.js +├── utils.js - 组件专用工具函数 +└── constants.js - 组件专用常量 +``` + +#### 2. 状态管理决策树 + +使用此决策树确定状态应该存储在哪里: + +``` +是否是服务端数据(来自 API)? +├─ 是 → 使用 React Query(或暂时使用 Redux,后续迁移) +│ +└─ 否 → 是否需要在多个不相关的组件间共享? + ├─ 是 → 是否是 UI 状态(模态框、侧边栏开关等)? + │ ├─ 是 → Redux (authModalSlice, sidebarSlice 等) + │ └─ 否 → React Context (AuthContext, NotificationContext) + │ + └─ 否 → 是否需要在父组件和多个子组件间共享? + ├─ 是 → 状态提升到共同父组件,通过 props 传递 + └─ 否 → 本地组件状态 (useState, useReducer) +``` + +**状态管理规则:** +- **Redux**: 全局 UI 状态、跨切面关注点、需要在路由切换间保持的状态 +- **Context**: 依赖注入(主题、认证)、避免属性透传,适合稳定值 +- **组件状态**: 表单输入、开关、本地 UI 状态(下拉菜单、标签页) +- **React Query**(未来): 所有服务端状态、API 缓存、数据变更 + +**性能规则:** +- 如果 Context 值频繁变化,拆分为多个 Context 或使用 Redux +- 在 Context 边界使用 `React.memo` 防止不必要的重渲染 + +#### 3. 代码分割策略 + +**路由级分割(主要策略):** +- 所有主要视图在 `src/routes/lazy-components.js` 中使用 `React.lazy()` +- 重量级页面(Community、TradingSimulation、Company)始终懒加载 +- 认证页面可以懒加载(不在关键路径上) + +**库级分割(webpack):** +- 已在 `craco.config.js` 中配置 +- 大型库独立打包:charts、Three.js、Chakra、Ant Design +- 关键规则: 保持初始 bundle < 500KB gzipped + +**组件级分割(选择性使用):** +- 仅用于真正重量级且条件渲染的组件(如 3D 可视化) +```jsx +const HeavyChart = lazy(() => import('./HeavyChart')); +// 仅在需要时渲染 +{showChart && }>} +``` + +#### 4. API 层设计模式 + +**服务层架构:** +``` +组件 (Component) + ↓ 调用 +自定义 Hook (useStockData) + ↓ 使用 +服务函数 (src/services/stockService.js) + ↓ 调用 +Axios 实例(配置了 baseURL、拦截器) + ↓ 请求 +后端 API 或 MSW Mock +``` + +**API 服务模板:** +```javascript +// src/services/exampleService.js +import axios from 'axios'; +import { getApiBase } from '@utils/apiConfig'; + +const api = axios.create({ + baseURL: getApiBase(), + timeout: 10000, +}); + +// 请求拦截器(添加认证 token) +api.interceptors.request.use(config => { + const token = localStorage.getItem('token'); + if (token) config.headers.Authorization = `Bearer ${token}`; + return config; +}); + +// 响应拦截器(全局错误处理) +api.interceptors.response.use( + response => response.data, + error => { + // 全局错误处理 + console.error('API Error:', error); + return Promise.reject(error); + } +); + +export const fetchExample = async (id) => { + return api.get(`/api/example/${id}`); +}; +``` + +**MSW Mock Handler 模板:** +```javascript +// src/mocks/handlers/example.js +import { http, HttpResponse } from 'msw'; + +export const exampleHandlers = [ + http.get('/api/example/:id', ({ params }) => { + return HttpResponse.json({ + id: params.id, + data: 'mock data', + }); + }), +]; +``` + +#### 5. 错误处理架构 + +**三层错误边界策略:** +``` +App.js(根组件) + ↓ 捕获致命错误(显示降级 UI,记录到监控服务) +布局 (MainLayout, AuthLayout) + ↓ 捕获布局特定错误(显示错误页面,允许重试) +页面(通过 PageTransitionWrapper 包裹的各个路由) + ↓ 捕获页面特定错误(显示错误消息,允许导航) +``` + +**API 错误处理模式:** +```javascript +try { + const data = await fetchData(); + // 处理成功情况 +} catch (error) { + if (error.response?.status === 401) { + // 跳转到登录页 + } else if (error.response?.status === 403) { + // 显示权限错误 + } else { + // 显示通用错误 + showNotification('数据加载失败', 'error'); + } +} +``` + +### 开发规范与最佳实践 + +#### 1. 组件开发规范 + +**文件命名约定:** +- 组件: `PascalCase.js` (如 `EventCard.js`) +- 工具函数: `camelCase.js` (如 `priceFormatters.js`) +- 常量: `SCREAMING_SNAKE_CASE.js` 或 `camelCase.js` (如 `API_ENDPOINTS.js`, `animations.js`) +- Hooks: `useCamelCase.js` (如 `useStockData.js`) + +**组件文件结构:** +```javascript +// 1. 导入(分组并排序) +import React, { useState, useEffect } from 'react'; +import { Box, Text } from '@chakra-ui/react'; +import { useDispatch } from 'react-redux'; +import PropTypes from 'prop-types'; +import { CustomComponent } from '@components/CustomComponent'; +import { useCustomHook } from '@hooks/useCustomHook'; +import { helperFunction } from './utils'; + +// 2. 常量(组件专用) +const DEFAULT_VALUE = 10; + +// 3. 组件定义 +export const MyComponent = ({ prop1, prop2 }) => { + // 3a. Hooks(按类型分组) + const dispatch = useDispatch(); + const [state, setState] = useState(DEFAULT_VALUE); + const customValue = useCustomHook(); + + // 3b. 副作用 + useEffect(() => { + // 副作用逻辑 + }, []); + + // 3c. 事件处理器 + const handleClick = () => { + setState(prev => prev + 1); + }; + + // 3d. 渲染逻辑 + return ( + + {state} + + ); +}; + +// 4. PropTypes(或 TypeScript 类型) +MyComponent.propTypes = { + prop1: PropTypes.string.isRequired, + prop2: PropTypes.number, +}; + +// 5. 默认 Props +MyComponent.defaultProps = { + prop2: 0, +}; +``` + +**Props 设计指南:** +- 在组件参数中使用对象解构 +- 必需的 props 在前,可选的 props 在后 +- 布尔类型 props 使用 `is`、`has`、`should` 前缀(如 `isLoading`、`hasError`) +- 回调函数使用 `onEventName` 格式(如 `onClick`、`onSubmit`) +- 避免传递整个对象,只传递需要的几个属性 + +**性能优化检查清单:** +- [ ] 昂贵的计算是否用 `useMemo` 包裹? +- [ ] 传递给子组件的回调函数是否用 `useCallback` 包裹? +- [ ] 列表项是否使用唯一且稳定的 `key` props(不是数组索引)? +- [ ] 大型列表是否虚拟化(react-window 或 react-virtuoso)? +- [ ] 频繁接收 prop 更新的组件是否用 `React.memo` 包裹? +- [ ] 图片是否懒加载(`loading="lazy"`)? + +#### 2. Hooks 开发规范 + +**自定义 Hook 规则:** +- 必须以 `use` 前缀开头 +- 应该在多个组件间可复用 +- 应该处理一个特定关注点(数据获取、表单状态等) +- 应该返回对象或数组(不直接返回原始值) + +**自定义 Hook 模板:** +```javascript +// src/hooks/useStockData.js +import { useState, useEffect } from 'react'; +import { fetchStockData } from '@services/stockService'; + +export const useStockData = (stockId) => { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + if (!stockId) return; + + let isMounted = true; + setLoading(true); + + fetchStockData(stockId) + .then(result => { + if (isMounted) { + setData(result); + setError(null); + } + }) + .catch(err => { + if (isMounted) { + setError(err); + } + }) + .finally(() => { + if (isMounted) setLoading(false); + }); + + return () => { + isMounted = false; + }; + }, [stockId]); + + return { data, loading, error }; +}; +``` + +#### 3. Git 工作流与提交规范 + +**分支命名约定:** +``` +feature/简短描述 - 新功能 +fix/bug描述 - Bug 修复 +refactor/组件名称 - 代码重构 +docs/变更内容 - 文档更新 +chore/任务描述 - 维护任务 +``` + +**提交信息格式:** +``` +<类型>(<范围>): <主题> + +<正文> + +<脚注> +``` + +**类型:** +- `feat`: 新功能 +- `fix`: Bug 修复 +- `refactor`: 既不修复 Bug 也不添加功能的代码更改 +- `style`: 代码风格更改(格式化、缺少分号等) +- `docs`: 文档更改 +- `test`: 添加或更新测试 +- `chore`: 维护任务(依赖、构建配置等) + +**示例:** +``` +feat(community): 添加按日期范围筛选事件功能 + +实现了日期范围选择器用于筛选事件。 +添加了 Redux slice 用于筛选状态管理。 + +Closes #123 + +--- + +fix(trading): 修正模拟交易中的利润计算 + +修复了导致盈亏显示不正确的浮点精度问题。 + +--- + +refactor(components): 将 EventCard 拆分为原子组件 + +将 1200 行的 EventCard 拆分为: +- CompactEventCard +- DetailedEventCard +- EventTimeline (原子组件) +- EventImportanceBadge (原子组件) +``` + +**代码审查检查清单:** +- [ ] 代码是否遵循组件结构指南? +- [ ] 是否有超过 500 行应该拆分的组件? +- [ ] 状态管理是否合适(Redux vs Context vs Local)? +- [ ] 是否存在性能问题(不必要的重渲染、缺少记忆化)? +- [ ] 新功能是否有错误边界? +- [ ] 错误处理是否全面(API 错误、边界情况)? +- [ ] 新的 API 是否在 MSW 中 mock 以便开发? +- [ ] 是否定义了 PropTypes 或 TypeScript 类型? +- [ ] 代码是否具有可访问性(ARIA 标签、键盘导航)? +- [ ] 是否有 console 错误或警告? + +### 技术债务与已知问题 + +本节跟踪技术债务、性能问题和计划中的重构工作。发现或解决问题时请更新此列表。 + +#### 高优先级技术债务 + +**1. Redux 到 React Query 迁移** +- **状态**: 已计划 +- **影响**: 高 - 影响所有 API 调用 +- **时间线**: 2025 年 Q2 开始 +- **描述**: 将服务端状态从 Redux 迁移到 React Query,以获得更好的缓存、自动重新获取和减少样板代码 +- **受影响文件**: `src/store/slices/*Slice.js`、整个应用中的 API 服务调用 +- **迁移策略**: + 1. 在 `AppProviders.js` 中设置 React Query provider + 2. 创建 `src/queries/` 目录存放 query hooks + 3. 一次迁移一个领域(从 Community 或 Stock 数据开始) + 4. Redux 保留用于 UI 状态(模态框、侧边栏等) + +**2. 大型组件重构** +- **状态**: 进行中 +- **影响**: 中 - 可维护性和可读性 +- **需要重构的组件**: + - 任何超过 500 行的新组件 + - 审查 `src/views/` 中的组件,寻找潜在的拆分机会 +- **遵循模式**: 参见上面的"组件组织模式"章节 + +**3. TypeScript 渐进式迁移** +- **状态**: 已计划 +- **影响**: 高 - 类型安全、减少运行时错误 +- **时间线**: 2025 年 Q3 开始 +- **迁移顺序**: + 1. `src/utils/` (工具函数 - 最容易添加类型) + 2. `src/services/` (API 层 - 高价值) + 3. `src/store/` (Redux slices - 中等价值) + 4. `src/components/` (共享组件) + 5. `src/views/` (页面组件 - 最后) + +#### 中优先级技术债务 + +**4. Webpack 到 Vite 迁移** +- **状态**: 评估中 +- **影响**: 高 - 开发体验 +- **好处**: HMR 速度提升 10-50 倍,配置更简单 +- **风险**: 可能需要大量重构构建配置、CRACO 自定义配置 +- **决策节点**: React Query 迁移完成后 + +**5. Moment.js 替换** +- **状态**: 进行中(已配置移除 locale 文件) +- **影响**: 低 - bundle 大小减少(约 20KB) +- **策略**: 新代码中用 `date-fns` 替换 `moment()`,现有代码逐步迁移 +- **使用 moment.js 的文件**: 搜索 `import moment` 以识别 + +**6. 统一错误处理** +- **状态**: 需要改进 +- **影响**: 中 - 用户体验、调试 +- **问题**: + - 部分 API 调用缺少错误处理 + - 错误边界使用不一致 + - 某些地方的错误消息对用户不友好 +- **行动项**: + - 审计所有 API 调用的错误处理 + - 为所有主要视图添加错误边界 + - 标准化错误消息显示(NotificationContext) + +#### 低优先级技术债务 + +**7. 测试覆盖率** +- **状态**: 不足 +- **影响**: 中 - 变更信心 +- **当前覆盖率**: 未知(需要测量) +- **目标**: 关键路径 60%+ 覆盖率 +- **优先区域**: + 1. 工具函数(易于测试、高价值) + 2. Redux slices(状态管理逻辑) + 3. 自定义 hooks(可复用逻辑) + 4. 关键 UI 流程(认证、交易模拟) + +**8. Bundle 大小优化** +- **状态**: 持续监控中 +- **影响**: 低 - 加载时间 +- **当前大小**: 使用 `npm run build:analyze` 检查 +- **优化机会**: + - 移除未使用的依赖 + - Tree-shake 大型库(lodash → lodash-es) + - 考虑懒加载 Three.js 和其他重量级库 + +#### 已知问题与限制 + +**性能:** +- **Community 视图中的大型事件列表**: 如果列表超过 100 项,考虑虚拟化(react-window) +- **图表重渲染**: ApexCharts 在大数据集时可能较慢;考虑节流数据更新 + +**浏览器兼容性:** +- **不支持 IE11**: 现代 JavaScript 特性需要 polyfills 才能支持旧浏览器 +- **Safari 兼容性**: 某些 Chakra UI 动画在 Safari 中行为可能不同 + +**移动端响应式:** +- **交易模拟**: 复杂表格在移动端未完全优化 +- **图表**: 可能需要改进触摸事件处理 + +**数据/API:** +- **实时 WebSocket**: 连接断开时不总是能优雅处理;需添加重连逻辑 +- **ClickHouse 查询**: 大日期范围的某些分析查询可能较慢;考虑分页或聚合 + +--- + +## 更新本文档 + +本 CLAUDE.md 文件是一个持续更新的文档。在以下情况下应更新它: +- 添加新的架构模式或指南 +- 发现新的最佳实践 +- 解决或添加技术债务项 +- 做出重要的技术决策 + +所有开发人员应在入职时审查本文档,并在做出架构决策时参考它。 \ No newline at end of file