UMBRA/backend/app/schemas/event_invitation.py
Kyle Pope df857a5719 Fix QA findings: flush before notify, dedup RSVP, sa_false, validation
- C-02: flush invitations before creating notifications so invitation_id
  is available in notification data; eliminates extra pending fetch
- C-03: skip RSVP notification when status hasn't changed
- C-01: add defensive comments on update/delete endpoints
- W-01: add ge=1, le=2147483647 per-element validation on user_ids
- W-04: deduplicate invited_event_ids query via get_invited_event_ids()
- W-06: replace Python False with sa_false() in or_() clauses
- Frontend: extract resolveInvitationId helper, prefer data.invitation_id

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:01:15 +08:00

33 lines
957 B
Python

from typing import Annotated, Literal, Optional
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
class EventInvitationCreate(BaseModel):
model_config = ConfigDict(extra="forbid")
user_ids: list[Annotated[int, Field(ge=1, le=2147483647)]] = Field(..., min_length=1, max_length=20)
class EventInvitationRespond(BaseModel):
model_config = ConfigDict(extra="forbid")
status: Literal["accepted", "tentative", "declined"]
class EventInvitationOverrideCreate(BaseModel):
model_config = ConfigDict(extra="forbid")
status: Literal["accepted", "tentative", "declined"]
class EventInvitationResponse(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
event_id: int
user_id: int
invited_by: Optional[int]
status: str
invited_at: datetime
responded_at: Optional[datetime]
invitee_name: Optional[str] = None
invitee_umbral_name: Optional[str] = None