// Package main is the entry point for the chat-api service. package main import ( "context" "github.com/redis/go-redis/v9" "git.threesix.ai/jordan/sp3-test-1770368381/pkg/app" "git.threesix.ai/jordan/sp3-test-1770368381/pkg/logging" "git.threesix.ai/jordan/sp3-test-1770368381/pkg/realtime" "git.threesix.ai/jordan/sp3-test-1770368381/services/chat-api/internal/adapter/memory" "git.threesix.ai/jordan/sp3-test-1770368381/services/chat-api/internal/api" "git.threesix.ai/jordan/sp3-test-1770368381/services/chat-api/internal/config" "git.threesix.ai/jordan/sp3-test-1770368381/services/chat-api/internal/service" ) func main() { // Create logger logger := logging.Default() cfg := config.Load() // Create adapters (repositories) exampleRepo := memory.NewExampleRepository() // Create services (business logic) exampleService := service.NewExampleService(exampleRepo, logger) // Create application application := app.New("chat-api", app.WithDefaultPort(8001)) // Set up WebSocket hub and Redis broadcaster hub := realtime.NewHub(logger) hubCtx, hubCancel := context.WithCancel(context.Background()) go hub.Run(hubCtx) var broadcaster realtime.Broadcaster if cfg.RedisURL != "" { opts, err := redis.ParseURL(cfg.RedisURL) if err != nil { logger.Error("invalid REDIS_URL", "error", err) } else { redisClient := redis.NewClient(opts) redisBroadcaster := realtime.NewRedisBroadcaster(redisClient, hub, logger) go func() { if err := redisBroadcaster.Run(hubCtx); err != nil && hubCtx.Err() == nil { logger.Error("redis broadcaster error", "error", err) } }() broadcaster = redisBroadcaster application.OnShutdown(func(_ context.Context) error { return redisClient.Close() }) } } wsHandler := realtime.NewHandler(hub, logger, realtime.HandlerConfig{ Broadcaster: broadcaster, }) application.OnShutdown(func(_ context.Context) error { hubCancel() return nil }) // Register routes with dependency injection api.RegisterRoutes(application, exampleService, wsHandler) // Start server application.Run() }