// Package config 定义 user-service 的启动配置和 YAML 加载入口。 package config import ( "strings" "hyapp/pkg/configx" "hyapp/pkg/logx" ) // Config 描述 user-service 启动配置。 type Config struct { // ServiceName 是进程服务名,当前主要用于配置可读性。 ServiceName string `yaml:"service_name"` // NodeID 是当前服务节点标识,预留给日志和后续健康响应使用。 NodeID string `yaml:"node_id"` // Environment 是日志和部署策略使用的环境标签。 Environment string `yaml:"environment"` // GRPCAddr 是 user-service 内部 gRPC 监听地址。 GRPCAddr string `yaml:"grpc_addr"` // MySQLDSN 是用户主数据、认证身份、session 和短号事务的必需存储连接串。 MySQLDSN string `yaml:"mysql_dsn"` // MySQLAutoMigrate 保留给显式本地迁移;线上 schema 由发布流程或 initdb 管理。 MySQLAutoMigrate bool `yaml:"mysql_auto_migrate"` // IDGenerator 控制 user_id 发号节点。 IDGenerator IDGeneratorConfig `yaml:"id_generator"` // DisplayUserID 控制短号分配重试和默认短号修改冷却期。 DisplayUserID DisplayUserIDConfig `yaml:"display_user_id"` // ThirdParty 控制本地三方登录 provider allowlist。 ThirdParty ThirdPartyConfig `yaml:"third_party"` // RegionRebuildWorker 控制历史用户 region_id 快照后台重算。 RegionRebuildWorker RegionRebuildWorkerConfig `yaml:"region_rebuild_worker"` // InviteRechargeWorker 控制邀请有效人数的 wallet recharge outbox 消费。 InviteRechargeWorker InviteRechargeWorkerConfig `yaml:"invite_recharge_worker"` // MicTimeWorker 控制 room-service 麦位事件消费和用户麦上时长聚合。 MicTimeWorker MicTimeWorkerConfig `yaml:"mic_time_worker"` // JWT 控制 access token 和 refresh session 的签发参数。 JWT JWTConfig `yaml:"jwt"` // Log 控制 stdout 结构化日志格式、等级和 access body 策略。 Log logx.Config `yaml:"log"` } // IDGeneratorConfig 保存 user_id 发号节点配置。 type IDGeneratorConfig struct { // NodeID 参与雪花 ID 发号,多个 user-service 节点必须不同。 NodeID int64 `yaml:"node_id"` } // DisplayUserIDConfig 保存短号分配和修改策略。 type DisplayUserIDConfig struct { // AllocateMaxAttempts 是默认短号冲突时的最大重试次数。 AllocateMaxAttempts int `yaml:"allocate_max_attempts"` // ChangeCooldownSec 是默认短号修改冷却期秒数。 ChangeCooldownSec int64 `yaml:"change_cooldown_sec"` } // ThirdPartyConfig 保存三方登录 provider allowlist 和真实 verifier 配置。 type ThirdPartyConfig struct { // AllowedProviders 是 provider allowlist;firebase 会被强制路由到 Firebase verifier。 AllowedProviders []string `yaml:"allowed_providers"` // Firebase 保存 Firebase Auth ID token verifier 配置。 Firebase FirebaseConfig `yaml:"firebase"` } // FirebaseConfig 保存 Firebase Auth ID token verifier 配置。 type FirebaseConfig struct { // ProjectID 必须匹配 Firebase token 的 aud 和 issuer。 ProjectID string `yaml:"project_id"` // AllowedSignInProviders 限制 firebase.sign_in_provider,首版默认 google.com。 AllowedSignInProviders []string `yaml:"allowed_sign_in_providers"` // CertsURL 只用于测试或私有代理;生产为空时使用 Firebase 官方公钥端点。 CertsURL string `yaml:"certs_url"` } // RegionRebuildWorkerConfig 保存区域映射变更后历史用户快照重算策略。 type RegionRebuildWorkerConfig struct { // Enabled 控制是否启动后台 worker;关闭后只创建 task,不消费。 Enabled bool `yaml:"enabled"` // PollIntervalSec 是两轮扫描间隔秒数。 PollIntervalSec int64 `yaml:"poll_interval_sec"` // LockTTLSec 是单个 task claim 锁定时间秒数,过期允许其他节点接管。 LockTTLSec int64 `yaml:"lock_ttl_sec"` // BatchSize 是单轮最多更新 users 数量。 BatchSize int `yaml:"batch_size"` } // InviteRechargeWorkerConfig 保存钱包充值事实消费策略。 type InviteRechargeWorkerConfig struct { // Enabled 控制是否启动钱包充值事件轮询。 Enabled bool `yaml:"enabled"` // WalletMySQLDSN 是 wallet-service outbox 只读连接串;本地可复用同一个 MySQL 实例。 WalletMySQLDSN string `yaml:"wallet_mysql_dsn"` // PollIntervalSec 是没有积压时两轮扫描间隔秒数。 PollIntervalSec int64 `yaml:"poll_interval_sec"` // BatchSize 是单轮最多消费的 wallet_outbox 事件数。 BatchSize int `yaml:"batch_size"` } // MicTimeWorkerConfig 保存房间麦位事件消费策略。 type MicTimeWorkerConfig struct { // Enabled 控制是否启动 room_outbox 轮询;关闭后查询仍可读取已聚合数据。 Enabled bool `yaml:"enabled"` // RoomMySQLDSN 是 room-service outbox 只读连接串。 RoomMySQLDSN string `yaml:"room_mysql_dsn"` // PollIntervalSec 是没有积压时两轮扫描间隔秒数。 PollIntervalSec int64 `yaml:"poll_interval_sec"` // BatchSize 是单轮最多消费的 RoomMicChanged 事件数。 BatchSize int `yaml:"batch_size"` // CompensationEnabled 控制是否启动异常 open session 补偿。 CompensationEnabled bool `yaml:"compensation_enabled"` // CompensationIntervalSec 是补偿扫描间隔秒数。 CompensationIntervalSec int64 `yaml:"compensation_interval_sec"` // CompensationBatchSize 是单轮最多关闭的异常 session 数。 CompensationBatchSize int `yaml:"compensation_batch_size"` // PendingPublishMaxAgeSec 是 pending_publish 缺失 down 事件时的兜底关闭窗口。 PendingPublishMaxAgeSec int64 `yaml:"pending_publish_max_age_sec"` // PublishingSessionMaxAgeSec 是 publishing 缺失 down 事件时允许累计的最大窗口。 PublishingSessionMaxAgeSec int64 `yaml:"publishing_session_max_age_sec"` } // JWTConfig 保存 access token 和 refresh token 的签发策略。 type JWTConfig struct { // Issuer 写入 access token iss claim。 Issuer string `yaml:"issuer"` // AccessTokenTTLSec 是短期 access token 有效期。 AccessTokenTTLSec int64 `yaml:"access_token_ttl_sec"` // RefreshTokenTTLSec 是服务端 session/refresh token 有效期。 RefreshTokenTTLSec int64 `yaml:"refresh_token_ttl_sec"` // SigningAlg 当前只支持 HS256。 SigningAlg string `yaml:"signing_alg"` // SigningSecret 是 HS256 签名密钥,生产不能使用默认开发值。 SigningSecret string `yaml:"signing_secret"` } // Default 返回本地默认配置。 func Default() Config { // 默认端口遵守项目 13xxx 约束;本地进程默认连接 docker-compose 暴露的 MySQL。 return Config{ ServiceName: "user-service", NodeID: "user-local", Environment: "local", GRPCAddr: ":13005", MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_user?parseTime=true&charset=utf8mb4&loc=Local", MySQLAutoMigrate: false, IDGenerator: IDGeneratorConfig{ NodeID: 1, }, DisplayUserID: DisplayUserIDConfig{ AllocateMaxAttempts: 8, ChangeCooldownSec: 2592000, }, ThirdParty: ThirdPartyConfig{ AllowedProviders: []string{"firebase"}, Firebase: FirebaseConfig{ AllowedSignInProviders: []string{"google.com"}, }, }, RegionRebuildWorker: RegionRebuildWorkerConfig{ Enabled: true, PollIntervalSec: 5, LockTTLSec: 30, BatchSize: 500, }, InviteRechargeWorker: InviteRechargeWorkerConfig{ Enabled: true, WalletMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_wallet?parseTime=true&charset=utf8mb4&loc=Local", PollIntervalSec: 5, BatchSize: 100, }, MicTimeWorker: MicTimeWorkerConfig{ Enabled: true, RoomMySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_room?parseTime=true&charset=utf8mb4&loc=Local", PollIntervalSec: 5, BatchSize: 100, CompensationEnabled: true, CompensationIntervalSec: 60, CompensationBatchSize: 100, PendingPublishMaxAgeSec: 120, PublishingSessionMaxAgeSec: 43200, }, JWT: JWTConfig{ Issuer: "hyapp", AccessTokenTTLSec: 1800, RefreshTokenTTLSec: 2592000, SigningAlg: "HS256", SigningSecret: "dev-shared-secret", }, Log: logx.Config{ Level: "info", Format: "json", MaxPayloadBytes: 2048, }, } } // Load 从独立 config.yaml 读取 user-service 配置。 func Load(path string) (Config, error) { cfg := Default() if path == "" { // 空路径显式使用默认配置,便于单元测试和最小启动。 return cfg, nil } if err := configx.LoadYAML(path, &cfg); err != nil { // 配置解析失败返回空 Config,避免调用方误用部分默认值继续启动。 return Config{}, err } cfg.ServiceName = strings.TrimSpace(cfg.ServiceName) if cfg.ServiceName == "" { cfg.ServiceName = "user-service" } cfg.NodeID = strings.TrimSpace(cfg.NodeID) if cfg.NodeID == "" { cfg.NodeID = cfg.ServiceName } cfg.Environment = strings.ToLower(strings.TrimSpace(cfg.Environment)) if cfg.Environment == "" { cfg.Environment = "local" } return cfg, nil }