191 lines
4.6 KiB
Python
191 lines
4.6 KiB
Python
from pydantic import BaseModel, EmailStr, Field
|
|
from typing import Optional, List
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
|
|
# ============================================
|
|
# User Schemas
|
|
# ============================================
|
|
class UserBase(BaseModel):
|
|
email: EmailStr
|
|
|
|
|
|
class UserCreate(UserBase):
|
|
pass
|
|
|
|
|
|
class User(UserBase):
|
|
id: UUID
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============================================
|
|
# Event Schemas
|
|
# ============================================
|
|
class EventBase(BaseModel):
|
|
name: str
|
|
date: Optional[datetime] = None
|
|
location: Optional[str] = None
|
|
|
|
|
|
class EventCreate(EventBase):
|
|
pass
|
|
|
|
|
|
class EventUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
date: Optional[datetime] = None
|
|
location: Optional[str] = None
|
|
|
|
|
|
class Event(EventBase):
|
|
id: UUID
|
|
created_at: datetime
|
|
updated_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class EventWithMembers(Event):
|
|
members: List["EventMember"] = []
|
|
|
|
|
|
# ============================================
|
|
# Event Member Schemas
|
|
# ============================================
|
|
class EventMemberBase(BaseModel):
|
|
role: str = "admin" # admin, editor, viewer
|
|
display_name: Optional[str] = None
|
|
|
|
|
|
class EventMemberCreate(BaseModel):
|
|
user_email: str = Field(..., description="Email address of the user to invite")
|
|
role: str = "admin"
|
|
display_name: Optional[str] = None
|
|
|
|
|
|
class EventMember(EventMemberBase):
|
|
id: UUID
|
|
event_id: UUID
|
|
user_id: UUID
|
|
created_at: datetime
|
|
user: Optional[User] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============================================
|
|
# Guest Schemas
|
|
# ============================================
|
|
class GuestBase(BaseModel):
|
|
first_name: str
|
|
last_name: str
|
|
email: Optional[str] = None
|
|
phone_number: Optional[str] = None
|
|
rsvp_status: str = "invited" # invited, confirmed, declined
|
|
meal_preference: Optional[str] = None
|
|
has_plus_one: bool = False
|
|
plus_one_name: Optional[str] = None
|
|
table_number: Optional[str] = None
|
|
side: Optional[str] = None # e.g., "groom side", "bride side"
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class GuestCreate(GuestBase):
|
|
pass
|
|
|
|
|
|
class GuestUpdate(BaseModel):
|
|
first_name: Optional[str] = None
|
|
last_name: Optional[str] = None
|
|
email: Optional[str] = None
|
|
phone_number: Optional[str] = None
|
|
rsvp_status: Optional[str] = None
|
|
meal_preference: Optional[str] = None
|
|
has_plus_one: Optional[bool] = None
|
|
plus_one_name: Optional[str] = None
|
|
table_number: Optional[str] = None
|
|
side: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class Guest(GuestBase):
|
|
id: UUID
|
|
event_id: UUID
|
|
added_by_user_id: UUID
|
|
owner_email: Optional[str] = None
|
|
source: str = "manual"
|
|
created_at: datetime
|
|
updated_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============================================
|
|
# Bulk Import Schemas
|
|
# ============================================
|
|
class GuestImportItem(BaseModel):
|
|
first_name: str
|
|
last_name: str
|
|
email: Optional[str] = None
|
|
phone_number: Optional[str] = None
|
|
side: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class GuestBulkImport(BaseModel):
|
|
guests: List[GuestImportItem]
|
|
|
|
|
|
# ============================================
|
|
# Filter/Search Schemas
|
|
# ============================================
|
|
class GuestFilter(BaseModel):
|
|
search: Optional[str] = None
|
|
side: Optional[str] = None
|
|
status: Optional[str] = None
|
|
added_by: Optional[str] = None # "me" for current user
|
|
|
|
|
|
# ============================================
|
|
# WhatsApp Schemas
|
|
# ============================================
|
|
class WhatsAppMessage(BaseModel):
|
|
message: str
|
|
phone: Optional[str] = None # Optional: override guest's phone
|
|
|
|
|
|
class WhatsAppStatus(BaseModel):
|
|
message_id: str
|
|
status: str
|
|
timestamp: datetime
|
|
|
|
|
|
# ============================================
|
|
# Google Contacts Import Schema
|
|
# ============================================
|
|
class GoogleContactsImport(BaseModel):
|
|
access_token: str
|
|
owner: Optional[str] = "Google Import"
|
|
|
|
|
|
# ============================================
|
|
# Public Guest Self-Service Schema
|
|
# ============================================
|
|
class GuestPublicUpdate(BaseModel):
|
|
"""Schema for public guest self-service updates (phone-based lookup)"""
|
|
first_name: Optional[str] = None
|
|
last_name: Optional[str] = None
|
|
rsvp_status: Optional[str] = None
|
|
meal_preference: Optional[str] = None
|
|
has_plus_one: Optional[bool] = None
|
|
plus_one_name: Optional[str] = None
|
|
|