Skip to content

Commit 87277e9

Browse files
authored
Merge pull request #1 from RoeKun/personal/RoeKun_web_edit
fix: update domain to pumpstrategy.io
2 parents e7c53e7 + 5aaa033 commit 87277e9

47 files changed

Lines changed: 6629 additions & 17669 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"issue_id": "FRONTEND-001",
3+
"title": "getBoundingClientRect Error on /traders Page (Vercel Production)",
4+
"status": "analyzed",
5+
"created_at": "2026-01-11",
6+
"environment": "Vercel Production (web-pink-omega-40.vercel.app)",
7+
8+
"error_details": {
9+
"message": "Uncaught TypeError: Cannot read properties of null (reading 'getBoundingClientRect')",
10+
"url": "https://web-pink-omega-40.vercel.app/traders",
11+
"type": "Window Error"
12+
},
13+
14+
"reproduction_path": {
15+
"steps": [
16+
"1. 访问 https://web-pink-omega-40.vercel.app/traders",
17+
"2. 等待页面加载完成",
18+
"3. 错误可能在以下场景触发:",
19+
" - 图表组件 (ComparisonChart/EquityChart) 渲染时",
20+
" - Tooltip 组件计算位置时",
21+
" - 页面快速切换导致组件未完全卸载"
22+
],
23+
"affected_components": [
24+
"ComparisonChart.tsx - 使用 Recharts ResponsiveContainer",
25+
"EquityChart.tsx - 使用 Recharts ResponsiveContainer",
26+
"AITradersPage.tsx - 主页面组件"
27+
]
28+
},
29+
30+
"root_cause_analysis": {
31+
"primary_cause": "Recharts 图表库在组件挂载/卸载时的竞态条件",
32+
"details": [
33+
"Recharts 的 ResponsiveContainer 组件内部使用 getBoundingClientRect 计算容器尺寸",
34+
"当组件在 DOM 完全挂载前或卸载过程中被访问时,ref 可能为 null",
35+
"生产环境的代码压缩和异步加载可能加剧这个问题"
36+
],
37+
"evidence": {
38+
"recharts_usage": [
39+
"ComparisonChart.tsx:253 - <ResponsiveContainer width=\"100%\" height={520}>",
40+
"EquityChart.tsx:290 - <ResponsiveContainer width='100%' height={280}>"
41+
],
42+
"no_direct_usage": "项目源码中未直接调用 getBoundingClientRect,确认来自第三方库"
43+
}
44+
},
45+
46+
"solution": {
47+
"status": "pending_implementation",
48+
"approach": "添加条件渲染和错误边界",
49+
"code_changes": [
50+
{
51+
"file": "web/src/components/ComparisonChart.tsx",
52+
"change": "在 ResponsiveContainer 外层添加 mounted 状态检查",
53+
"example": "const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); return () => setMounted(false); }, []); if (!mounted) return null;"
54+
},
55+
{
56+
"file": "web/src/components/EquityChart.tsx",
57+
"change": "同上,添加 mounted 状态检查"
58+
},
59+
{
60+
"file": "web/src/App.tsx",
61+
"change": "可选:添加 ErrorBoundary 组件包裹图表"
62+
}
63+
]
64+
},
65+
66+
"workaround": {
67+
"description": "本地开发环境无法复现,仅在 Vercel 生产环境出现",
68+
"temporary_fix": "刷新页面通常可以解决"
69+
},
70+
71+
"references": [
72+
"https://github.com/recharts/recharts/issues/1767",
73+
"https://github.com/recharts/recharts/issues/2830"
74+
]
75+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
name: pumpstrategy-migration
3+
overview: 将 Agent Trade 项目迁移到 pumpstrategy.io 域名,包括品牌替换、Logo 设计、域名配置更新,并输出前端技术文档。
4+
todos:
5+
- id: explore-brand-refs
6+
content: 使用 [subagent:code-explorer] 搜索项目中所有品牌相关引用
7+
status: completed
8+
- id: design-logo
9+
content: 设计 PumpStrategy 新 Logo(简约干练风格,体现 AI 交易策略)
10+
status: completed
11+
- id: replace-brand
12+
content: 执行品牌替换:名称、Logo、Favicon 等资源
13+
status: completed
14+
dependencies:
15+
- explore-brand-refs
16+
- design-logo
17+
- id: update-domain-config
18+
content: 更新域名配置:环境变量、API 端点、Vercel 配置
19+
status: completed
20+
dependencies:
21+
- explore-brand-refs
22+
- id: generate-tech-doc
23+
content: 输出前端技术文档:技术栈、部署、页面结构
24+
status: completed
25+
dependencies:
26+
- replace-brand
27+
- update-domain-config
28+
- id: create-migration-log
29+
content: 创建迁移记录文档:记录所有操作步骤和变更内容
30+
status: completed
31+
dependencies:
32+
- replace-brand
33+
- update-domain-config
34+
---
35+
36+
## 产品概述
37+
38+
将 Agent Trade 项目迁移到 pumpstrategy.io 域名,完成品牌重塑、Logo 设计、域名配置更新,并输出完整的前端技术文档。
39+
40+
## 核心功能
41+
42+
- 品牌替换:将所有 "Agent Trade" / "Monnaire" 相关品牌名称替换为 "PumpStrategy"
43+
- Logo 设计:设计简约干练的新 Logo,体现 AI 交易策略平台定位
44+
- 域名配置更新:将前端域名从 agentrade.xyz 迁移到 pumpstrategy.io
45+
- 技术文档输出:输出前端技术栈、部署服务器、页面结构等完整文档
46+
- 操作记录:记录所有替换操作并写入迁移文档
47+
48+
## 技术栈
49+
50+
- 前端框架:Vite + React + TypeScript
51+
- 样式方案:Tailwind CSS
52+
- 部署平台:前端 Vercel,后端 Replit
53+
- 当前后端域名:nofx-gyc567.replit.app
54+
55+
## 技术架构
56+
57+
### 系统架构
58+
59+
```mermaid
60+
flowchart TB
61+
subgraph Frontend["前端 (Vercel)"]
62+
A[React App] --> B[Vite Build]
63+
B --> C[Static Assets]
64+
end
65+
66+
subgraph Backend["后端 (Replit)"]
67+
D[API Server]
68+
end
69+
70+
subgraph Domain["域名配置"]
71+
E[pumpstrategy.io] --> Frontend
72+
F[nofx-gyc567.replit.app] --> Backend
73+
end
74+
75+
Frontend <--> Backend
76+
```
77+
78+
### 模块划分
79+
80+
- **品牌资源模块**:Logo、Favicon、品牌名称、品牌色彩
81+
- **配置模块**:环境变量、API 端点、域名配置
82+
- **页面模块**:各页面组件中的品牌引用
83+
- **文档模块**:技术文档、迁移记录
84+
85+
### 数据流
86+
87+
用户访问 pumpstrategy.io → Vercel 托管的静态资源 → React 应用加载 → API 请求到 Replit 后端
88+
89+
## 实施细节
90+
91+
### 核心目录结构(需修改的文件)
92+
93+
```
94+
agentrade/
95+
├── public/
96+
│ ├── Monnaire_Logo.svg # 需替换为新 Logo
97+
│ └── favicon.ico # 需更新 Favicon
98+
├── src/
99+
│ ├── assets/
100+
│ │ └── logo/ # Logo 资源目录
101+
│ ├── components/
102+
│ │ └── Header/ # 包含 Logo 引用的组件
103+
│ └── config/
104+
│ └── constants.ts # 品牌名称、域名常量
105+
├── index.html # 标题、meta 信息
106+
├── vercel.json # Vercel 部署配置
107+
├── .env # 环境变量
108+
└── docs/
109+
└── migration-log.md # 迁移记录文档(新建)
110+
```
111+
112+
### 关键代码结构
113+
114+
**品牌常量定义**:集中管理品牌相关常量,便于统一替换
115+
116+
```typescript
117+
// src/config/constants.ts
118+
export const BRAND = {
119+
name: 'PumpStrategy',
120+
domain: 'pumpstrategy.io',
121+
tagline: 'AI Trading Strategy Platform',
122+
logo: '/pumpstrategy-logo.svg'
123+
}
124+
```
125+
126+
**Logo 组件接口**:统一 Logo 组件调用方式
127+
128+
```typescript
129+
// Logo 组件 Props
130+
interface LogoProps {
131+
size?: 'sm' | 'md' | 'lg';
132+
variant?: 'full' | 'icon';
133+
className?: string;
134+
}
135+
```
136+
137+
### 技术实施计划
138+
139+
1. **品牌资源替换**
140+
141+
- 问题:需要替换所有品牌相关资源
142+
- 方案:使用全局搜索定位所有引用点,统一替换
143+
- 技术:grep/ripgrep 搜索,批量替换
144+
- 步骤:搜索 → 记录 → 替换 → 验证
145+
- 测试:本地运行验证所有页面显示正确
146+
147+
2. **Logo 设计与集成**
148+
149+
- 问题:需要设计符合 AI 交易策略平台定位的 Logo
150+
- 方案:设计简约干练的 SVG Logo
151+
- 技术:SVG 格式,支持多尺寸适配
152+
- 步骤:设计 → 导出 SVG → 集成到项目 → 更新引用
153+
- 测试:验证各页面 Logo 显示效果
154+
155+
3. **域名配置更新**
156+
157+
- 问题:需要更新所有域名引用
158+
- 方案:更新环境变量和配置文件
159+
- 技术:Vercel 域名绑定,环境变量配置
160+
- 步骤:更新配置 → 更新 Vercel 设置 → DNS 配置
161+
- 测试:验证域名解析和 HTTPS 证书
162+
163+
### 集成点
164+
165+
- Vercel 部署:更新域名绑定配置
166+
- DNS 配置:pumpstrategy.io 指向 Vercel
167+
- API 端点:确保后端 CORS 配置支持新域名
168+
169+
## Agent Extensions
170+
171+
### SubAgent
172+
173+
- **code-explorer**
174+
- 用途:全面搜索项目中所有品牌相关引用(Agent Trade、Monnaire、agentrade.xyz 等)
175+
- 预期结果:输出所有需要替换的文件列表和具体位置,确保无遗漏
176+
177+
### MCP
178+
179+
- **kuikly-mcp**
180+
- 用途:咨询 Logo 设计建议和 AI 交易策略平台的视觉风格方向
181+
- 预期结果:获取专业的设计建议,指导 Logo 设计方向

api/handlers/trader_fix_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ package handlers
33
import (
44
"bytes"
55
"encoding/json"
6-
"net/http"
6+
// "net/http" // Unused import removed
77
"net/http/httptest"
88
"testing"
99

10-
"github.com/stretchr/testify/assert"
10+
// "github.com/stretchr/testify/assert" // Unused import removed
1111
"github.com/stretchr/testify/require"
1212
)
1313

api/news_config_integration_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,16 @@ func SetupIntegrationTest(t *testing.T) *IntegrationTestHelper {
3030
mockRepo := NewMockNewsConfigRepository()
3131
handler := NewNewsConfigHandler(mockRepo)
3232

33-
// 注册路由
33+
// 手动注册路由(NewsConfigHandler 没有 RegisterRoutes 方法)
3434
apiGroup := router.Group("/api")
35-
handler.RegisterRoutes(apiGroup)
35+
userGroup := apiGroup.Group("/user")
36+
{
37+
userGroup.GET("/news-config", handler.GetUserNewsConfig)
38+
userGroup.POST("/news-config", handler.CreateOrUpdateUserNewsConfig)
39+
userGroup.PUT("/news-config", handler.UpdateUserNewsConfig)
40+
userGroup.DELETE("/news-config", handler.DeleteUserNewsConfig)
41+
userGroup.GET("/news-config/sources", handler.GetEnabledNewsSources)
42+
}
3643

3744
return &IntegrationTestHelper{
3845
router: router,

api/payment/handler_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package payment
22

33
import (
44
"bytes"
5+
"context"
56
"database/sql"
67
"encoding/json"
78
"net/http"
@@ -223,7 +224,7 @@ func TestGetOrder(t *testing.T) {
223224

224225
// 先创建一个订单
225226
service := payment.NewPaymentService(db)
226-
order, err := service.CreatePaymentOrder(router.(*gin.Context).Request.Context(), "user1", "pkg1")
227+
order, err := service.CreatePaymentOrder(context.Background(), "user1", "pkg1")
227228
require.NoError(t, err)
228229

229230
t.Run("Get Existing Order", func(t *testing.T) {
@@ -288,7 +289,7 @@ func TestGetUserOrders(t *testing.T) {
288289
// 创建多个订单
289290
service := payment.NewPaymentService(db)
290291
for i := 0; i < 3; i++ {
291-
_, err := service.CreatePaymentOrder(router.(*gin.Context).Request.Context(), "user1", "pkg1")
292+
_, err := service.CreatePaymentOrder(context.Background(), "user1", "pkg1")
292293
require.NoError(t, err)
293294
}
294295

@@ -356,7 +357,7 @@ func TestHandleWebhook(t *testing.T) {
356357

357358
// 创建测试订单
358359
service := payment.NewPaymentService(db)
359-
order, err := service.CreatePaymentOrder(router.(*gin.Context).Request.Context(), "user1", "pkg1")
360+
order, err := service.CreatePaymentOrder(context.Background(), "user1", "pkg1")
360361
require.NoError(t, err)
361362

362363
// 更新订单关联Crossmint ID

api/server.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,15 @@ func corsMiddleware() gin.HandlerFunc {
148148
"https://web-fco5upt1e-gyc567s-projects.vercel.app",
149149
"https://web-2ybunmaej-gyc567s-projects.vercel.app",
150150
"https://web-ge79k4nzy-gyc567s-projects.vercel.app",
151-
// 生产前端域名(含www和不含www)
152-
"https://www.agentrade.xyz",
153-
"https://agentrade.xyz",
154-
155-
// Replit部署域名
156-
"https://nofx-gyc567.replit.app",
151+
// 生产前端域名(含www和不含www)
152+
"https://www.agentrade.xyz",
153+
"https://agentrade.xyz",
154+
// PumpStrategy 新域名
155+
"https://pumpstrategy.io",
156+
"https://www.pumpstrategy.io",
157+
158+
// Replit部署域名
159+
"https://nofx-gyc567.replit.app",
157160
}
158161

159162
// 如果设置了环境变量,使用环境变量中的值

config/payment_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,7 @@ func setupPaymentTestDB(t *testing.T) *Database {
107107

108108
// 包装为Database对象
109109
database := &Database{
110-
neonDB: db,
111-
sqliteDB: db,
112-
currentDB: db,
113-
usingNeon: false,
110+
db: db,
114111
}
115112

116113
return database

database/user_news_config_repository_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package database
33
import (
44
"database/sql"
55
"testing"
6-
"time"
6+
// "time" // Unused import removed
77
)
88

99
func TestUserNewsConfigRepository_CreateAndGet(t *testing.T) {

logger/news_config_logger_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package logger
22

33
import (
4+
"fmt"
45
"os"
56
"testing"
67
"time"
@@ -70,8 +71,8 @@ func TestStructuredLogger_LogWithError(t *testing.T) {
7071
tmpDir := t.TempDir()
7172
logger, _ := NewStructuredLogger(tmpDir)
7273

73-
testError := "配置已存在"
74-
err := logger.LogCreate("test-user", nil, 10*time.Millisecond, &testError)
74+
testError := fmt.Errorf("配置已存在")
75+
err := logger.LogCreate("test-user", nil, 10*time.Millisecond, testError)
7576
if err != nil {
7677
t.Errorf("日志记录失败: %v", err)
7778
}

0 commit comments

Comments
 (0)