from datetime import datetime, timezone from typing import Optional from beanie import Document from pymongo import IndexModel, ASCENDING from pydantic import BaseModel, Field class EmergencyContact(BaseModel): name: str = "" relation: str = "" phone: str = "" class User(Document): openid: str = Field(..., unique=True) union_id: Optional[str] = None session_key: Optional[str] = None # Basic info name: str = "" phone: Optional[str] = None age: Optional[int] = None height: Optional[float] = None # cm pre_pregnancy_weight: Optional[float] = None # kg current_weight: Optional[float] = None # kg blood_type: Optional[str] = None allergies: list[str] = Field(default_factory=list) medical_history: list[str] = Field(default_factory=list) # Pregnancy info last_period_date: Optional[datetime] = None due_date: Optional[datetime] = None pregnancy_week: Optional[int] = None pregnancy_day: Optional[int] = None multiple_pregnancy: Optional[str] = None # 单胎/双胎/三胎+ pregnancy_count: Optional[int] = None # 第几次怀孕 emergency_contact: EmergencyContact = Field(default_factory=EmergencyContact) # Status is_onboarded: bool = False avatar_url: Optional[str] = None created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) class Settings: name = "users" indexes = [ IndexModel( [("phone", ASCENDING)], unique=True, partialFilterExpression={"phone": {"$type": "string"}}, ), ]