feat: add periodic practice reports

This commit is contained in:
2026-07-31 16:37:25 +08:00
parent 88ed92d78c
commit 99e23b33ec
16 changed files with 602 additions and 3 deletions

View File

@@ -3,7 +3,7 @@ from app.models.ai_config import ModelConfig, Prompt, SystemConfig
from app.models.base import Base
from app.models.chat import ChatMessage, ChatSession, TopicSession
from app.models.entitlement import EntitlementPlan, UserEntitlement, UserEntitlementLog
from app.models.growth import GrowthProfileRevision, ShareDraft, TeacherHelpCard, TopicSummary, UserGrowthProfile
from app.models.growth import GrowthProfileRevision, PeriodicReport, ShareDraft, TeacherHelpCard, TopicSummary, UserGrowthProfile
from app.models.knowledge import (
HumanAttentionHistory,
HumanAttentionRecord,
@@ -48,6 +48,7 @@ __all__ = [
"HumanAttentionRecord",
"ModelConfig",
"OperationLog",
"PeriodicReport",
"LogRetentionPolicy",
"StorageSnapshot",
"TopicSession",

View File

@@ -100,3 +100,29 @@ class ShareDraft(Base):
copied: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
copied_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
class PeriodicReport(Base):
__tablename__ = "sys_periodic_report"
__table_args__ = (
UniqueConstraint("user_id", "report_type", "period_start", "period_end", name="uq_sys_periodic_report_period"),
Index("ix_sys_periodic_report_user_type_created", "user_id", "report_type", "created_at"),
Index("ix_sys_periodic_report_status_created", "status", "created_at"),
)
id: Mapped[int] = mapped_column(PRIMARY_KEY_TYPE, primary_key=True, autoincrement=True)
user_id: Mapped[int] = mapped_column(ForeignKey("sys_user.id"), index=True, nullable=False)
report_type: Mapped[str] = mapped_column(String(30), nullable=False)
period_start: Mapped[datetime] = mapped_column(DateTime, nullable=False)
period_end: Mapped[datetime] = mapped_column(DateTime, nullable=False)
title: Mapped[str] = mapped_column(String(160), nullable=False)
content: Mapped[str] = mapped_column(Text, default="", nullable=False)
source_summary_ids: Mapped[str | None] = mapped_column(Text, nullable=True)
source_topic_ids: Mapped[str | None] = mapped_column(Text, nullable=True)
model_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
status: Mapped[str] = mapped_column(String(20), default="success", index=True, nullable=False)
error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
generated_by: Mapped[str] = mapped_column(String(30), default="manual", nullable=False)
generated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now(), nullable=False)