[BE-API-011] be-api: Implement conversation participants endpoints
- Added RemoveMember method to RoomService and RoomServiceInterface - Corrected RemoveMember in RoomRepository to use uuid.UUID - Added AddParticipant and RemoveParticipant handlers - Added POST /conversations/:id/participants route - Added DELETE /conversations/:id/participants/:userId route - Handlers use standard API response format - Handlers reuse AddMember/RemoveMember service methods Phase: PHASE-2 Priority: P1 Progress: 20/267 (7.5%)
This commit is contained in:
parent
358dd68397
commit
74ff4053ab
5 changed files with 128 additions and 2 deletions
|
|
@ -1600,7 +1600,20 @@
|
|||
"description": "POST /api/v1/conversations/:id/participants and DELETE /api/v1/conversations/:id/participants/:userId",
|
||||
"owner": "backend",
|
||||
"estimated_hours": 3,
|
||||
"status": "todo",
|
||||
"status": "completed",
|
||||
"completion": {
|
||||
"completed_at": "2025-12-23T09:48:25Z",
|
||||
"actual_hours": 0.75,
|
||||
"commits": [],
|
||||
"files_changed": [
|
||||
"veza-backend-api/internal/repositories/room_repository.go",
|
||||
"veza-backend-api/internal/services/room_service.go",
|
||||
"veza-backend-api/internal/handlers/room_handler.go",
|
||||
"veza-backend-api/internal/api/router.go"
|
||||
],
|
||||
"notes": "Added RemoveMember method to RoomService and RoomServiceInterface. Corrected RemoveMember in RoomRepository to use uuid.UUID instead of int64. Added AddParticipant and RemoveParticipant handlers in RoomHandler. Added POST /conversations/:id/participants and DELETE /conversations/:id/participants/:userId routes. Handlers use standard API response format (RespondSuccess, RespondWithAppError). Handlers reuse AddMember/RemoveMember service methods.",
|
||||
"issues_encountered": []
|
||||
},
|
||||
"files_involved": [],
|
||||
"implementation_steps": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -865,6 +865,8 @@ func (r *APIRouter) setupCoreProtectedRoutes(v1 *gin.RouterGroup) {
|
|||
conversations.GET("/:id", roomHandler.GetRoom)
|
||||
conversations.DELETE("/:id", roomHandler.DeleteRoom) // BE-API-010: Delete conversation endpoint
|
||||
conversations.POST("/:id/members", roomHandler.AddMember)
|
||||
conversations.POST("/:id/participants", roomHandler.AddParticipant) // BE-API-011: Add participant endpoint
|
||||
conversations.DELETE("/:id/participants/:userId", roomHandler.RemoveParticipant) // BE-API-011: Remove participant endpoint
|
||||
conversations.GET("/:id/history", roomHandler.GetRoomHistory)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ type RoomServiceInterface interface {
|
|||
GetUserRooms(ctx context.Context, userID uuid.UUID) ([]*services.RoomResponse, error)
|
||||
GetRoom(ctx context.Context, roomID uuid.UUID) (*services.RoomResponse, error)
|
||||
AddMember(ctx context.Context, roomID, userID uuid.UUID) error
|
||||
RemoveMember(ctx context.Context, roomID, userID uuid.UUID) error // BE-API-011: Remove member method
|
||||
GetRoomHistory(ctx context.Context, roomID uuid.UUID, limit, offset int) ([]services.ChatMessageResponse, error)
|
||||
DeleteRoom(ctx context.Context, roomID uuid.UUID, userID uuid.UUID) error // BE-API-010: Delete room method
|
||||
}
|
||||
|
|
@ -270,3 +271,84 @@ func (h *RoomHandler) DeleteRoom(c *gin.Context) {
|
|||
|
||||
RespondSuccess(c, http.StatusOK, gin.H{"message": "Conversation deleted successfully"})
|
||||
}
|
||||
|
||||
// AddParticipant ajoute un participant à une conversation
|
||||
// POST /api/v1/conversations/:id/participants
|
||||
// BE-API-011: Implement conversation participants endpoints
|
||||
func (h *RoomHandler) AddParticipant(c *gin.Context) {
|
||||
// Récupérer l'ID de la room depuis l'URL
|
||||
roomIDStr := c.Param("id")
|
||||
roomID, err := uuid.Parse(roomIDStr)
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.NewValidationError("invalid room id"))
|
||||
return
|
||||
}
|
||||
|
||||
// Parser la requête
|
||||
var req AddMemberRequest
|
||||
if appErr := h.commonHandler.BindAndValidateJSON(c, &req); appErr != nil {
|
||||
RespondWithAppError(c, appErr)
|
||||
return
|
||||
}
|
||||
|
||||
// Ajouter le participant (utilise la même logique que AddMember)
|
||||
if err := h.roomService.AddMember(c.Request.Context(), roomID, req.UserID); err != nil {
|
||||
if errors.Is(err, services.ErrRoomNotFound) {
|
||||
RespondWithAppError(c, apperrors.NewNotFoundError("conversation"))
|
||||
return
|
||||
}
|
||||
h.logger.Error("failed to add participant to room",
|
||||
zap.Error(err),
|
||||
zap.String("room_id", roomID.String()),
|
||||
zap.String("user_id", req.UserID.String()))
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to add participant", err))
|
||||
return
|
||||
}
|
||||
|
||||
h.logger.Info("participant added to room",
|
||||
zap.String("room_id", roomID.String()),
|
||||
zap.String("user_id", req.UserID.String()))
|
||||
|
||||
RespondSuccess(c, http.StatusOK, gin.H{"message": "Participant added successfully"})
|
||||
}
|
||||
|
||||
// RemoveParticipant retire un participant d'une conversation
|
||||
// DELETE /api/v1/conversations/:id/participants/:userId
|
||||
// BE-API-011: Implement conversation participants endpoints
|
||||
func (h *RoomHandler) RemoveParticipant(c *gin.Context) {
|
||||
// Récupérer l'ID de la room depuis l'URL
|
||||
roomIDStr := c.Param("id")
|
||||
roomID, err := uuid.Parse(roomIDStr)
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.NewValidationError("invalid room id"))
|
||||
return
|
||||
}
|
||||
|
||||
// Récupérer l'ID de l'utilisateur depuis l'URL
|
||||
userIDStr := c.Param("userId")
|
||||
userID, err := uuid.Parse(userIDStr)
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.NewValidationError("invalid user id"))
|
||||
return
|
||||
}
|
||||
|
||||
// Retirer le participant
|
||||
if err := h.roomService.RemoveMember(c.Request.Context(), roomID, userID); err != nil {
|
||||
if errors.Is(err, services.ErrRoomNotFound) {
|
||||
RespondWithAppError(c, apperrors.NewNotFoundError("conversation"))
|
||||
return
|
||||
}
|
||||
h.logger.Error("failed to remove participant from room",
|
||||
zap.Error(err),
|
||||
zap.String("room_id", roomID.String()),
|
||||
zap.String("user_id", userID.String()))
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to remove participant", err))
|
||||
return
|
||||
}
|
||||
|
||||
h.logger.Info("participant removed from room",
|
||||
zap.String("room_id", roomID.String()),
|
||||
zap.String("user_id", userID.String()))
|
||||
|
||||
RespondSuccess(c, http.StatusOK, gin.H{"message": "Participant removed successfully"})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ func (r *RoomRepository) AddMember(ctx context.Context, member *models.RoomMembe
|
|||
}
|
||||
|
||||
// RemoveMember retire un membre d'une room
|
||||
func (r *RoomRepository) RemoveMember(ctx context.Context, roomID uuid.UUID, userID int64) error {
|
||||
// MIGRATION UUID: userID migré vers uuid.UUID
|
||||
func (r *RoomRepository) RemoveMember(ctx context.Context, roomID uuid.UUID, userID uuid.UUID) error {
|
||||
return r.db.WithContext(ctx).
|
||||
Where("room_id = ? AND user_id = ?", roomID, userID).
|
||||
Delete(&models.RoomMember{}).Error
|
||||
|
|
|
|||
|
|
@ -217,6 +217,34 @@ func (s *RoomService) AddMember(ctx context.Context, roomID uuid.UUID, userID uu
|
|||
return nil
|
||||
}
|
||||
|
||||
// RemoveMember retire un membre d'une room
|
||||
// BE-API-011: Implement conversation participants endpoints
|
||||
func (s *RoomService) RemoveMember(ctx context.Context, roomID uuid.UUID, userID uuid.UUID) error {
|
||||
// Vérifier que la room existe
|
||||
_, err := s.roomRepo.GetByID(ctx, roomID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrRoomNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to get room: %w", err)
|
||||
}
|
||||
|
||||
// Retirer le membre
|
||||
if err := s.roomRepo.RemoveMember(ctx, roomID, userID); err != nil {
|
||||
s.logger.Error("failed to remove member from room",
|
||||
zap.Error(err),
|
||||
zap.String("room_id", roomID.String()),
|
||||
zap.String("user_id", userID.String()))
|
||||
return fmt.Errorf("failed to remove member: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("member removed from room",
|
||||
zap.String("room_id", roomID.String()),
|
||||
zap.String("user_id", userID.String()))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChatMessageResponse pour la réponse d'historique
|
||||
type ChatMessageResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
|
|
|
|||
Loading…
Reference in a new issue