feat: add durable Kuknos settlement coordination

This commit is contained in:
Navid
2026-09-15 13:59:13 +03:30
parent d5c9b338a4
commit 12c478cf3a
34 changed files with 1846 additions and 122 deletions
+47 -12
View File
@@ -3,6 +3,8 @@ package config
import (
"fmt"
"os"
"strings"
"time"
"github.com/knadh/koanf/parsers/toml"
@@ -11,21 +13,22 @@ import (
)
type Config struct {
Environment string `koanf:"environment"`
GRPC GRPCConfig `koanf:"grpc"`
Database DatabaseConfig `koanf:"database"`
Environment string `koanf:"environment"`
GRPC GRPCConfig `koanf:"grpc"`
Database DatabaseConfig `koanf:"db"`
Settlement SettlementConfig `koanf:"settlement"`
}
type DashboardConfig struct {
Environment string `koanf:"environment"`
HTTP HTTPConfig `koanf:"http"`
Database DatabaseConfig `koanf:"database"`
Database DatabaseConfig `koanf:"db"`
}
type GRPCConfig struct {
Host string `koanf:"host"`
Port int `koanf:"port"`
ShutdownTimeout time.Duration `koanf:"shutdown-timeout"`
ShutdownTimeout time.Duration `koanf:"timeout"`
}
type HTTPConfig struct {
@@ -36,12 +39,23 @@ type HTTPConfig struct {
}
type DatabaseConfig struct {
Host string `koanf:"host"`
Port int `koanf:"port"`
Name string `koanf:"name"`
User string `koanf:"user"`
Password string `koanf:"password"`
SSLMode string `koanf:"ssl-mode"`
Host string `koanf:"host"`
Port int `koanf:"port"`
Name string `koanf:"name"`
User string `koanf:"user"`
Password string `koanf:"password"`
GormLogLevel int `koanf:"gorm-log-level"`
SSLMode string `koanf:"-"`
}
type SettlementConfig struct {
Enabled bool `koanf:"enabled"`
Endpoint string `koanf:"endpoint"`
WorkerID string `koanf:"worker-id"`
PollInterval time.Duration `koanf:"poll-interval"`
BatchSize int `koanf:"batch-size"`
MaxAttempts int `koanf:"max-attempts"`
AdminToken string `koanf:"admin-token"`
}
func Load(path string) (*Config, error) {
@@ -52,12 +66,14 @@ func Load(path string) (*Config, error) {
Port: 8600,
ShutdownTimeout: 10 * time.Second,
},
Database: defaultDatabaseConfig(),
Database: defaultDatabaseConfig(),
Settlement: SettlementConfig{WorkerID: "gl-settlement-1", PollInterval: 5 * time.Second, BatchSize: 20, MaxAttempts: 8},
}
if err := load(path, cfg); err != nil {
return nil, err
}
applyEnvironment(&cfg.Database, &cfg.Settlement)
if err := cfg.Validate(); err != nil {
return nil, err
}
@@ -78,12 +94,28 @@ func LoadDashboard(path string) (*DashboardConfig, error) {
if err := load(path, cfg); err != nil {
return nil, err
}
applyEnvironment(&cfg.Database, nil)
if err := cfg.Validate(); err != nil {
return nil, err
}
return cfg, nil
}
func applyEnvironment(database *DatabaseConfig, settlement *SettlementConfig) {
if value, ok := os.LookupEnv("DARANO_GL_DB_PASSWORD"); ok {
database.Password = value
}
if settlement == nil {
return
}
if value, ok := os.LookupEnv("DARANO_GL_SETTLEMENT_ENDPOINT"); ok {
settlement.Endpoint = strings.TrimRight(value, "/")
}
if value, ok := os.LookupEnv("DARANO_GL_ADMIN_TOKEN"); ok {
settlement.AdminToken = value
}
}
func load(path string, target any) error {
k := koanf.New(".")
if err := k.Load(file.Provider(path), toml.Parser()); err != nil {
@@ -115,6 +147,9 @@ func (c *Config) Validate() error {
if c.GRPC.ShutdownTimeout <= 0 {
return fmt.Errorf("grpc shutdown timeout must be positive")
}
if c.Environment == "production" && c.Settlement.AdminToken == "" {
return fmt.Errorf("settlement admin token is required in production")
}
return validateDatabase(c.Database)
}