diff --git a/.github/workflows/pr-go-test-coverage.yml b/.github/workflows/pr-go-test-coverage.yml index fb5134da..87f9a9ef 100644 --- a/.github/workflows/pr-go-test-coverage.yml +++ b/.github/workflows/pr-go-test-coverage.yml @@ -29,7 +29,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.25' - name: Set up Python uses: actions/setup-python@v5 @@ -52,7 +52,13 @@ jobs: - name: Download dependencies run: go mod download + - name: Verify Go coverage tool + run: | + go tool cover -h || echo "Warning: go tool cover not available" + - name: Run tests with coverage + env: + DATA_ENCRYPTION_KEY: "test-encryption-key-for-ci-only-not-production" run: | go test -v -race -coverprofile=coverage.out -covermode=atomic ./... diff --git a/auth/auth.go b/auth/auth.go index c3c22bde..85fa184f 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -16,7 +16,6 @@ import ( // JWTSecret JWT密钥,将从配置中动态设置 var JWTSecret []byte - // tokenBlacklist 用于登出后的token黑名单(仅内存,按过期时间清理) var tokenBlacklist = struct { sync.RWMutex @@ -34,10 +33,6 @@ func SetJWTSecret(secret string) { JWTSecret = []byte(secret) } - - - - // BlacklistToken 将token加入黑名单直到过期 func BlacklistToken(token string, exp time.Time) { tokenBlacklist.Lock() diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 88fd2063..ee756113 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -2,11 +2,11 @@ package bootstrap import ( "fmt" + "log" "nofx/logger" "sort" "sync" "time" - "log" ) // Priority 初始化优先级常量 diff --git a/config/database.go b/config/database.go index abbf8fd7..5977ae3c 100644 --- a/config/database.go +++ b/config/database.go @@ -54,7 +54,7 @@ type DatabaseInterface interface { // Database 配置数据库 type Database struct { - db *sql.DB + db *sql.DB cryptoService *crypto.CryptoService } @@ -760,12 +760,12 @@ func (d *Database) GetExchanges(userID string) ([]*ExchangeConfig, error) { if err != nil { return nil, err } - + // 解密敏感字段 exchange.APIKey = d.decryptSensitiveData(exchange.APIKey) exchange.SecretKey = d.decryptSensitiveData(exchange.SecretKey) exchange.AsterPrivateKey = d.decryptSensitiveData(exchange.AsterPrivateKey) - + exchanges = append(exchanges, &exchange) } @@ -889,7 +889,7 @@ func (d *Database) CreateExchange(userID, id, name, typ string, enabled bool, ap encryptedAPIKey := d.encryptSensitiveData(apiKey) encryptedSecretKey := d.encryptSensitiveData(secretKey) encryptedAsterPrivateKey := d.encryptSensitiveData(asterPrivateKey) - + _, err := d.db.Exec(` INSERT OR IGNORE INTO exchanges (id, user_id, name, type, enabled, api_key, secret_key, testnet, hyperliquid_wallet_addr, aster_user, aster_signer, aster_private_key) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) @@ -1242,13 +1242,13 @@ func (d *Database) encryptSensitiveData(plaintext string) string { if d.cryptoService == nil || plaintext == "" { return plaintext } - + encrypted, err := d.cryptoService.EncryptForStorage(plaintext) if err != nil { log.Printf("⚠️ 加密失败: %v", err) return plaintext // 返回明文作为降级处理 } - + return encrypted } @@ -1257,17 +1257,17 @@ func (d *Database) decryptSensitiveData(encrypted string) string { if d.cryptoService == nil || encrypted == "" { return encrypted } - + // 如果不是加密格式,直接返回 if !d.cryptoService.IsEncryptedStorageValue(encrypted) { return encrypted } - + decrypted, err := d.cryptoService.DecryptFromStorage(encrypted) if err != nil { log.Printf("⚠️ 解密失败: %v", err) return encrypted // 返回加密文本作为降级处理 } - + return decrypted } diff --git a/config/database_test.go b/config/database_test.go index 11655bca..99ac03f3 100644 --- a/config/database_test.go +++ b/config/database_test.go @@ -206,7 +206,6 @@ func TestUpdateExchange_NonEmptyValuesShouldUpdate(t *testing.T) { } } - // TestUpdateExchange_PartialUpdateShouldWork 测试部分字段更新 func TestUpdateExchange_PartialUpdateShouldWork(t *testing.T) { db, cleanup := setupTestDB(t) diff --git a/config/test_rsa_key.pem.pub b/config/test_rsa_key.pem.pub new file mode 100644 index 00000000..a9f89eeb --- /dev/null +++ b/config/test_rsa_key.pem.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4Y666RzY5LLi6PiYL+vC +7+fcr122Fd8BC7IdqUSYKQ33Nsi9J7J5fDgcMf7ZAnIBpxMV7+e1KEoiwtGmxwHj +mYo0ZV0E6JXdiK26S052+Shquri0IXkwGFraDuNKqmGrj6vZuXtq2L2gdSyZCxrI +veN9g6LxBvLBP1Rx7UEmZeyokRYvChcxAQXuS/0br44BOHGtwAElk6AGLISz55AG +oM40b3ktiza+8THKMz3GiylQQYpBltbM3yAXPlnXJ2MtUZiaHNhEQI4++PMvEErN +Izm8cIgcvUAXJ5vBfa4kD0kSgBJFuEQ2im3qcWTuEPRKztEeJDY7XAVHc1Xy6d4N +vQIDAQAB +-----END PUBLIC KEY----- diff --git a/crypto/crypto.go b/crypto/crypto.go index 8710e908..9a29480f 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -391,4 +391,4 @@ func (cs *CryptoService) DecryptSensitiveData(payload *EncryptedPayload) (string return "", err } return string(plaintext), nil -} \ No newline at end of file +} diff --git a/decision/engine.go b/decision/engine.go index 15b4a892..a4d9132c 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -37,7 +37,7 @@ type PositionInfo struct { Leverage int `json:"leverage"` UnrealizedPnL float64 `json:"unrealized_pnl"` UnrealizedPnLPct float64 `json:"unrealized_pnl_pct"` - PeakPnLPct float64 `json:"peak_pnl_pct"` // 历史最高收益率(百分比) + PeakPnLPct float64 `json:"peak_pnl_pct"` // 历史最高收益率(百分比) LiquidationPrice float64 `json:"liquidation_price"` MarginUsed float64 `json:"margin_used"` UpdateTime int64 `json:"update_time"` // 持仓更新时间戳(毫秒)