from datetime import date, datetime, time from typing import Optional from sqlalchemy import ( JSON, BigInteger, Boolean, Date, DateTime, Index, Integer, Numeric, SmallInteger, String, Text, Time, UniqueConstraint, text, ) from sqlalchemy.orm import Mapped, mapped_column from app.models import Base class Parent(Base): __tablename__ = "parents" user_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) openid: Mapped[str] = mapped_column(String(64), unique=True, nullable=False) unionid: Mapped[Optional[str]] = mapped_column(String(64)) nickname: Mapped[Optional[str]] = mapped_column(String(64)) avatar_url: Mapped[Optional[str]] = mapped_column(String(255)) avatar_file_key: Mapped[Optional[str]] = mapped_column(String(255)) phone: Mapped[Optional[str]] = mapped_column(String(20)) status: Mapped[int] = mapped_column(Integer, server_default="1") created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class Child(Base): __tablename__ = "children" child_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) child_name: Mapped[str] = mapped_column(String(32), nullable=False) child_gender: Mapped[int] = mapped_column(Integer, server_default="2") child_birthday: Mapped[Optional[date]] = mapped_column(Date) status: Mapped[int] = mapped_column(Integer, server_default="1") created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class ParentChildRelation(Base): __tablename__ = "parent_child_relations" __table_args__ = ( UniqueConstraint("user_id", "child_id", name="uq_user_child"), Index("idx_pcr_user_id", "user_id"), Index("idx_pcr_child_id", "child_id"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) child_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) relation_type: Mapped[int] = mapped_column(Integer, server_default="9") is_primary: Mapped[bool] = mapped_column(Boolean, server_default="0") status: Mapped[int] = mapped_column(Integer, server_default="1") created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class DeviceBinding(Base): __tablename__ = "device_bindings" __table_args__ = ( UniqueConstraint("device_id", name="uq_device_binding_device"), UniqueConstraint("child_id", name="uq_device_binding_child"), Index("idx_device_bindings_owner_user_id", "owner_user_id"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) device_id: Mapped[str] = mapped_column(String(64), nullable=False, unique=True) owner_user_id: Mapped[int] = mapped_column(Integer, nullable=False) child_id: Mapped[Optional[int]] = mapped_column(Integer) status: Mapped[int] = mapped_column(Integer, server_default="1") bound_at: Mapped[datetime] = mapped_column(DateTime, nullable=False) unbound_at: Mapped[Optional[datetime]] = mapped_column(DateTime) created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class DeviceBindSession(Base): __tablename__ = "device_bind_sessions" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) bind_token: Mapped[str] = mapped_column(String(36), unique=True, nullable=False) device_id: Mapped[str] = mapped_column(String(64), nullable=False) initiator_user_id: Mapped[int] = mapped_column(Integer, nullable=False) target_child_id: Mapped[Optional[int]] = mapped_column(Integer) challenge_code_hash: Mapped[Optional[str]] = mapped_column(String(64)) challenge_set_at: Mapped[Optional[datetime]] = mapped_column(DateTime) expires_at: Mapped[datetime] = mapped_column(DateTime, nullable=False) max_attempt_count: Mapped[int] = mapped_column(Integer, server_default="5") attempt_count: Mapped[int] = mapped_column(Integer, server_default="0") status: Mapped[int] = mapped_column(Integer, server_default="1") bind_mode: Mapped[int] = mapped_column(Integer, server_default="1") card_uuid: Mapped[Optional[str]] = mapped_column(String(64)) confirmed_at: Mapped[Optional[datetime]] = mapped_column(DateTime) consumed_at: Mapped[Optional[datetime]] = mapped_column(DateTime) created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class DeviceBindHistory(Base): __tablename__ = "device_bind_history" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) device_id: Mapped[str] = mapped_column(String(64), nullable=False) child_id: Mapped[Optional[int]] = mapped_column(Integer) bound_by_user_id: Mapped[int] = mapped_column(Integer, nullable=False) unbound_by_user_id: Mapped[Optional[int]] = mapped_column(Integer) bind_source: Mapped[int] = mapped_column(Integer, server_default="1") bound_at: Mapped[datetime] = mapped_column(DateTime, nullable=False) unbound_at: Mapped[Optional[datetime]] = mapped_column(DateTime) unbind_reason: Mapped[Optional[str]] = mapped_column(String(191)) created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class Card(Base): __tablename__ = "cards" card_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) card_uuid: Mapped[str] = mapped_column(String(64), unique=True, nullable=False) device_id: Mapped[Optional[str]] = mapped_column(String(64)) card_name: Mapped[Optional[str]] = mapped_column(String(64)) status: Mapped[int] = mapped_column(Integer, server_default="0") total_swaps: Mapped[int] = mapped_column(Integer, server_default="0") created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) class DeviceSetting(Base): __tablename__ = "device_settings" setting_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) device_id: Mapped[str] = mapped_column(String(64), unique=True, nullable=False) sleep_mode: Mapped[int] = mapped_column(Integer, server_default="0") disable_time_start: Mapped[Optional[time]] = mapped_column(Time) disable_time_end: Mapped[Optional[time]] = mapped_column(Time) timezone: Mapped[str] = mapped_column(String(32), server_default=text("'Asia/Shanghai'")) volume: Mapped[Optional[int]] = mapped_column(Integer) brightness: Mapped[Optional[int]] = mapped_column(Integer) disable_weekdays: Mapped[Optional[str]] = mapped_column(String(32)) created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP")) updated_at: Mapped[Optional[datetime]] = mapped_column( DateTime, server_default=text("CURRENT_TIMESTAMP"), onupdate=datetime.utcnow, ) class IMConversation(Base): __tablename__ = "im_conversations" __table_args__ = ( UniqueConstraint("conversation_type", "pair_key", name="uq_conv_type_pair"), Index("idx_im_conv_participant_a", "participant_a_type", "participant_a_id"), Index("idx_im_conv_participant_b", "participant_b_type", "participant_b_id"), Index("idx_im_conv_last_message_at", "last_message_at"), ) id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) conversation_type: Mapped[int] = mapped_column(Integer, nullable=False) participant_a_type: Mapped[int] = mapped_column(Integer, nullable=False) participant_a_id: Mapped[str] = mapped_column(String(64), nullable=False) participant_b_type: Mapped[int] = mapped_column(Integer, nullable=False) participant_b_id: Mapped[str] = mapped_column(String(64), nullable=False) pair_key: Mapped[str] = mapped_column(String(191), nullable=False) status: Mapped[int] = mapped_column(Integer, default=1) last_seq: Mapped[int] = mapped_column(BigInteger, default=0, index=True) message_count: Mapped[int] = mapped_column(BigInteger, default=0) last_message_preview: Mapped[Optional[str]] = mapped_column(String(255)) last_message_at: Mapped[Optional[datetime]] = mapped_column(DateTime) ext_json: Mapped[Optional[dict]] = mapped_column(JSON) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow ) class IMMessage(Base): __tablename__ = "im_messages" __table_args__ = ( UniqueConstraint("conversation_id", "seq", name="uq_im_msg_conv_seq"), UniqueConstraint("conversation_id", "client_msg_id", name="uq_im_msg_client"), Index("idx_im_msg_sender", "sender_type", "sender_id", "created_at"), Index("idx_im_msg_receiver", "receiver_type", "receiver_id", "created_at"), ) id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) conversation_id: Mapped[int] = mapped_column(BigInteger, nullable=False) seq: Mapped[int] = mapped_column(BigInteger, nullable=False) sender_type: Mapped[int] = mapped_column(Integer, nullable=False) sender_id: Mapped[str] = mapped_column(String(64), nullable=False) receiver_type: Mapped[int] = mapped_column(Integer, nullable=False) receiver_id: Mapped[str] = mapped_column(String(64), nullable=False) content_type: Mapped[int] = mapped_column(Integer, nullable=False) content_text: Mapped[Optional[str]] = mapped_column(Text) content_json: Mapped[Optional[dict]] = mapped_column(JSON) media_file_key: Mapped[Optional[str]] = mapped_column(String(255)) media_duration_ms: Mapped[Optional[int]] = mapped_column(Integer) media_mime_type: Mapped[Optional[str]] = mapped_column(String(64)) media_size_bytes: Mapped[Optional[int]] = mapped_column(BigInteger) media_transcript_text: Mapped[Optional[str]] = mapped_column(Text) client_msg_id: Mapped[Optional[str]] = mapped_column(String(64)) sender_name_snapshot: Mapped[Optional[str]] = mapped_column(String(64)) sender_avatar_snapshot: Mapped[Optional[str]] = mapped_column(String(255)) receiver_name_snapshot: Mapped[Optional[str]] = mapped_column(String(64)) receiver_avatar_snapshot: Mapped[Optional[str]] = mapped_column(String(255)) ext_json: Mapped[Optional[dict]] = mapped_column(JSON) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime) class ChildLocationCurrent(Base): __tablename__ = "child_location_current" child_id: Mapped[int] = mapped_column(BigInteger, primary_key=True) device_id: Mapped[str] = mapped_column(String(64), nullable=False) coord_type: Mapped[str] = mapped_column(String(16), default="gcj02") lat: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False) lng: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False) accuracy_m: Mapped[Optional[int]] = mapped_column(Integer) altitude_m: Mapped[Optional[float]] = mapped_column(Numeric(8, 2)) speed_mps: Mapped[Optional[float]] = mapped_column(Numeric(8, 2)) heading_deg: Mapped[Optional[int]] = mapped_column(SmallInteger) source: Mapped[int] = mapped_column(Integer, nullable=False) battery_pct: Mapped[Optional[int]] = mapped_column(Integer) device_time: Mapped[datetime] = mapped_column(DateTime, nullable=False) server_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow ) class ChildLocationHistory(Base): __tablename__ = "child_location_history" __table_args__ = ( Index("idx_child_loc_hist_child", "child_id", "created_at"), ) id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) child_id: Mapped[int] = mapped_column(BigInteger, nullable=False) device_id: Mapped[str] = mapped_column(String(64), nullable=False) coord_type: Mapped[str] = mapped_column(String(16), default="gcj02") lat: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False) lng: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False) accuracy_m: Mapped[Optional[int]] = mapped_column(Integer) altitude_m: Mapped[Optional[float]] = mapped_column(Numeric(8, 2)) speed_mps: Mapped[Optional[float]] = mapped_column(Numeric(8, 2)) heading_deg: Mapped[Optional[int]] = mapped_column(SmallInteger) source: Mapped[int] = mapped_column(Integer, nullable=False) battery_pct: Mapped[Optional[int]] = mapped_column(Integer) device_time: Mapped[datetime] = mapped_column(DateTime, nullable=False) server_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)