Update server with new guest rsvp endpoint
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from app.schemas.guests import GuestCreate, GuestUpdate, GuestRead
|
from app.schemas.guests import GuestCreate, GuestUpdate, GuestRead, GuestWithRSVPResponse, map_rsvp_status_to_guest_status
|
||||||
from app.crud.guest import guest_crud
|
from app.crud.guest import guest_crud
|
||||||
from typing import List
|
from typing import List
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from app.core.database import get_db
|
from app.core.database import get_db
|
||||||
from app.models import GuestStatus
|
from app.models import GuestStatus
|
||||||
|
from app.crud.rsvp import crud_rsvp
|
||||||
|
from app.schemas.rsvp import RSVPSchemaCreate
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@@ -57,9 +59,45 @@ def delete_guest(guest_id: uuid.UUID, db: Session = Depends(get_db)):
|
|||||||
return guest
|
return guest
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/{guest_id}/status", response_model=GuestRead)
|
@router.patch("/{guest_id}/status", response_model=GuestRead, operation_id='set_guest_status')
|
||||||
def set_guest_status(guest_id: uuid.UUID, status: GuestStatus, db: Session = Depends(get_db)):
|
def set_guest_status(guest_id: uuid.UUID, status: GuestStatus, db: Session = Depends(get_db)):
|
||||||
guest = guest_crud.update_status(db, guest_id=guest_id, status=status)
|
guest = guest_crud.update_status(db, guest_id=guest_id, status=status)
|
||||||
if not guest:
|
if not guest:
|
||||||
raise HTTPException(status_code=404, detail="Guest not found")
|
raise HTTPException(status_code=404, detail="Guest not found")
|
||||||
return guest
|
return guest
|
||||||
|
|
||||||
|
@router.post("/{guest_id}/rsvp", response_model=GuestWithRSVPResponse, operation_id='create_guest_rsvp')
|
||||||
|
def process_guest_rsvp(
|
||||||
|
guest_id: uuid.UUID,
|
||||||
|
rsvp_data: RSVPSchemaCreate,
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
# Start a transaction
|
||||||
|
try:
|
||||||
|
# Update or create RSVP
|
||||||
|
existing_rsvp = crud_rsvp.get_rsvp_by_event_and_guest(
|
||||||
|
db, event_id=rsvp_data.event_id, guest_id=guest_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if existing_rsvp:
|
||||||
|
rsvp = crud_rsvp.update(db, db_obj=existing_rsvp, obj_in=rsvp_data)
|
||||||
|
else:
|
||||||
|
rsvp_data.guest_id = guest_id # Ensure guest_id matches URL
|
||||||
|
rsvp = crud_rsvp.create(db, obj_in=rsvp_data)
|
||||||
|
|
||||||
|
# Update guest status to match RSVP
|
||||||
|
guest_status = map_rsvp_status_to_guest_status(rsvp_data.status)
|
||||||
|
guest = guest_crud.update_status(db, guest_id=guest_id, status=guest_status)
|
||||||
|
|
||||||
|
# Both operations succeeded, commit the transaction
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Return combined response
|
||||||
|
return {
|
||||||
|
"guest": guest,
|
||||||
|
"rsvp": rsvp
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(status_code=500, detail=f"Failed to process RSVP: {str(e)}")
|
||||||
@@ -6,6 +6,9 @@ from typing import Optional, Any, Dict
|
|||||||
from app.models.guest import GuestStatus
|
from app.models.guest import GuestStatus
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from app.schemas.rsvp import RSVPSchema, RSVPStatus
|
||||||
|
|
||||||
|
|
||||||
class GuestBase(BaseModel):
|
class GuestBase(BaseModel):
|
||||||
event_id: UUID
|
event_id: UUID
|
||||||
invited_by: UUID
|
invited_by: UUID
|
||||||
@@ -46,4 +49,25 @@ class GuestRead(GuestBase):
|
|||||||
actual_additional_guests: int
|
actual_additional_guests: int
|
||||||
is_blocked: bool
|
is_blocked: bool
|
||||||
model_config = ConfigDict(from_attributes=True)
|
model_config = ConfigDict(from_attributes=True)
|
||||||
invitation_code: str
|
invitation_code: str
|
||||||
|
|
||||||
|
class GuestWithRSVPResponse(BaseModel):
|
||||||
|
"""
|
||||||
|
Combined response model that includes both guest and RSVP information.
|
||||||
|
This gives the frontend a complete picture of the guest's response in a single object.
|
||||||
|
"""
|
||||||
|
guest: GuestRead
|
||||||
|
rsvp: Optional[RSVPSchema] = None
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
from_attributes = True
|
||||||
|
|
||||||
|
def map_rsvp_status_to_guest_status(rsvp_status: RSVPStatus) -> GuestStatus:
|
||||||
|
if rsvp_status == RSVPStatus.ATTENDING:
|
||||||
|
return GuestStatus.CONFIRMED
|
||||||
|
elif rsvp_status == RSVPStatus.NOT_ATTENDING:
|
||||||
|
return GuestStatus.DECLINED
|
||||||
|
elif rsvp_status == RSVPStatus.MAYBE:
|
||||||
|
return GuestStatus.PENDING
|
||||||
|
else:
|
||||||
|
return GuestStatus.INVITED
|
||||||
Reference in New Issue
Block a user