package config import ( "fmt" "os" "time" "gopkg.in/yaml.v3" ) type Config struct { Environment string `yaml:"environment"` ArchiveDir string `yaml:"archiveDir"` StateDir string `yaml:"stateDir"` PollInterval string `yaml:"pollInterval"` Feishu FeishuConfig `yaml:"feishu"` PollDuration time.Duration `yaml:"-"` } type FeishuConfig struct { AppID string `yaml:"appId"` AppSecret string `yaml:"appSecret"` ChatID string `yaml:"chatId"` } func Load(path string) (Config, error) { body, err := os.ReadFile(path) if err != nil { return Config{}, fmt.Errorf("read config %s: %w", path, err) } var cfg Config if err := yaml.Unmarshal(body, &cfg); err != nil { return Config{}, fmt.Errorf("parse config %s: %w", path, err) } if cfg.Environment == "" { cfg.Environment = "preview" } if cfg.ArchiveDir == "" { cfg.ArchiveDir = "/data/full-sync" } if cfg.StateDir == "" { cfg.StateDir = "/data/state" } if cfg.PollInterval == "" { cfg.PollInterval = "10s" } cfg.PollDuration, err = time.ParseDuration(cfg.PollInterval) if err != nil || cfg.PollDuration <= 0 { return Config{}, fmt.Errorf("invalid pollInterval %q", cfg.PollInterval) } return cfg, nil } func (c Config) ValidateSend() error { if c.Feishu.AppID == "" || c.Feishu.AppSecret == "" { return fmt.Errorf("feishu.appId and feishu.appSecret are required") } if c.Feishu.ChatID == "" { return fmt.Errorf("feishu.chatId is required") } return nil }