package main import ( "database/sql" "log" _ "github.com/lib/pq" "github.com/gin-gonic/gin" "github.com/tcs-iptv/tcs/internal/api" "github.com/tcs-iptv/tcs/internal/chain" "github.com/tcs-iptv/tcs/internal/config" "github.com/tcs-iptv/tcs/internal/httpx" "github.com/tcs-iptv/tcs/internal/macode" "github.com/tcs-iptv/tcs/internal/service" ) // newAllocationStore 优先使用 PostgreSQL(持久、防重号),不可用时回退内存。 func newAllocationStore(dsn string) macode.AllocationStore { db, err := sql.Open("postgres", dsn) if err == nil { if pingErr := db.Ping(); pingErr == nil { log.Printf("macode: 使用 PostgreSQL 号段存储") return macode.NewPostgresStore(db) } } log.Printf("macode: PostgreSQL 不可用,回退内存号段存储(仅开发用)") return macode.NewMemoryStore() } func main() { cfg := config.Load() // 装配依赖:链(MVP 用内存 mock)+ MA 码生成器(登记号段)+ 业务服务 ch := chain.NewMemoryChain() gen := macode.NewGenerator(newAllocationStore(cfg.PostgresDSN)) // 示例号段(生产由与发码机构对接后配置) // 机构节点 6101 = 陕西(管理方:陕西IPTV运营公司);行业节点 8531 = IPTV视听内容 _ = gen.RegisterSegment(macode.Segment{ IndustryNode: "8531", OrgNode: "6101", Category: macode.CategoryMicroDrama, Start: 1, End: 9999999, SeqWidth: 7, }) _ = gen.RegisterSegment(macode.Segment{ IndustryNode: "8531", OrgNode: "6101", Category: macode.CategoryWebSeries, Start: 1, End: 9999999, SeqWidth: 7, }) _ = gen.RegisterSegment(macode.Segment{ IndustryNode: "8531", OrgNode: "6101", Category: macode.CategoryWebMovie, Start: 1, End: 9999999, SeqWidth: 7, }) svc := service.New(ch, gen) h := api.NewHandler(svc) // 鉴权密钥库(MVP 预置四角色示例密钥;生产从 Vault/DB 加载) keys := httpx.NewMemoryKeyStore() keys.Add("ak-regulator", "sk-regulator", string(chain.RoleRegulator)) keys.Add("ak-reviewer", "sk-reviewer", string(chain.RoleReviewer)) keys.Add("ak-cp", "sk-cp", string(chain.RoleCP)) keys.Add("ak-operator", "sk-operator", string(chain.RoleOperator)) r := gin.Default() httpx.Health(r, "api-svc") v1 := r.Group("/api/v1", httpx.AuthMiddleware(keys)) h.Register(v1) log.Printf("api-svc listening on %s", cfg.APIAddr) if err := r.Run(cfg.APIAddr); err != nil { log.Fatalf("api-svc failed: %v", err) } }