mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 09:11:03 +08:00
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:
78
main.go
78
main.go
@@ -25,54 +25,64 @@ type LeverageConfig struct {
|
||||
|
||||
// ConfigFile 配置文件结构,只包含需要同步到数据库的字段
|
||||
type ConfigFile struct {
|
||||
AdminMode bool `json:"admin_mode"`
|
||||
BetaMode bool `json:"beta_mode"`
|
||||
APIServerPort int `json:"api_server_port"`
|
||||
UseDefaultCoins bool `json:"use_default_coins"`
|
||||
DefaultCoins []string `json:"default_coins"`
|
||||
CoinPoolAPIURL string `json:"coin_pool_api_url"`
|
||||
OITopAPIURL string `json:"oi_top_api_url"`
|
||||
MaxDailyLoss float64 `json:"max_daily_loss"`
|
||||
MaxDrawdown float64 `json:"max_drawdown"`
|
||||
StopTradingMinutes int `json:"stop_trading_minutes"`
|
||||
Leverage LeverageConfig `json:"leverage"`
|
||||
JWTSecret string `json:"jwt_secret"`
|
||||
DataKLineTime string `json:"data_k_line_time"`
|
||||
AdminMode bool `json:"admin_mode"`
|
||||
BetaMode bool `json:"beta_mode"`
|
||||
APIServerPort int `json:"api_server_port"`
|
||||
UseDefaultCoins bool `json:"use_default_coins"`
|
||||
DefaultCoins []string `json:"default_coins"`
|
||||
CoinPoolAPIURL string `json:"coin_pool_api_url"`
|
||||
OITopAPIURL string `json:"oi_top_api_url"`
|
||||
MaxDailyLoss float64 `json:"max_daily_loss"`
|
||||
MaxDrawdown float64 `json:"max_drawdown"`
|
||||
StopTradingMinutes int `json:"stop_trading_minutes"`
|
||||
Leverage LeverageConfig `json:"leverage"`
|
||||
JWTSecret string `json:"jwt_secret"`
|
||||
DataKLineTime string `json:"data_k_line_time"`
|
||||
Log *config.LogConfig `json:"log"` // 日志配置
|
||||
}
|
||||
|
||||
// syncConfigToDatabase 从config.json读取配置并同步到数据库
|
||||
func syncConfigToDatabase(database config.DatabaseInterface) error {
|
||||
// loadConfigFile 读取并解析config.json文件
|
||||
func loadConfigFile() (*ConfigFile, error) {
|
||||
// 检查config.json是否存在
|
||||
if _, err := os.Stat("config.json"); os.IsNotExist(err) {
|
||||
log.Printf("📄 config.json不存在,跳过同步")
|
||||
return nil
|
||||
log.Printf("📄 config.json不存在,使用默认配置")
|
||||
return &ConfigFile{}, nil
|
||||
}
|
||||
|
||||
// 读取config.json
|
||||
data, err := os.ReadFile("config.json")
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取config.json失败: %w", err)
|
||||
return nil, fmt.Errorf("读取config.json失败: %w", err)
|
||||
}
|
||||
|
||||
// 解析JSON
|
||||
var configFile ConfigFile
|
||||
if err := json.Unmarshal(data, &configFile); err != nil {
|
||||
return fmt.Errorf("解析config.json失败: %w", err)
|
||||
return nil, fmt.Errorf("解析config.json失败: %w", err)
|
||||
}
|
||||
|
||||
return &configFile, nil
|
||||
}
|
||||
|
||||
// syncConfigToDatabase 将配置同步到数据库
|
||||
func syncConfigToDatabase(database config.DatabaseInterface, configFile *ConfigFile) error {
|
||||
if configFile == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("🔄 开始同步config.json到数据库...")
|
||||
|
||||
// 同步各配置项到数据库
|
||||
configs := map[string]string{
|
||||
"admin_mode": fmt.Sprintf("%t", configFile.AdminMode),
|
||||
"beta_mode": fmt.Sprintf("%t", configFile.BetaMode),
|
||||
"api_server_port": strconv.Itoa(configFile.APIServerPort),
|
||||
"use_default_coins": fmt.Sprintf("%t", configFile.UseDefaultCoins),
|
||||
"coin_pool_api_url": configFile.CoinPoolAPIURL,
|
||||
"oi_top_api_url": configFile.OITopAPIURL,
|
||||
"max_daily_loss": fmt.Sprintf("%.1f", configFile.MaxDailyLoss),
|
||||
"max_drawdown": fmt.Sprintf("%.1f", configFile.MaxDrawdown),
|
||||
"stop_trading_minutes": strconv.Itoa(configFile.StopTradingMinutes),
|
||||
"admin_mode": fmt.Sprintf("%t", configFile.AdminMode),
|
||||
"beta_mode": fmt.Sprintf("%t", configFile.BetaMode),
|
||||
"api_server_port": strconv.Itoa(configFile.APIServerPort),
|
||||
"use_default_coins": fmt.Sprintf("%t", configFile.UseDefaultCoins),
|
||||
"coin_pool_api_url": configFile.CoinPoolAPIURL,
|
||||
"oi_top_api_url": configFile.OITopAPIURL,
|
||||
"max_daily_loss": fmt.Sprintf("%.1f", configFile.MaxDailyLoss),
|
||||
"max_drawdown": fmt.Sprintf("%.1f", configFile.MaxDrawdown),
|
||||
"stop_trading_minutes": strconv.Itoa(configFile.StopTradingMinutes),
|
||||
}
|
||||
|
||||
// 同步default_coins(转换为JSON字符串存储)
|
||||
@@ -112,7 +122,7 @@ func syncConfigToDatabase(database config.DatabaseInterface) error {
|
||||
// loadBetaCodesToDatabase 加载内测码文件到数据库
|
||||
func loadBetaCodesToDatabase(database config.DatabaseInterface) error {
|
||||
betaCodeFile := "beta_codes.txt"
|
||||
|
||||
|
||||
// 检查内测码文件是否存在
|
||||
if _, err := os.Stat(betaCodeFile); os.IsNotExist(err) {
|
||||
log.Printf("📄 内测码文件 %s 不存在,跳过加载", betaCodeFile)
|
||||
@@ -126,7 +136,7 @@ func loadBetaCodesToDatabase(database config.DatabaseInterface) error {
|
||||
}
|
||||
|
||||
log.Printf("🔄 发现内测码文件 %s (%.1f KB),开始加载...", betaCodeFile, float64(fileInfo.Size())/1024)
|
||||
|
||||
|
||||
// 加载内测码到数据库
|
||||
err = database.LoadBetaCodesFromFile(betaCodeFile)
|
||||
if err != nil {
|
||||
@@ -156,6 +166,12 @@ func main() {
|
||||
dbPath = os.Args[1]
|
||||
}
|
||||
|
||||
// 读取配置文件
|
||||
configFile, err := loadConfigFile()
|
||||
if err != nil {
|
||||
log.Fatalf("❌ 读取config.json失败: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("📋 初始化配置数据库: %s", dbPath)
|
||||
database, err := config.NewDatabase(dbPath)
|
||||
if err != nil {
|
||||
@@ -164,7 +180,7 @@ func main() {
|
||||
defer database.Close()
|
||||
|
||||
// 同步config.json到数据库
|
||||
if err := syncConfigToDatabase(database); err != nil {
|
||||
if err := syncConfigToDatabase(database, configFile); err != nil {
|
||||
log.Printf("⚠️ 同步config.json到数据库失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user