package app import ( "context" "net/http" "time" "git.118im.com/im_team/im_workbench/internal/ai" "git.118im.com/im_team/im_workbench/internal/auth" "git.118im.com/im_team/im_workbench/internal/config" "git.118im.com/im_team/im_workbench/internal/events" "git.118im.com/im_team/im_workbench/internal/httpapi" "git.118im.com/im_team/im_workbench/internal/managerconfig" "git.118im.com/im_team/im_workbench/internal/store" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/redis/go-redis/v9" ) type App struct { store *store.Store redis *redis.Client events events.Publisher api *httpapi.API } func New(cfg *config.Config) (*App, error) { uidKey := managerconfig.ResolveUIDKey(context.Background(), cfg.Manager, cfg.Auth.UIDKey) if err := httpapi.SetUIDKey(uidKey); err != nil { return nil, err } if err := store.SetUIDKey(uidKey); err != nil { return nil, err } cfg.AI = managerconfig.ResolveAIConfig(context.Background(), cfg.Manager, cfg.AI) st, err := store.Open(cfg.MySQL) if err != nil { return nil, err } var redisClient *redis.Client if !cfg.Auth.SkipSessionInDev { redisClient = redis.NewClient(&redis.Options{ Addr: cfg.Redis.Addr, Username: cfg.Redis.Username, Password: cfg.Redis.Password, DB: cfg.Redis.DB, }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := redisClient.Ping(ctx).Err(); err != nil { _ = st.Close() return nil, err } } publisher, err := events.NewKafkaPublisher(cfg.Kafka) if err != nil { if redisClient != nil { _ = redisClient.Close() } _ = st.Close() return nil, err } aiService := ai.NewService(ai.NewClient(cfg.AI)) return &App{ store: st, redis: redisClient, events: publisher, api: httpapi.New(st, auth.New(cfg.Auth, redisClient), publisher, cfg.Auth, cfg.Manager, aiService), }, nil } func (a *App) Handler() http.Handler { mux := http.NewServeMux() mux.HandleFunc("/healthz", a.api.Healthz) mux.Handle("/metrics", promhttp.Handler()) a.api.Register(mux) return mux } func (a *App) Close() { if a.redis != nil { _ = a.redis.Close() } if a.events != nil { _ = a.events.Close() } if a.store != nil { _ = a.store.Close() } }