Compare commits

...

2 commits

View file

@ -1,8 +1,8 @@
from datetime import UTC, datetime from datetime import UTC, datetime
from typing import Literal, cast, final, overload from typing import Annotated, Literal, cast, final, overload
from beanie import Link, PydanticObjectId from beanie import Link, PydanticObjectId
from fastapi import APIRouter, HTTPException, Response, status from fastapi import APIRouter, HTTPException, Query, Response, status
from pydantic import BaseModel from pydantic import BaseModel
from src.db.models.event import Event from src.db.models.event import Event
@ -153,11 +153,14 @@ async def get_user_invitatinos(user_id: PydanticObjectId, user: CurrentUserDep)
@base_router.get("/users/{user_id}/invitations/incoming") @base_router.get("/users/{user_id}/invitations/incoming")
async def get_user_incoming_invitatinos(user_id: PydanticObjectId, user: CurrentUserDep) -> list[InvitationData]: async def get_user_incoming_invitatinos(
user_id: PydanticObjectId,
user: CurrentUserDep,
invite_status: Annotated[Literal["pending", "accepted", "declined"] | None, Query()] = None,
) -> list[InvitationData]:
"""Get all incoming invitations for a given user. """Get all incoming invitations for a given user.
Note that this endpoint only allows you to access the invitations you received. Note that this endpoint only allows you to access the invitations you received.
Only invitations with status "pending" are returned.
""" """
if user.id is None: if user.id is None:
raise MissingIdError(user) raise MissingIdError(user)
@ -165,11 +168,12 @@ async def get_user_incoming_invitatinos(user_id: PydanticObjectId, user: Current
if user.id != user_id: if user.id != user_id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You can only access your own invitations.") raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You can only access your own invitations.")
invitations = await Invitation.find( query = Invitation.find(expr(Invitation.invitee).id == user_id)
expr(Invitation.invitee).id == user_id, if invite_status is not None:
Invitation.status == "pending", query = query.find(Invitation.status == invite_status)
fetch_links=True, query = query.find(fetch_links=True)
).to_list()
invitations = await query.to_list()
return [InvitationData.from_invitation(invitation) for invitation in invitations] return [InvitationData.from_invitation(invitation) for invitation in invitations]
@ -220,7 +224,7 @@ async def delete_invitation(invitation_id: PydanticObjectId, user: CurrentUserDe
@invitations_router.post("/{invitation_id}/accept") @invitations_router.post("/{invitation_id}/accept")
async def accept_invitation(invitation_id: PydanticObjectId, user: CurrentUserDep) -> Response: async def accept_invitation(invitation_id: PydanticObjectId, user: CurrentUserDep) -> InvitationData:
"""Accept an invitation.""" """Accept an invitation."""
invitation = await Invitation.get(invitation_id, fetch_links=True) invitation = await Invitation.get(invitation_id, fetch_links=True)
if invitation is None: if invitation is None:
@ -238,7 +242,7 @@ async def accept_invitation(invitation_id: PydanticObjectId, user: CurrentUserDe
# Mark the invitation as accepted # Mark the invitation as accepted
invitation.status = "accepted" invitation.status = "accepted"
invitation.responded_at = datetime.now(tz=UTC) invitation.responded_at = datetime.now(tz=UTC)
_ = await invitation.save() _ = await invitation.replace()
# Add the user to the event # Add the user to the event
event = invitation.event event = invitation.event
@ -258,11 +262,11 @@ async def accept_invitation(invitation_id: PydanticObjectId, user: CurrentUserDe
) )
notification = await notification.create() notification = await notification.create()
return Response(status_code=status.HTTP_204_NO_CONTENT) return InvitationData.from_invitation(invitation)
@invitations_router.post("/{invitation_id}/decline") @invitations_router.post("/{invitation_id}/decline")
async def decline_invitation(invitation_id: PydanticObjectId, user: CurrentUserDep) -> Response: async def decline_invitation(invitation_id: PydanticObjectId, user: CurrentUserDep) -> InvitationData:
"""Decline an invitation.""" """Decline an invitation."""
invitation = await Invitation.get(invitation_id, fetch_links=True) invitation = await Invitation.get(invitation_id, fetch_links=True)
if invitation is None: if invitation is None:
@ -279,7 +283,7 @@ async def decline_invitation(invitation_id: PydanticObjectId, user: CurrentUserD
invitation.status = "declined" invitation.status = "declined"
invitation.responded_at = datetime.now(tz=UTC) invitation.responded_at = datetime.now(tz=UTC)
_ = await invitation.save() _ = await invitation.replace()
# Send back a notification to the invitor about the decline # Send back a notification to the invitor about the decline
notification = Notification( notification = Notification(
@ -291,7 +295,7 @@ async def decline_invitation(invitation_id: PydanticObjectId, user: CurrentUserD
) )
notification = await notification.create() notification = await notification.create()
return Response(status_code=status.HTTP_204_NO_CONTENT) return InvitationData.from_invitation(invitation)
router = APIRouter() router = APIRouter()