// Package api provides HTTP routing and handlers for the chat-api service. package api import ( "git.threesix.ai/jordan/sp3-verify-1770325830/pkg/app" "git.threesix.ai/jordan/sp3-verify-1770325830/pkg/auth" "git.threesix.ai/jordan/sp3-verify-1770325830/pkg/realtime" "git.threesix.ai/jordan/sp3-verify-1770325830/services/chat-api/internal/api/handlers" "git.threesix.ai/jordan/sp3-verify-1770325830/services/chat-api/internal/config" "git.threesix.ai/jordan/sp3-verify-1770325830/services/chat-api/internal/service" ) // RegisterRoutes registers all HTTP routes for the service. // Routes are mounted under /api/chat-api to match the ingress path routing. // This allows the monorepo to expose multiple services under a single domain: // - https://domain/api/chat-api/health // - https://domain/api/chat-api/examples // - wss://domain/api/chat-api/ws func RegisterRoutes( application *app.App, exampleService *service.ExampleService, hub realtime.Hub, broadcaster realtime.Broadcaster, ) { logger := application.Logger() cfg := config.Load() // Initialize handlers with injected services healthHandler := handlers.NewHealth(logger) exampleHandler := handlers.NewExample(exampleService, logger) // Initialize WebSocket handler wsHandler := realtime.NewHandler(hub, logger, realtime.HandlerConfig{ Broadcaster: broadcaster, OnConnect: func(conn realtime.Connection) { logger.Info("websocket client connected", "client_id", conn.ID(), "user_id", conn.UserID(), ) }, OnDisconnect: func(conn realtime.Connection) { logger.Info("websocket client disconnected", "client_id", conn.ID(), ) }, OnMessage: func(conn realtime.Connection, msg *realtime.Message) *realtime.Message { if msg.Type == "" { msg.Type = realtime.MessageTypeChat } return msg }, AuthRequired: cfg.AuthEnabled, }) // Build and mount OpenAPI spec spec := NewServiceSpec() application.EnableDocs(spec) // Mount WebSocket routes application.Mount("/api/chat-api/ws", wsHandler.Routes()) // Register API routes under /api/{service-name} to match ingress path routing. // The ingress routes /api/chat-api/* to this service. application.Route("/api/chat-api", func(r app.Router) { r.Get("/health", healthHandler.Check) // Public routes (no auth required) r.Get("/examples", app.Wrap(exampleHandler.List)) r.Get("/examples/{id}", app.Wrap(exampleHandler.Get)) // Protected routes (auth required when enabled) r.Group(func(r app.Router) { if cfg.AuthEnabled { r.Use(auth.Middleware(auth.MiddlewareConfig{ Validator: auth.NewJWTValidator(auth.JWTConfig{ Secret: []byte(cfg.JWTSecret), Issuer: "sp3-verify-1770325830", }), })) } r.Post("/examples", app.Wrap(exampleHandler.Create)) r.Put("/examples/{id}", app.Wrap(exampleHandler.Update)) r.Delete("/examples/{id}", app.Wrap(exampleHandler.Delete)) }) }) }