42 lines
1.8 KiB
Python
42 lines
1.8 KiB
Python
"""时态纪念日模型(辰正 §5.3)。"""
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.core.ids import new_anniversary_id
|
|
from app.core.time import utc_now
|
|
from app.db.base import Base
|
|
|
|
|
|
class TimeAnniversary(Base):
|
|
"""纪念日 / 特殊日子(辰正设计 §5.3)。
|
|
|
|
枚举值(calendar / kind / subject_type / source)以契约字典
|
|
``docs/contracts/contract-glossary.md`` §11.4.1–§11.4.4 为单一事实源。
|
|
"""
|
|
|
|
__tablename__ = "time_anniversaries"
|
|
|
|
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_anniversary_id)
|
|
character_id: Mapped[str] = mapped_column(String(80), ForeignKey("characters.id"), index=True)
|
|
name: Mapped[str] = mapped_column(String(200), nullable=False)
|
|
calendar: Mapped[str] = mapped_column(String(20), nullable=False) # solar / lunar
|
|
date: Mapped[str] = mapped_column(String(20), nullable=False) # 公历 ISO 或农历日期编码
|
|
recurs_yearly: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
|
kind: Mapped[str] = mapped_column(
|
|
String(40), nullable=False
|
|
) # birthday / anniversary / milestone / custom
|
|
subject_type: Mapped[str] = mapped_column(
|
|
String(40), nullable=False
|
|
) # user / character_self / relationship / custom
|
|
source: Mapped[str] = mapped_column(
|
|
String(40), nullable=False, default="manual"
|
|
) # auto / manual / imported
|
|
metadata_json: Mapped[str] = mapped_column(Text, nullable=False, default="{}")
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), default=utc_now, onupdate=utc_now
|
|
)
|