79 lines
3.6 KiB
Python
79 lines
3.6 KiB
Python
"""ORM rows for the generated-file library read index."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import BigInteger, Boolean, Index, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base
|
|
from deerflow.persistence.types import BeijingDateTime
|
|
|
|
|
|
class ArtifactLibraryItemRow(Base):
|
|
"""One generated file projected into the fast library listing."""
|
|
|
|
__tablename__ = "artifact_library_items"
|
|
__table_args__ = (
|
|
Index(
|
|
"ix_artifact_library_user_modified",
|
|
"user_id",
|
|
"modified_at",
|
|
"artifact_id",
|
|
),
|
|
Index(
|
|
"ix_artifact_library_user_kind",
|
|
"user_id",
|
|
"file_kind",
|
|
"modified_at",
|
|
"artifact_id",
|
|
),
|
|
Index(
|
|
"ix_artifact_library_user_source",
|
|
"user_id",
|
|
"source_type",
|
|
"modified_at",
|
|
"artifact_id",
|
|
),
|
|
Index("ix_artifact_library_user_generation", "user_id", "sync_generation"),
|
|
)
|
|
|
|
# A deterministic SHA-256 of (user_id, thread_id, virtual path) avoids a
|
|
# long composite primary key that would exceed older MySQL index limits.
|
|
artifact_id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
user_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
thread_id: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
thread_title: Mapped[str] = mapped_column(String(512), nullable=False, default="")
|
|
agent_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
agent_name: Mapped[str | None] = mapped_column(String(512), nullable=True)
|
|
thread_type: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
source_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
strategy_project_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
strategy_name: Mapped[str | None] = mapped_column(String(512), nullable=True)
|
|
strategy_stale: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
strategy_source_kind: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
download_url: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
path: Mapped[str] = mapped_column(Text, nullable=False)
|
|
name: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
size_bytes: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
|
|
mime_type: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
modified_at: Mapped[datetime] = mapped_column(BeijingDateTime(), nullable=False)
|
|
file_kind: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
sync_generation: Mapped[str] = mapped_column(String(36), nullable=False)
|
|
indexed_at: Mapped[datetime] = mapped_column(BeijingDateTime(), nullable=False, default=lambda: datetime.now(UTC))
|
|
|
|
|
|
class ArtifactLibrarySyncStateRow(Base):
|
|
"""Per-user lease and last-published generation metadata."""
|
|
|
|
__tablename__ = "artifact_library_sync_states"
|
|
|
|
user_id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False, default="idle")
|
|
generation: Mapped[str | None] = mapped_column(String(36), nullable=True)
|
|
started_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True)
|
|
lease_expires_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True)
|
|
completed_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True)
|
|
last_error: Mapped[str | None] = mapped_column(String(1024), nullable=True)
|