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>
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 0. Users Table for Display Name Resolution
|
||||
|
||||
- [x] 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)
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 0.4 Run database migration to create `users` table
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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"
|
||||
|
||||
- [x] 1.2 Update `.env.example` with DIFY configuration variables
|
||||
|
||||
- [x] 1.3 Add dependencies to `requirements.txt`:
|
||||
- `python-docx>=1.1.0`
|
||||
- `httpx>=0.27.0` (async HTTP client for DIFY API)
|
||||
|
||||
- [x] 1.4 Install dependencies: `pip install -r requirements.txt`
|
||||
|
||||
## 2. Database Schema and Models
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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)
|
||||
|
||||
- [x] 2.3 Run database migration to create `generated_reports` table
|
||||
|
||||
## 3. DIFY Service Integration
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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)
|
||||
|
||||
- [x] 4.2 Create data models for collected data:
|
||||
- `RoomReportData` dataclass
|
||||
- `MessageData` dataclass
|
||||
- `MemberData` dataclass
|
||||
- `FileData` dataclass
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 5.3 Implement document styling:
|
||||
- Set default font (標楷體 or 微軟正黑體)
|
||||
- Set heading styles
|
||||
- Set paragraph spacing
|
||||
- Set table styles
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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)
|
||||
|
||||
- [x] 6.4 Implement download endpoint:
|
||||
- Verify report exists and is completed
|
||||
- Load .docx from storage
|
||||
- Return as file response with proper headers
|
||||
|
||||
- [x] 6.5 Register router in `app/main.py`
|
||||
|
||||
## 7. Report Generation Orchestration
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 7.3 Implement document storage:
|
||||
- Upload .docx to MinIO under `reports/{room_id}/{report_id}.docx`
|
||||
- Store path in database
|
||||
|
||||
## 8. WebSocket Notifications
|
||||
|
||||
- [x] 8.1 Add report notification schemas to `app/modules/realtime/schemas.py`:
|
||||
- `ReportGeneratedBroadcast`
|
||||
- `ReportGenerationFailedBroadcast`
|
||||
|
||||
- [x] 8.2 Integrate WebSocket broadcast in report generation:
|
||||
- Broadcast `report_generated` on success
|
||||
- Broadcast `report_generation_failed` on failure
|
||||
|
||||
## 9. Frontend Integration
|
||||
|
||||
- [x] 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>`
|
||||
|
||||
- [x] 9.2 Add TypeScript types for reports in `frontend/src/types/index.ts`
|
||||
|
||||
- [x] 9.3 Create report generation hooks in `frontend/src/hooks/useReports.ts`:
|
||||
- `useGenerateReport` mutation
|
||||
- `useReportList` query
|
||||
- `useReportStatus` query
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 9.6 Handle WebSocket report notifications:
|
||||
- Update UI when report_generated received
|
||||
- Show toast notification
|
||||
- Refresh report list
|
||||
|
||||
## 10. Integration Testing
|
||||
|
||||
- [x] 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
|
||||
|
||||
- [x] 10.2 Create integration test with real DIFY (optional, manual):
|
||||
- Test with sample room data
|
||||
- Verify JSON output format
|
||||
- Check document quality
|
||||
|
||||
## 11. Documentation
|
||||
|
||||
- [x] 11.1 Update API documentation with new endpoints
|
||||
- [x] 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** | |
|
||||
Reference in New Issue
Block a user