feat: implement hybrid database architecture and frontend encryption

- Add PostgreSQL + SQLite hybrid database support with automatic switching
- Implement frontend AES-GCM + RSA-OAEP encryption for sensitive data
- Add comprehensive DatabaseInterface with all required methods
- Fix compilation issues with interface consistency
- Update all database method signatures to use DatabaseInterface
- Add missing UpdateTraderInitialBalance method to PostgreSQL implementation
- Integrate RSA public key distribution via /api/config endpoint
- Add frontend crypto service with proper error handling
- Support graceful degradation between encrypted and plaintext transmission
- Add directory creation for RSA keys and PEM parsing fixes
- Test both SQLite and PostgreSQL modes successfully

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
icy
2025-11-06 01:50:06 +08:00
parent aecc5e58a1
commit 65053518d6
104 changed files with 16864 additions and 4152 deletions

View File

@@ -50,6 +50,20 @@ type LeverageConfig struct {
AltcoinLeverage int `json:"altcoin_leverage"` // 山寨币的杠杆倍数主账户建议5-20子账户≤5
}
// LogConfig 日志配置
type LogConfig struct {
Level string `json:"level"` // 日志级别: debug, info, warn, error (默认: info)
Telegram *TelegramConfig `json:"telegram"` // Telegram推送配置可选
}
// TelegramConfig Telegram推送配置简化版只保留必需字段
type TelegramConfig struct {
Enabled bool `json:"enabled"` // 是否启用(默认: false
BotToken string `json:"bot_token"` // Bot Token
ChatID int64 `json:"chat_id"` // Chat ID
MinLevel string `json:"min_level"` // 最低日志级别该级别及以上的日志会推送到Telegram可选默认: error
}
// Config 总配置
type Config struct {
Traders []TraderConfig `json:"traders"`
@@ -60,6 +74,7 @@ type Config struct {
MaxDrawdown float64 `json:"max_drawdown"`
StopTradingMinutes int `json:"stop_trading_minutes"`
Leverage LeverageConfig `json:"leverage"` // 杠杆配置
Log *LogConfig `json:"log"` // 日志配置(可选)
}
// LoadConfig 从文件加载配置

View File

@@ -40,6 +40,7 @@ type DatabaseInterface interface {
GetTraders(userID string) ([]*TraderRecord, error)
UpdateTraderStatus(userID, id string, isRunning bool) error
UpdateTrader(trader *TraderRecord) error
UpdateTraderInitialBalance(userID, id string, newBalance float64) error
UpdateTraderCustomPrompt(userID, id string, customPrompt string, overrideBase bool) error
DeleteTrader(userID, id string) error
GetTraderConfig(userID, traderID string) (*TraderRecord, *AIModelConfig, *ExchangeConfig, error)
@@ -899,6 +900,12 @@ func (d *Database) UpdateTraderCustomPrompt(userID, id string, customPrompt stri
return err
}
// UpdateTraderInitialBalance 更新交易员初始余额(用于自动同步交易所实际余额)
func (d *Database) UpdateTraderInitialBalance(userID, id string, newBalance float64) error {
_, err := d.db.Exec(`UPDATE traders SET initial_balance = ? WHERE id = ? AND user_id = ?`, newBalance, id, userID)
return err
}
// DeleteTrader 删除交易员
func (d *Database) DeleteTrader(userID, id string) error {
_, err := d.db.Exec(`DELETE FROM traders WHERE id = ? AND user_id = ?`, id, userID)
@@ -928,8 +935,13 @@ func (d *Database) GetTraderConfig(userID, traderID string) (*TraderRecord, *AIM
`, traderID, userID).Scan(
&trader.ID, &trader.UserID, &trader.Name, &trader.AIModelID, &trader.ExchangeID,
&trader.InitialBalance, &trader.ScanIntervalMinutes, &trader.IsRunning,
&trader.BTCETHLeverage, &trader.AltcoinLeverage, &trader.TradingSymbols,
&trader.UseCoinPool, &trader.UseOITop,
&trader.CustomPrompt, &trader.OverrideBasePrompt, &trader.SystemPromptTemplate,
&trader.IsCrossMargin,
&trader.CreatedAt, &trader.UpdatedAt,
&aiModel.ID, &aiModel.UserID, &aiModel.Name, &aiModel.Provider, &aiModel.Enabled, &aiModel.APIKey,
&aiModel.CustomAPIURL, &aiModel.CustomModelName,
&aiModel.CreatedAt, &aiModel.UpdatedAt,
&exchange.ID, &exchange.UserID, &exchange.Name, &exchange.Type, &exchange.Enabled,
&exchange.APIKey, &exchange.SecretKey, &exchange.Testnet,
@@ -1065,7 +1077,7 @@ func (d *Database) LoadBetaCodesFromFile(filePath string) error {
log.Printf("插入内测码 %s 失败: %v", code, err)
continue
}
if rowsAffected, _ := result.RowsAffected(); rowsAffected > 0 {
insertedCount++
}

View File

@@ -464,6 +464,12 @@ func (d *PostgreSQLDatabase) UpdateTraderCustomPrompt(userID, id string, customP
return err
}
// UpdateTraderInitialBalance 更新交易员初始余额(用于自动同步交易所实际余额)
func (d *PostgreSQLDatabase) UpdateTraderInitialBalance(userID, id string, newBalance float64) error {
_, err := d.db.Exec(`UPDATE traders SET initial_balance = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2 AND user_id = $3`, newBalance, id, userID)
return err
}
// DeleteTrader 删除交易员
func (d *PostgreSQLDatabase) DeleteTrader(userID, id string) error {
_, err := d.db.Exec(`DELETE FROM traders WHERE id = $1 AND user_id = $2`, id, userID)

View File

@@ -1,9 +0,0 @@
package config
import "testing"
func TestExample(t *testing.T) {
if 1+1 != 2 {
t.Error("Math is broken")
}
}