96 lines
2.6 KiB
Python
96 lines
2.6 KiB
Python
from __future__ import annotations
|
||
|
||
from datetime import datetime
|
||
from typing import Literal, Optional
|
||
|
||
from sqlalchemy import (
|
||
JSON,
|
||
Boolean,
|
||
DateTime,
|
||
Enum,
|
||
ForeignKey,
|
||
Index,
|
||
Numeric,
|
||
func,
|
||
)
|
||
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
||
from app.db.base import Base
|
||
|
||
ContentStage = Literal["general", "expecting", "parenting", "unknown"]
|
||
|
||
|
||
class ContentProfile(Base):
|
||
"""
|
||
内容画像表(Content Profile / Cᵢ)。
|
||
|
||
字段语义必须严格对齐:
|
||
- `设计说明文档/句子文案打分規則.md`
|
||
"""
|
||
|
||
__tablename__ = "content_profiles"
|
||
|
||
__table_args__ = (
|
||
Index("idx_profiles_stage", "stage"),
|
||
Index("idx_profiles_personalization_power", "personalization_power"),
|
||
Index("idx_profiles_is_safe_pool", "is_safe_pool"),
|
||
)
|
||
|
||
content_id: Mapped[int] = mapped_column(
|
||
ForeignKey("contents.content_id", ondelete="CASCADE"),
|
||
primary_key=True,
|
||
comment="FK -> contents.content_id",
|
||
)
|
||
|
||
stage: Mapped[ContentStage] = mapped_column(
|
||
Enum("general", "expecting", "parenting", "unknown", name="content_stage"),
|
||
nullable=False,
|
||
server_default="general",
|
||
comment="母职阶段定位(general/expecting/parenting/unknown)",
|
||
)
|
||
|
||
emotion_score: Mapped[Optional[float]] = mapped_column(
|
||
Numeric(3, 2),
|
||
nullable=True,
|
||
comment="情绪调性 0~1;NULL 表示 general",
|
||
)
|
||
|
||
context_suitability_json: Mapped[dict] = mapped_column(
|
||
JSON,
|
||
nullable=False,
|
||
comment="各 context 的适配度(JSON:0/0.5/1;必须包含 5 个 key)",
|
||
)
|
||
need_suitability_json: Mapped[dict] = mapped_column(
|
||
JSON,
|
||
nullable=False,
|
||
comment="各 need 的适配度(JSON:0/0.5/1;必须包含 5 个 key)",
|
||
)
|
||
|
||
personalization_power: Mapped[int] = mapped_column(
|
||
nullable=False,
|
||
server_default="0",
|
||
comment="个性化力度(约定只允许 0/5/10,分别映射 0/0.5/1)",
|
||
)
|
||
|
||
review_confidence: Mapped[Optional[float]] = mapped_column(
|
||
Numeric(3, 2),
|
||
nullable=True,
|
||
comment="标注置信度 0~1;NULL 表示由推荐侧按 0.7 兜底",
|
||
)
|
||
|
||
is_safe_pool: Mapped[bool] = mapped_column(
|
||
Boolean,
|
||
nullable=False,
|
||
server_default="0",
|
||
comment="是否属于通用安全池(L3 兜底)",
|
||
)
|
||
|
||
updated_at: Mapped[datetime] = mapped_column(
|
||
DateTime,
|
||
nullable=False,
|
||
server_default=func.now(),
|
||
server_onupdate=func.now(),
|
||
comment="画像更新时间",
|
||
)
|
||
|