package handlers import ( "net/http" "github.com/gin-gonic/gin" "github.com/google/uuid" "go.uber.org/zap" apperrors "veza-backend-api/internal/errors" "veza-backend-api/internal/services" ) // StreamEventRequest represents a stream event from the stream server type StreamEventRequest struct { EventType string `json:"event_type" binding:"required"` StreamID string `json:"stream_id"` Title string `json:"title"` Description string `json:"description"` Tags []string `json:"tags"` DurationMs uint64 `json:"duration_ms"` ListenerID string `json:"listener_id"` } // StreamEventsHandler handles stream event callbacks from the stream server type StreamEventsHandler struct { logger *zap.Logger liveStreamService *services.LiveStreamService } // NewStreamEventsHandler creates a new StreamEventsHandler func NewStreamEventsHandler(logger *zap.Logger) *StreamEventsHandler { return &StreamEventsHandler{logger: logger} } // SetLiveStreamService sets the live stream service for updating is_live and viewer_count func (h *StreamEventsHandler) SetLiveStreamService(svc *services.LiveStreamService) { h.liveStreamService = svc } // HandleStreamEvent receives stream events (StreamStarted, StreamEnded, ListenerJoined, ListenerLeft) // from the stream server and processes them (e.g. update live_streams metadata, analytics) func (h *StreamEventsHandler) HandleStreamEvent(c *gin.Context) { var req StreamEventRequest if err := c.ShouldBindJSON(&req); err != nil { h.logger.Warn("Invalid stream event payload", zap.Error(err)) RespondWithAppError(c, apperrors.NewValidationError("invalid payload")) return } h.logger.Info("Stream event received", zap.String("event_type", req.EventType), zap.String("stream_id", req.StreamID), zap.String("listener_id", req.ListenerID), ) if h.liveStreamService != nil && req.StreamID != "" { streamID, err := uuid.Parse(req.StreamID) if err == nil { switch req.EventType { case "stream_started": if err := h.liveStreamService.SetIsLive(c.Request.Context(), streamID, true); err != nil { h.logger.Warn("Failed to set stream live", zap.Error(err), zap.String("stream_id", req.StreamID)) } case "stream_ended": if err := h.liveStreamService.SetIsLive(c.Request.Context(), streamID, false); err != nil { h.logger.Warn("Failed to set stream ended", zap.Error(err), zap.String("stream_id", req.StreamID)) } case "listener_joined": if err := h.liveStreamService.UpdateViewerCount(c.Request.Context(), streamID, 1); err != nil { h.logger.Warn("Failed to increment viewer count", zap.Error(err), zap.String("stream_id", req.StreamID)) } case "listener_left": if err := h.liveStreamService.UpdateViewerCount(c.Request.Context(), streamID, -1); err != nil { h.logger.Warn("Failed to decrement viewer count", zap.Error(err), zap.String("stream_id", req.StreamID)) } } } } c.JSON(http.StatusOK, gin.H{"message": "event received"}) }