Files

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)