Files
Task_Reporter/app/modules/report_generation/schemas.py
egg 599802b818 feat: Add Chat UX improvements with notifications and @mention support
- Add ActionBar component with expandable toolbar for mobile
- Add @mention functionality with autocomplete dropdown
- Add browser notification system (push, sound, vibration)
- Add NotificationSettings modal for user preferences
- Add mention badges on room list cards
- Add ReportPreview with Markdown rendering and copy/download
- Add message copy functionality with hover actions
- Add backend mentions field to messages with Alembic migration
- Add lots field to rooms, remove templates
- Optimize WebSocket database session handling
- Various UX polish (animations, accessibility)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 08:20:37 +08:00

120 lines
4.0 KiB
Python

"""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")