56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
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"}},
|
|
),
|
|
]
|