Files
boc/landvex-admin/backend/app/models/report.py
T

61 lines
2.1 KiB
Python
Raw Normal View History

"""Report and analytics models."""
from datetime import datetime
from uuid import UUID, uuid4
from sqlalchemy import String, ForeignKey, Text, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
class Report(Base):
__tablename__ = "reports"
id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)
tenant_id: Mapped[UUID] = mapped_column(
ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
)
name: Mapped[str] = mapped_column(String(255), nullable=False)
type: Mapped[str] = mapped_column(String(50), nullable=False)
config: Mapped[dict] = mapped_column(JSON, default=dict)
schedule: Mapped[str | None] # Cron expression or null for one-time
last_run_at: Mapped[datetime | None]
next_run_at: Mapped[datetime | None]
created_by: Mapped[UUID | None] = mapped_column(ForeignKey("users.id"))
created_at: Mapped[datetime] = mapped_column(default=datetime.utcnow)
# Relationships
tenant: Mapped["Tenant"] = relationship(back_populates="reports")
runs: Mapped[list["ReportRun"]] = relationship(
back_populates="report", cascade="all, delete-orphan"
)
def __repr__(self) -> str:
return f"<Report {self.name}>"
class ReportRunStatus(str, Enum):
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
class ReportRun(Base):
__tablename__ = "report_runs"
id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)
report_id: Mapped[UUID] = mapped_column(
ForeignKey("reports.id", ondelete="CASCADE"), nullable=False
)
status: Mapped[ReportRunStatus] = mapped_column(default=ReportRunStatus.RUNNING)
result_url: Mapped[str | None] = mapped_column(Text)
error_message: Mapped[str | None] = mapped_column(Text)
started_at: Mapped[datetime] = mapped_column(default=datetime.utcnow)
completed_at: Mapped[datetime | None]
# Relationships
report: Mapped["Report"] = relationship(back_populates="runs")
def __repr__(self) -> str:
return f"<ReportRun {self.status}>"