feat(models): add series column to Topic for content columns

Topic model: new series VARCHAR field (optional, indexed)
Schema: series in TopicBase/TopicCreate/TopicUpdate
API: GET /api/topics supports ?series= query param
DB migration: ALTER TABLE topics ADD COLUMN series

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
yuzhiran
2026-06-23 13:22:13 +08:00
parent e9cd0374f4
commit f1e6c11505
4 changed files with 8 additions and 0 deletions
+3
View File
@@ -31,6 +31,7 @@ def list_topics(
status: Optional[str] = None,
today: Optional[bool] = None,
tag: Optional[str] = None,
series: Optional[str] = None,
search: Optional[str] = None,
sort_by: str = Query("priority_score", enum=["priority_score", "created_at", "title", "updated_at"]),
order: str = Query("desc", enum=["asc", "desc"]),
@@ -54,6 +55,8 @@ def list_topics(
query = query.filter(func.date(Topic.created_at) == date.today())
if tag:
query = query.filter(Topic.tags.contains([tag]))
if series:
query = query.filter(Topic.series == series)
if search:
query = query.filter(Topic.title.contains(search))
+1
View File
@@ -131,6 +131,7 @@ def init_db():
("search_rankings", "org_id", "VARCHAR DEFAULT 'default'"),
("geo_readiness_scores", "org_id", "VARCHAR DEFAULT 'default'"),
("articles", "org_id", "VARCHAR DEFAULT 'default'"),
("topics", "series", "VARCHAR"),
]:
try:
conn.execute(text(f"ALTER TABLE {table} ADD COLUMN IF NOT EXISTS {col} {typ}"))
+1
View File
@@ -265,6 +265,7 @@ class Topic(Base):
platform_urls = Column(JSON, default=dict)
lock_by = Column(String, nullable=True)
lock_at = Column(DateTime, nullable=True)
series = Column(String, nullable=True, index=True, comment="所属栏目,如:AI工具实测周报、科技人文思辨")
field = relationship("TopicField", backref="topics")
+3
View File
@@ -76,6 +76,7 @@ class TopicBase(BaseModel):
scoring_data: Dict[str, Any] = {}
lock_by: Optional[str] = None
lock_at: Optional[datetime] = None
series: Optional[str] = None
class TopicCreate(BaseModel):
@@ -90,6 +91,7 @@ class TopicCreate(BaseModel):
tags: List[str] = []
custom_data: Dict[str, Any] = {}
scoring_data: Dict[str, Any] = {}
series: Optional[str] = None
class TopicAnalyzeRequest(BaseModel):
@@ -123,6 +125,7 @@ class TopicUpdate(BaseModel):
scoring_data: Optional[Dict[str, Any]] = None
priority_score: Optional[int] = None
total_score: Optional[float] = None
series: Optional[str] = None
class TopicResponse(TopicBase):