UMBRA/backend/app/schemas/event_invitation.py
Kyle Pope 925c9caf91 Fix QA and pentest findings for event invitations
C-01: Use func.count() for invitation cap instead of loading all rows
C-02: Remove unused display_calendar_id from EventInvitationResponse
F-01: Add field allowlist for invited editors (blocks is_starred,
      recurrence_rule, calendar_id mutations)
W-02: Memoize existingInviteeIds Set in EventDetailPanel
W-03: Block per-occurrence overrides on declined/pending invitations
S-01: Make can_modify non-optional in EventInvitation TypeScript type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:28:01 +08:00

44 lines
1.2 KiB
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 UpdateDisplayCalendar(BaseModel):
model_config = ConfigDict(extra="forbid")
calendar_id: Annotated[int, Field(ge=1, le=2147483647)]
class UpdateCanModify(BaseModel):
model_config = ConfigDict(extra="forbid")
can_modify: bool
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
can_modify: bool = False