-
Notifications
You must be signed in to change notification settings - Fork 2.3k
refactor(ui): optimize config refresh with SWR auto-revalidation #924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
refactor(ui): optimize config refresh with SWR auto-revalidation #924
Conversation
Replace the inline header implementation in main app with HeaderBar component to match landing page: - Remove duplicate inline header code (168 lines) - Use HeaderBar component for all main app pages like landing page does - Ensure consistent header design across all routes (/competition, /traders, /dashboard) - Maintain proper onPageChange navigation handling - Keep all header functionality (user info, admin mode, language toggle, logout) This fixes the header inconsistency where different pages used different header implementations. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…cture Revert PR NoFxAiOS#229: Remove UT infrastructure
…app pages Match main app layout with proven working /competition route layout: - Use px-6 py-6 pt-24 padding (same as /competition route) - Ensures HeaderBar doesn't overlap content on /traders and /dashboard pages - Provides consistent 6rem (96px) top clearance for fixed positioned HeaderBar - Removes responsive padding variants that differed from competition page This fixes header overlap issues across all main application routes. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # api/server.go
Resolved conflicts in: - api/server.go: Preserved beta_mode config and user permission checks - manager/trader_manager.go: Kept optimized concurrent competition data with caching Maintained all performance optimizations while merging new features from dev. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…y-markers chore(web): add peer dependency markers to package-lock.json
Removed unused 'Zap' import from App.tsx that was causing build failure. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
fix: resolve go vet warnings for non-constant format strings
Removed App.test.tsx and AITradersPage.test.tsx that were causing TypeScript build issues and are not currently in use. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Removed test script from package.json - Removed testing dependencies (@testing-library/react, vitest, jsdom) - Deleted test directory and vitest.config.ts - Updated package-lock.json to reflect changes - Build still works perfectly without test dependencies 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Beta Merge dev、Bug fix
The chart was not showing data because the API response format changed. Fixed the calculation of PnL percentage by computing it from total_pnl and balance values (initial_balance = balance - total_pnl). Now the AI competition chart should properly display performance comparison data. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add NOFX watermark to ComparisonChart (competition page) - Add NOFX watermark to EquityChart (dashboard page) - Fix empty state handling and internationalization in CompetitionPage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Beta bugfix
Fix(workflow): add title and size validation comments
fix(readme): update readme and pr reviewer
…ssing-fields fix(database): GetTraderConfig missing critical fields causes edit to fail
Fix:fix the main branch history issue from November 3rd.
Merge pull request NoFxAiOS#395 from NoFxAiOS/beta fix:fix the main branch history issue from November 3rd.
Enable automatic wallet address generation from private key for Hyperliquid exchange, simplifying user onboarding and reducing configuration errors. Backend Changes (trader/hyperliquid_trader.go): - Import crypto/ecdsa package for ECDSA public key operations - Enable wallet address auto-generation when walletAddr is empty - Use crypto.PubkeyToAddress() to derive address from private key - Add logging for both auto-generated and manually provided addresses Frontend Changes (web/src/components/AITradersPage.tsx): - Remove wallet address required validation (only private key required) - Update button disabled state to only check private key - Add "Optional" label to wallet address field - Add dynamic placeholder with bilingual hint - Show context-aware helper text based on input state - Remove HTML required attribute from input field Translation Updates (web/src/i18n/translations.ts): - Add 'optional' translation (EN: "Optional", ZH: "可选") - Add 'hyperliquidWalletAddressAutoGenerate' translation EN: "Leave blank to automatically generate wallet address from private key" ZH: "留空将自动从私钥生成钱包地址" Benefits: ✅ Simplified UX - Users only need to provide private key ✅ Error prevention - Auto-generated address always matches private key ✅ Backward compatible - Manual address input still supported ✅ Better UX - Clear visual indicators for optional fields Technical Details: - Uses Ethereum standard ECDSA public key to address conversion - Implementation was already present but commented out (lines 37-43) - No database schema changes required (hyperliquid_wallet_addr already nullable) - Fallback behavior: manual input > auto-generation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## 🐛 问题描述 币安交易所配置页面中的服务器IP复制功能无法正常工作 ## 🔍 根因分析 原始实现仅使用 navigator.clipboard.writeText() API: - 在某些浏览器环境下不可用或被阻止 - 需要 HTTPS 或 localhost 环境 - 缺少错误处理和用户反馈 ## ✅ 修复方案 1. **双重降级机制**: - 优先使用现代 Clipboard API - 降级到传统 execCommand 方法 2. **错误处理**: - 添加 try-catch 错误捕获 - 失败时显示友好的错误提示 - 提供IP地址供用户手动复制 3. **多语言支持**: - 添加 copyIPFailed 翻译键(中英文) ## 📝 修改文件 - web/src/components/AITradersPage.tsx - handleCopyIP 函数重构为异步函数 - 添加双重复制机制和错误处理 - web/src/i18n/translations.ts - 添加 copyIPFailed 错误提示翻译 ## 🧪 测试验证 ✅ TypeScript 编译通过 ✅ Vite 构建成功 ✅ 支持现代和传统浏览器环境 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
* fix(decision): 添加槓桿超限 fallback 機制並澄清盈虧計算說明 1. AI 決策輸出超限槓桿時(如 20x),驗證直接拒絕導致整個交易週期失敗 2. Prompt 未明確說明盈虧百分比已包含槓桿效應,導致 AI 思維鏈中誤用價格變動% - **Before**: 超限直接報錯 → 決策失敗 - **After**: 自動降級為配置上限 → 決策繼續執行 - **效果**: SOLUSDT 20x → 自動修正為 5x(配置上限) - 明確告知 AI:系統提供的「盈虧%」已包含槓桿效應 - 公式: 盈虧% = (未實現盈虧 / 保證金) × 100 - 示例: 5x 槓桿,價格漲 2% = 實際盈利 10% - 測試山寨幣超限修正(20x → 5x) - 測試 BTC/ETH 超限修正(20x → 10x) - 測試正常範圍不修正 - 測試無效槓桿拒絕 ``` PASS: TestLeverageFallback/山寨币杠杆超限_自动修正为上限 PASS: TestLeverageFallback/BTC杠杆超限_自动修正为上限 PASS: TestLeverageFallback/杠杆在上限内_不修正 PASS: TestLeverageFallback/杠杆为0_应该报错 ``` - ✅ 向後兼容:正常槓桿範圍不受影響 - ✅ 容錯性增強:AI 輸出超限時系統自動修正 - ✅ 決策質量提升:AI 對槓桿收益有正確認知 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * style: apply go fmt after rebase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…xAiOS#796) * fix(trader): add mutex to prevent race condition in Meta refresh (issue NoFxAiOS#742) **問題**: 根據 issue NoFxAiOS#742 審查標準,發現 BLOCKING 級別的並發安全問題: - refreshMetaIfNeeded() 中的 `t.meta = meta` 缺少並發保護 - 多個 goroutine 同時調用 OpenLong/OpenShort 會造成競態條件 **修復**: 1. 添加 sync.RWMutex 保護 meta 字段 2. refreshMetaIfNeeded() 使用寫鎖保護 meta 更新 3. getSzDecimals() 使用讀鎖保護 meta 訪問 **符合標準**: - issue NoFxAiOS#742: "並發安全問題需使用 sync.Once 等機制" - 使用 RWMutex 實現讀寫分離,提升並發性能 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test(trader): add comprehensive race condition tests for meta field mutex protection - Test concurrent reads (100 goroutines accessing getSzDecimals) - Test concurrent read/write (50 readers + 10 writers simulating meta refresh) - Test nil meta edge case (returns default value 4) - Test valid meta with multiple coins (BTC, ETH, SOL) - Test massive concurrency (1000 iterations with race detector) All 5 test cases passed, including -race verification with no data races detected. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…FxAiOS#833) * feat: 启动交易员时自动重新加载系统提示词模板 ## 改动内容 - 在 handleStartTrader 中调用 decision.ReloadPromptTemplates() - 每次启动交易员时从硬盘重新加载 prompts/ 目录下的所有 .txt 模板文件 - 添加完整的单元测试和端到端集成测试 ## 测试覆盖 - 单元测试:模板加载、获取、重新加载功能 - 集成测试:文件修改 → 重新加载 → 决策引擎使用新内容的完整流程 - 并发测试:验证多 goroutine 场景下的线程安全性 - Race detector 测试通过 ## 用户体验改进 - 修改 prompt 文件后无需重启服务 - 只需停止交易员再启动即可应用新的 prompt - 控制台会输出重新加载成功的日志提示 * feat: 在重新加载日志中显示当前使用的模板名称 * feat: fallback 到 default 模板时明确显示原因 * fix: correct GetTraderConfig return type to get SystemPromptTemplate * refactor: extract reloadPromptTemplatesWithLog as reusable method
…ced Layout System, and Integrated React Router (NoFxAiOS#872)
優化添加 AI 模型/交易所後的刷新體驗,使用 SWR 自動重新驗證。
Changes:
**Frontend (web/src/components/AITradersPage.tsx):**
- 將 allModels 和 allExchanges 從 useState 改為 useSWR
- 保存後自動調用 mutate() 觸發重新請求
- 簡化 useEffect:移除手動加載邏輯,SWR 自動處理
Before:
```typescript
const [allModels, setAllModels] = useState<AIModel[]>([])
// useEffect 手動加載
// 保存後手動 setAllModels(refreshedModels)
```
After:
```typescript
const { data: allModels, mutate: mutateModels } = useSWR<AIModel[]>(
user && token ? 'models' : null,
api.getModelConfigs
)
// 保存後自動 mutateModels()
```
Benefits:
1. **自動刷新**:保存後立即更新 UI,無需手動刷新頁面
2. **代碼簡化**:減少 useState 和手動請求邏輯
3. **一致性**:與 traders 列表使用相同的 SWR 模式
4. **性能優化**:SWR 內建快取和去重機制
Technical Details:
- handleSaveModelConfig: await api.updateModelConfigs() → mutateModels()
- handleSaveExchangeConfig: await api.updateExchangeConfigsEncrypted() → mutateExchanges()
- handleDeleteModelConfig: setAllModels([...items]) → mutateModels()
- handleDeleteExchangeConfig: setAllExchanges([...items]) → mutateExchanges()
- 保留 supportedModels/supportedExchanges 為 useState(無需自動刷新)
User Experience:
- 添加/編輯模型後,列表立即更新顯示新配置
- 添加/編輯交易所後,列表立即更新顯示新配置
- 刪除配置後,列表立即移除
- 無需等待或手動刷新頁面
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
修復 TypeScript 類型錯誤:useSWR 返回的 data 可能是 undefined。
Issue:
- AITradersPage.tsx(1219,11): Type 'AIModel[] | undefined' is not assignable to type 'AIModel[]'
- useSWR 的 data 在加載時為 undefined
- ModelConfigModal 期待 AIModel[] 類型
Fix:
- configuredModels={allModels || []}
- 當 data 是 undefined 時,使用空陣列作為默認值
Result:
- TypeScript 編譯通過
- 運行時邏輯正確(加載中顯示空列表)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
| // 使用函数式更新确保状态正确更新 | ||
| setAllModels([...items]) | ||
| setItems: () => { | ||
| // 自动刷新模型列表 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this get models from backend service?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! 🎯
Yes, mutateModels() will fetch from backend service.
However, I found a redundancy issue you helped uncover:
Before (had bug):
const refreshedItems = await config.refreshApi() // 1st backend call
config.setItems(refreshedItems) // 2nd backend call (mutateModels ignores refreshedItems)After (fixed in d87fe51):
config.setItems() // Only 1 backend call via mutateModels()Changes:
- Removed redundant
refreshApiparameter - Now only calls backend once via SWR mutate
- More efficient and follows SWR best practices ✅
Thanks for the review! 🙏
移除删除配置时的冗余后端调用。 Issue (感谢 @hzb1115 发现): - handleDeleteConfig 先调用 refreshApi() 获取数据 - 然后调用 setItems(refreshedItems),但 setItems 实际是 mutateModels() - 导致获取的 refreshedItems 被忽略,mutateModels() 又调用一次后端 - 结果:删除时调用 2 次后端 API(冗余) Fix: - 移除 refreshApi 参数和调用 - 直接使用 setItems() 触发 SWR mutate - 更新 handleDeleteConfig 类型定义:setItems: () => void Before (冗余): ```typescript const refreshedItems = await config.refreshApi() // API 调用 1 config.setItems(refreshedItems) // API 调用 2 (mutateModels) ``` After (优化): ```typescript config.setItems() // 只调用 mutateModels() = API 调用 1 ``` Result: - ✅ 删除配置时只调用 1 次后端 API - ✅ 代码更简洁,符合 SWR 最佳实践 - ✅ 功能完全相同,性能更好 Addresses: - @hzb1115: "Will this get models from backend service?" Answer: Yes, mutateModels() will fetch from backend. Now only once (before was twice). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
同步 PR NoFxAiOS#924 的性能优化到 z-dev-v2 分支。 Changes: 1. 移除 handleDeleteConfig 的 refreshApi 参数 2. 更新 setItems 类型:(items: T[]) => void → () => void 3. 移除冗余的后端 API 调用 4. 添加 allModels || [] 默认值(TypeScript 类型安全) Before (冗余): ```typescript const refreshedItems = await config.refreshApi() // API 调用 1 config.setItems(refreshedItems) // API 调用 2 (mutateModels) ``` After (优化): ```typescript config.setItems() // 只调用 mutateModels() = API 调用 1 ``` Result: - ✅ 删除配置时只调用 1 次后端 API(减少 50%) - ✅ TypeScript 类型安全(无 undefined 错误) - ✅ 保留 z-dev-v2 的额外功能(策略显示、WebCrypto 检查) - ✅ 代码更简洁,符合 SWR 最佳实践 Synced from PR NoFxAiOS#924: - Commit d87fe51: refactor(ui): remove redundant API calls - Commit 4f3f289: fix(types): provide default empty array 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
@0xEmberZz Could you pls help review this? |
43aad91 to
5517269
Compare
02cb78a to
7bd5ca0
Compare
Summary
優化添加 AI 模型/交易所後的刷新體驗,使用 SWR 自動重新驗證。
Changes
Frontend (web/src/components/AITradersPage.tsx):
Before
After
Benefits
Technical Details
User Experience
Testing
🤖 Generated with Claude Code