"""Pydantic schemas for report generation API Request and response models for the report generation endpoints. """ from pydantic import BaseModel, Field from typing import Optional, List from datetime import datetime from enum import Enum class ReportStatus(str, Enum): """Report generation status""" PENDING = "pending" COLLECTING_DATA = "collecting_data" GENERATING_CONTENT = "generating_content" ASSEMBLING_DOCUMENT = "assembling_document" COMPLETED = "completed" FAILED = "failed" # Request Schemas class ReportGenerateRequest(BaseModel): """Request to generate a report (optional parameters)""" include_images: bool = Field(default=True, description="Whether to embed images in the report") include_file_list: bool = Field(default=True, description="Whether to include file attachment list") # Response Schemas class ReportGenerateResponse(BaseModel): """Response after triggering report generation""" report_id: str = Field(..., description="Unique report identifier") status: ReportStatus = Field(..., description="Initial status (typically 'pending')") message: str = Field(default="Report generation started", description="Status message") class ReportStatusResponse(BaseModel): """Full report metadata response""" report_id: str room_id: str generated_by: str generated_at: datetime status: ReportStatus error_message: Optional[str] = None report_title: Optional[str] = None prompt_tokens: Optional[int] = None completion_tokens: Optional[int] = None class Config: from_attributes = True class ReportListItem(BaseModel): """Report item in list response""" report_id: str generated_at: datetime generated_by: str status: ReportStatus report_title: Optional[str] = None class Config: from_attributes = True class ReportListResponse(BaseModel): """List of reports for a room""" reports: List[ReportListItem] total: int class ReportMarkdownResponse(BaseModel): """Report content in Markdown format for in-page preview""" report_id: str report_title: Optional[str] = None markdown: str = Field(..., description="Full report content in Markdown format") # AI Report Content Schemas (validated JSON from DIFY) class TimelineEvent(BaseModel): """Single event in timeline""" time: str = Field(..., description="Time of event (HH:MM or YYYY-MM-DD HH:MM)") description: str = Field(..., description="Event description") class ParticipantInfo(BaseModel): """Participant information""" name: str = Field(..., description="Participant name") role: str = Field(..., description="Role in incident (e.g., 事件發起人, 維修負責人)") class AIReportContent(BaseModel): """Validated JSON schema from DIFY AI response""" summary: dict = Field(..., description="Event summary with 'content' field") timeline: dict = Field(..., description="Timeline with 'events' list") participants: dict = Field(..., description="Participants with 'members' list") resolution_process: dict = Field(..., description="Resolution process with 'content' field") current_status: dict = Field(..., description="Current status with 'status' and 'description' fields") final_resolution: dict = Field(..., description="Final resolution with 'has_resolution' and 'content' fields") @classmethod def validate_structure(cls, data: dict) -> bool: """Validate the basic structure of AI response""" required_keys = ["summary", "timeline", "participants", "resolution_process", "current_status", "final_resolution"] for key in required_keys: if key not in data: return False return True # Error Response class ErrorResponse(BaseModel): """Error response""" detail: str # Health Check Response class HealthCheckResponse(BaseModel): """DIFY service health check response""" status: str = Field(..., description="Status: 'ok' or 'error'") message: str = Field(..., description="Human-readable status message")