Files
Task_Reporter/openspec/changes/archive/2025-12-04-add-ai-report-generation/tasks.md
egg 3927441103 feat: Add AI report generation with DIFY integration
- Add Users table for display name resolution from AD authentication
- Integrate DIFY AI service for report content generation
- Create docx assembly service with image embedding from MinIO
- Add REST API endpoints for report generation and download
- Add WebSocket notifications for generation progress
- Add frontend UI with progress modal and download functionality
- Add integration tests for report generation flow

Report sections (Traditional Chinese):
- 事件摘要 (Summary)
- 時間軸 (Timeline)
- 參與人員 (Participants)
- 處理過程 (Resolution Process)
- 目前狀態 (Current Status)
- 最終處置結果 (Final Resolution)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:32:40 +08:00

10 KiB

Implementation Tasks

0. Users Table for Display Name Resolution

  • 0.1 Create app/modules/auth/models.py - Add User model:

    • user_id (PK, VARCHAR 255) - email address
    • display_name (VARCHAR 255, NOT NULL)
    • office_location (VARCHAR 100, nullable)
    • job_title (VARCHAR 100, nullable)
    • last_login_at (TIMESTAMP)
    • created_at (TIMESTAMP, default NOW)
  • 0.2 Create app/modules/auth/services/user_service.py:

    • upsert_user(user_id, display_name, office_location, job_title) function
    • Uses SQLAlchemy merge or INSERT ON CONFLICT for atomic upsert
    • Updates last_login_at on every call
  • 0.3 Modify app/modules/auth/router.py login endpoint:

    • After successful AD authentication, call upsert_user() with:
      • user_id: userInfo.email
      • display_name: userInfo.name
      • office_location: userInfo.officeLocation
      • job_title: userInfo.jobTitle
  • 0.4 Run database migration to create users table

  • 0.5 Write unit tests for user upsert:

    • Test new user creation
    • Test existing user update
    • Test last_login_at update

1. Configuration and Dependencies

  • 1.1 Add DIFY settings to app/core/config.py:

    • DIFY_BASE_URL: str = "https://dify.theaken.com/v1"
    • DIFY_API_KEY: str (required)
    • DIFY_TIMEOUT_SECONDS: int = 120
    • REPORT_MAX_MESSAGES: int = 200
    • REPORT_STORAGE_PATH: str = "reports"
  • 1.2 Update .env.example with DIFY configuration variables

  • 1.3 Add dependencies to requirements.txt:

    • python-docx>=1.1.0
    • httpx>=0.27.0 (async HTTP client for DIFY API)
  • 1.4 Install dependencies: pip install -r requirements.txt

2. Database Schema and Models

  • 2.1 Create app/modules/report_generation/models.py:

    • GeneratedReport SQLAlchemy model with fields:
      • report_id (PK, UUID)
      • room_id (FK to incident_rooms)
      • generated_by, generated_at
      • status (pending/collecting_data/generating_content/assembling_document/completed/failed)
      • error_message
      • dify_message_id, dify_conversation_id
      • prompt_tokens, completion_tokens
      • report_title, report_json (JSONB)
      • docx_storage_path
  • 2.2 Create app/modules/report_generation/schemas.py:

    • ReportGenerateRequest (optional parameters)
    • ReportGenerateResponse (report_id, status)
    • ReportStatusResponse (full report metadata)
    • ReportListResponse (list of reports)
    • AIReportContent (validated JSON schema from DIFY)
  • 2.3 Run database migration to create generated_reports table

3. DIFY Service Integration

  • 3.1 Create app/modules/report_generation/prompts.py:

    • System prompt template (Traditional Chinese)
    • JSON output schema with examples
    • User query template for room data formatting
  • 3.2 Create app/modules/report_generation/services/dify_service.py:

    • DifyService class with httpx async client
    • generate_report_content(prompt: str) -> dict method
    • Request construction with headers and body
    • Response parsing and JSON extraction
    • Error handling (timeout, auth failure, invalid JSON)
    • Retry logic for recoverable errors
  • 3.3 Write unit tests for DIFY service:

    • Mock successful API response
    • Mock timeout scenario
    • Mock invalid JSON response
    • Mock authentication failure

4. Report Data Collection Service

  • 4.1 Create app/modules/report_generation/services/report_data_service.py:

    • ReportDataService class
    • collect_room_data(room_id: str) -> RoomReportData method
    • Query room metadata from incident_rooms
    • Query messages with sender display names
    • Query members with roles
    • Query files with metadata
    • Handle message limit (summarize if exceeds REPORT_MAX_MESSAGES)
  • 4.2 Create data models for collected data:

    • RoomReportData dataclass
    • MessageData dataclass
    • MemberData dataclass
    • FileData dataclass
  • 4.3 Create prompt builder function:

    • build_report_prompt(room_data: RoomReportData) -> str
    • Format room metadata section
    • Format members section
    • Format messages timeline
    • Format files section
  • 4.4 Write unit tests for data collection:

    • Test with normal room data
    • Test with empty room (should raise error)
    • Test message summarization for large rooms

5. Document Assembly Service

  • 5.1 Create app/modules/report_generation/services/docx_service.py:

    • DocxAssemblyService class
    • create_document(report_content: dict, room_data: RoomReportData) -> BytesIO method
    • Document title and metadata header
    • Section formatting (headings, paragraphs, tables)
    • Timeline table generation
    • Member list formatting
  • 5.2 Implement image embedding:

    • Download images from MinIO using existing minio_service
    • Resize images to max width (15cm)
    • Insert images into document
    • Handle missing images gracefully
  • 5.3 Implement document styling:

    • Set default font (標楷體 or 微軟正黑體)
    • Set heading styles
    • Set paragraph spacing
    • Set table styles
  • 5.4 Write unit tests for docx assembly:

    • Test basic document creation
    • Test with embedded images (mock MinIO)
    • Test without images
    • Test missing image handling

6. REST API Router

  • 6.1 Create app/modules/report_generation/router.py:

    • POST /api/rooms/{room_id}/reports/generate - Trigger generation
    • GET /api/rooms/{room_id}/reports - List reports
    • GET /api/rooms/{room_id}/reports/{report_id} - Get report status
    • GET /api/rooms/{room_id}/reports/{report_id}/download - Download .docx
  • 6.2 Create app/modules/report_generation/dependencies.py:

    • verify_room_access - Check user is room member
    • verify_report_access - Check report belongs to accessible room
  • 6.3 Implement generate endpoint:

    • Verify room membership
    • Create report record with status "pending"
    • Return report_id immediately
    • Trigger async report generation (can use background task or sync for MVP)
  • 6.4 Implement download endpoint:

    • Verify report exists and is completed
    • Load .docx from storage
    • Return as file response with proper headers
  • 6.5 Register router in app/main.py

7. Report Generation Orchestration

  • 7.1 Create main orchestration function in services/__init__.py:

    • generate_report(room_id: str, user_id: str, db: Session) -> str
    • Update status at each stage
    • Call data collection service
    • Call DIFY service
    • Call docx assembly service
    • Store document (MinIO or local)
    • Update final status
  • 7.2 Implement error handling:

    • Catch and log all exceptions
    • Update report status to "failed" with user-friendly error message
    • Store technical error in database for debugging
  • 7.3 Implement document storage:

    • Upload .docx to MinIO under reports/{room_id}/{report_id}.docx
    • Store path in database

8. WebSocket Notifications

  • 8.1 Add report notification schemas to app/modules/realtime/schemas.py:

    • ReportGeneratedBroadcast
    • ReportGenerationFailedBroadcast
  • 8.2 Integrate WebSocket broadcast in report generation:

    • Broadcast report_generated on success
    • Broadcast report_generation_failed on failure

9. Frontend Integration

  • 9.1 Create frontend/src/services/reports.ts:

    • generateReport(roomId: string): Promise<{report_id: string}>
    • listReports(roomId: string): Promise<Report[]>
    • getReportStatus(roomId: string, reportId: string): Promise<Report>
    • downloadReport(roomId: string, reportId: string): Promise<Blob>
  • 9.2 Add TypeScript types for reports in frontend/src/types/index.ts

  • 9.3 Create report generation hooks in frontend/src/hooks/useReports.ts:

    • useGenerateReport mutation
    • useReportList query
    • useReportStatus query
  • 9.4 Add "Generate Report" button to RoomDetail page:

    • Show only for resolved/archived rooms (or with warning for active)
    • Disable during generation
    • Show progress indicator
  • 9.5 Add report list and download UI:

    • Show list of generated reports
    • Download button for each completed report
    • Status indicator for pending/failed reports
  • 9.6 Handle WebSocket report notifications:

    • Update UI when report_generated received
    • Show toast notification
    • Refresh report list

10. Integration Testing

  • 10.1 Create tests/test_report_generation.py:

    • Test full report generation flow (with mocked DIFY)
    • Test API endpoints (generate, list, download)
    • Test permission checks
    • Test error scenarios
  • 10.2 Create integration test with real DIFY (optional, manual):

    • Test with sample room data
    • Verify JSON output format
    • Check document quality

11. Documentation

  • 11.1 Update API documentation with new endpoints
  • 11.2 Update .env.example with all DIFY configuration

Task Dependencies

0.1 ─▶ 0.2 ─▶ 0.3 ─▶ 0.4 ─▶ 0.5
                      │
                      ▼
1.1 ─┬─▶ 2.1 ─▶ 2.3 ─┴─▶ 4.1 (needs users table for JOIN)
1.2 ─┘
1.3 ─▶ 1.4 ─┬─▶ 3.1 ─▶ 3.2 ─▶ 3.3
            ├─▶ 4.1 ─▶ 4.2 ─▶ 4.3 ─▶ 4.4
            └─▶ 5.1 ─▶ 5.2 ─▶ 5.3 ─▶ 5.4

2.2 ─┬─▶ 6.1 ─▶ 6.2 ─▶ 6.3 ─▶ 6.4 ─▶ 6.5
     │
3.2 ─┼─▶ 7.1 ─▶ 7.2 ─▶ 7.3
4.1 ─┤
5.1 ─┘

7.1 ─▶ 8.1 ─▶ 8.2

6.5 ─▶ 9.1 ─▶ 9.2 ─▶ 9.3 ─▶ 9.4 ─▶ 9.5 ─▶ 9.6

All ─▶ 10.1 ─▶ 10.2 ─▶ 11.1 ─▶ 11.2

Parallelizable Work

The following can be done in parallel:

  • Section 0 (Users Table) should be done first as a prerequisite
  • Section 3 (DIFY Service) and Section 4 (Data Collection) and Section 5 (Docx Assembly)
  • Section 6 (API Router) can start once Section 2 (Schemas) is done
  • Section 9 (Frontend) can start once Section 6 (API) is done

Summary

Section Tasks Description
0. Users Table 5 Display name resolution
1. Config 4 Configuration and dependencies
2. Database 3 Models and schemas
3. DIFY 3 AI service integration
4. Data Collection 4 Room data gathering
5. Docx Assembly 4 Document generation
6. REST API 5 API endpoints
7. Orchestration 3 Main generation flow
8. WebSocket 2 Notifications
9. Frontend 6 UI integration
10. Testing 2 Integration tests
11. Documentation 2 Docs update
Total 43