package main import ( "context" "fmt" "log" "os" "os/signal" "syscall" "github.com/geo-platform/tenant-api/internal/bootstrap" tenantapp "github.com/geo-platform/tenant-api/internal/tenant/app" "github.com/geo-platform/tenant-api/internal/tenant/transport" ) func main() { configPath := "configs/config.yaml" if p := os.Getenv("CONFIG_PATH"); p != "" { configPath = p } app, err := bootstrap.New(configPath) if err != nil { log.Fatalf("bootstrap: %v", err) } defer app.Close() workerCtx, workerCancel := context.WithCancel(context.Background()) defer workerCancel() app.StartConfigWatcher(workerCtx) app.GenerationStreams.Run(workerCtx) app.DesktopTaskStreams.Run(workerCtx) app.DesktopDispatch.Run(workerCtx) monitoringService := app.MonitoringService monitoringCallbackService := tenantapp.NewMonitoringCallbackService(app.DB, app.MonitoringDB, app.RabbitMQ, app.LLM, app.Logger) tenantapp.NewMonitoringCollectOutboxWorker(monitoringService, app.Logger).Start(workerCtx) tenantapp.NewMonitoringResultIngestWorker(monitoringCallbackService, app.RabbitMQ, app.Logger, app.Config().MonitoringWorkers).Start(workerCtx) tenantapp.NewMonitoringProjectionRebuildWorker(monitoringCallbackService, app.RabbitMQ, app.Logger, app.Config().MonitoringWorkers).Start(workerCtx) tenantapp.NewDesktopAccountHealthSinkWorker(app.DB, app.RabbitMQ, app.Logger).Start(workerCtx) imageService := tenantapp.NewImageService(app.DB, app.ObjectStorage, app.RabbitMQ, app.Logger) tenantapp.NewImageAssetWorker(imageService, app.RabbitMQ, app.Logger).Start(workerCtx) transport.RegisterRoutes(app) addr := fmt.Sprintf(":%d", app.Config().Server.Port) app.Logger.Sugar().Infof("tenant-api starting on %s", addr) go func() { if err := app.Engine.Run(addr); err != nil { app.Logger.Sugar().Fatalf("server: %v", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit workerCancel() app.Logger.Info("shutting down...") }