veza/veza-backend-api/internal/websocket/chat/handler_rooms.go
senke c7fb240dc3 feat(chat): Sprint 3 -- message handlers, real-time features, permissions
- Implement full MessageHandler dispatch with all 18 incoming message types
- Add handler_messages.go: SendMessage, EditMessage, DeleteMessage with ownership checks
- Add handler_rooms.go: JoinConversation, LeaveConversation
- Add handler_history.go: FetchHistory (cursor-based), SearchMessages (ILIKE), SyncMessages
- Add handler_realtime.go: Typing, MarkAsRead, Delivered, AddReaction, RemoveReaction
- Add handler_calls.go: WebRTC signaling relay (CallOffer/Answer/ICE/Hangup/Reject)
- Add PermissionService: CanRead/CanSend/CanJoin/CanModerate based on room_members
- Add RateLimiter: per-user per-action sliding window (in-memory)
- Wire all dependencies in router.go setupChatWebSocket
2026-02-22 20:43:44 +01:00

42 lines
1.2 KiB
Go

package chat
import (
"context"
"go.uber.org/zap"
)
func (h *MessageHandler) HandleJoinConversation(ctx context.Context, client *Client, msg *IncomingMessage) {
if msg.ConversationID == nil {
client.SendJSON(NewErrorResponse("conversation_id is required"))
return
}
if !h.permissions.CanJoin(ctx, client.UserID, *msg.ConversationID) {
client.SendJSON(NewErrorResponse("not allowed to join this conversation"))
return
}
h.hub.JoinRoom(client, *msg.ConversationID)
h.logger.Info("User joined conversation",
zap.String("user_id", client.UserID.String()),
zap.String("conversation_id", msg.ConversationID.String()))
client.SendJSON(NewActionConfirmedResponse("joined_conversation", true))
}
func (h *MessageHandler) HandleLeaveConversation(ctx context.Context, client *Client, msg *IncomingMessage) {
if msg.ConversationID == nil {
client.SendJSON(NewErrorResponse("conversation_id is required"))
return
}
h.hub.LeaveRoom(client, *msg.ConversationID)
h.logger.Info("User left conversation",
zap.String("user_id", client.UserID.String()),
zap.String("conversation_id", msg.ConversationID.String()))
client.SendJSON(NewActionConfirmedResponse("left_conversation", true))
}