66 lines
3.3 KiB
Python
66 lines
3.3 KiB
Python
"""ORM models for generated HTML pages and user favorites.
|
|
|
|
These back the "HTML 页面定时任务" feature: a scheduled task of kind
|
|
``html_page`` renders a full HTML document each run. Every rendered page is
|
|
recorded in :class:`ScheduledHtmlPageRow`; a user may bookmark one into
|
|
:class:`HtmlPageFavoriteRow`, which also stores a reusable style/layout
|
|
summary so a later task can be generated "in the style of" the favorite.
|
|
|
|
Both tables are brand new, so ``Base.metadata.create_all`` creates them on the
|
|
next startup without touching any existing schema.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base
|
|
from deerflow.persistence.types import BeijingDateTime, PortableJSON, PortableLongText
|
|
|
|
|
|
class ScheduledHtmlPageRow(Base):
|
|
"""One HTML page produced by a single run of an ``html_page`` task."""
|
|
|
|
__tablename__ = "scheduled_html_pages"
|
|
|
|
id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
task_id: Mapped[str] = mapped_column(String(64), index=True)
|
|
run_id: Mapped[str] = mapped_column(String(64), index=True)
|
|
user_id: Mapped[str] = mapped_column(String(64), index=True)
|
|
title: Mapped[str] = mapped_column(String(255))
|
|
# Full HTML document — can be large, so LONGTEXT on MySQL.
|
|
html_content: Mapped[str] = mapped_column(PortableLongText())
|
|
html_file_path: Mapped[str | None] = mapped_column(Text)
|
|
data_snapshot_json: Mapped[dict | None] = mapped_column(PortableJSON(), default=dict)
|
|
prompt_snapshot_json: Mapped[dict | None] = mapped_column(PortableJSON(), default=dict)
|
|
reference_favorite_id: Mapped[str | None] = mapped_column(String(64), index=True)
|
|
style_summary: Mapped[str | None] = mapped_column(Text)
|
|
layout_summary: Mapped[str | None] = mapped_column(Text)
|
|
created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=lambda: datetime.now(UTC))
|
|
updated_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|
|
|
|
|
|
class HtmlPageFavoriteRow(Base):
|
|
"""A user-bookmarked HTML page, with a reusable style/layout summary."""
|
|
|
|
__tablename__ = "html_page_favorites"
|
|
|
|
id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
user_id: Mapped[str] = mapped_column(String(64), index=True)
|
|
page_id: Mapped[str] = mapped_column(String(64), index=True)
|
|
title: Mapped[str] = mapped_column(String(255))
|
|
description: Mapped[str | None] = mapped_column(Text)
|
|
tags_json: Mapped[list | None] = mapped_column(PortableJSON(), default=list)
|
|
# Snapshot of the page HTML at favorite time, decoupled from the source run
|
|
# so deleting the run never breaks the favorite reference.
|
|
html_snapshot: Mapped[str] = mapped_column(PortableLongText())
|
|
style_summary: Mapped[str | None] = mapped_column(Text)
|
|
layout_summary: Mapped[str | None] = mapped_column(Text)
|
|
content_structure_summary: Mapped[str | None] = mapped_column(Text)
|
|
reuse_prompt: Mapped[str | None] = mapped_column(Text)
|
|
created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=lambda: datetime.now(UTC))
|
|
updated_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|