131 lines
4.2 KiB
Python
131 lines
4.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import selectinload
|
|
import uuid
|
|
|
|
from app.api import deps
|
|
from app.core.database import get_db
|
|
from app.models.ticket import Ticket, TicketParticipant
|
|
from app.models.user import User
|
|
from pydantic import BaseModel
|
|
|
|
router = APIRouter()
|
|
|
|
class ParticipantAdd(BaseModel):
|
|
user_id: uuid.UUID
|
|
|
|
class ParticipantResponse(BaseModel):
|
|
id: uuid.UUID
|
|
user_id: uuid.UUID
|
|
ticket_id: uuid.UUID
|
|
role: str
|
|
user_email: str
|
|
user_name: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
@router.get("/{ticket_id}/participants", response_model=list[ParticipantResponse])
|
|
async def list_participants(
|
|
ticket_id: uuid.UUID,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(deps.get_current_user)
|
|
):
|
|
result = await db.execute(
|
|
select(TicketParticipant)
|
|
.where(TicketParticipant.ticket_id == ticket_id)
|
|
.options(selectinload(TicketParticipant.user))
|
|
)
|
|
participants = result.scalars().all()
|
|
return [
|
|
ParticipantResponse(
|
|
id=p.id,
|
|
user_id=p.user_id,
|
|
ticket_id=p.ticket_id,
|
|
role=p.role,
|
|
user_email=p.user.email,
|
|
user_name=f"{p.user.first_name or ''} {p.user.last_name or ''}".strip()
|
|
)
|
|
for p in participants
|
|
]
|
|
|
|
@router.post("/{ticket_id}/participants", response_model=ParticipantResponse)
|
|
async def add_participant(
|
|
ticket_id: uuid.UUID,
|
|
data: ParticipantAdd,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(deps.get_current_user)
|
|
):
|
|
# Verificar que el ticket existe
|
|
ticket_result = await db.execute(select(Ticket).where(Ticket.id == ticket_id))
|
|
ticket = ticket_result.scalar_one_or_none()
|
|
if not ticket:
|
|
raise HTTPException(status_code=404, detail="Ticket not found")
|
|
|
|
# Solo el creador puede agregar participantes
|
|
if ticket.created_by != current_user.id and not current_user.role.is_global:
|
|
raise HTTPException(status_code=403, detail="Only the ticket creator can add participants")
|
|
|
|
# Verificar que el usuario existe
|
|
user_result = await db.execute(select(User).where(User.id == data.user_id))
|
|
user = user_result.scalar_one_or_none()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
# Verificar que no sea duplicado
|
|
existing = await db.execute(
|
|
select(TicketParticipant).where(
|
|
TicketParticipant.ticket_id == ticket_id,
|
|
TicketParticipant.user_id == data.user_id
|
|
)
|
|
)
|
|
if existing.scalar_one_or_none():
|
|
raise HTTPException(status_code=400, detail="User is already a participant")
|
|
|
|
participant = TicketParticipant(
|
|
ticket_id=ticket_id,
|
|
user_id=data.user_id,
|
|
role="participant"
|
|
)
|
|
db.add(participant)
|
|
await db.commit()
|
|
await db.refresh(participant)
|
|
|
|
return ParticipantResponse(
|
|
id=participant.id,
|
|
user_id=participant.user_id,
|
|
ticket_id=participant.ticket_id,
|
|
role=participant.role,
|
|
user_email=user.email,
|
|
user_name=f"{user.first_name or ''} {user.last_name or ''}".strip()
|
|
)
|
|
|
|
@router.delete("/{ticket_id}/participants/{user_id}", status_code=204)
|
|
async def remove_participant(
|
|
ticket_id: uuid.UUID,
|
|
user_id: uuid.UUID,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(deps.get_current_user)
|
|
):
|
|
ticket_result = await db.execute(select(Ticket).where(Ticket.id == ticket_id))
|
|
ticket = ticket_result.scalar_one_or_none()
|
|
if not ticket:
|
|
raise HTTPException(status_code=404, detail="Ticket not found")
|
|
|
|
if ticket.created_by != current_user.id and not current_user.role.is_global:
|
|
raise HTTPException(status_code=403, detail="Only the ticket creator can remove participants")
|
|
|
|
result = await db.execute(
|
|
select(TicketParticipant).where(
|
|
TicketParticipant.ticket_id == ticket_id,
|
|
TicketParticipant.user_id == user_id
|
|
)
|
|
)
|
|
participant = result.scalar_one_or_none()
|
|
if not participant:
|
|
raise HTTPException(status_code=404, detail="Participant not found")
|
|
|
|
await db.delete(participant)
|
|
await db.commit()
|