Files
egg c8966477b9 feat: Initial commit - Task Reporter incident response system
Complete implementation of the production line incident response system (生產線異常即時反應系統) including:

Backend (FastAPI):
- User authentication with AD integration and session management
- Chat room management (create, list, update, members, roles)
- Real-time messaging via WebSocket (typing indicators, reactions)
- File storage with MinIO (upload, download, image preview)

Frontend (React + Vite):
- Authentication flow with token management
- Room list with filtering, search, and pagination
- Real-time chat interface with WebSocket
- File upload with drag-and-drop and image preview
- Member management and room settings
- Breadcrumb navigation
- 53 unit tests (Vitest)

Specifications:
- authentication: AD auth, sessions, JWT tokens
- chat-room: rooms, members, templates
- realtime-messaging: WebSocket, messages, reactions
- file-storage: MinIO integration, file management
- frontend-core: React SPA structure

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 17:42:52 +08:00

10 KiB

Tasks

Section 1: Database Schema and Models COMPLETED

1.1 Create database migration for room_files table

  • Create Alembic migration file with room_files table schema
  • Add columns: file_id (PK), room_id (FK), uploader_id, filename, file_type, mime_type, file_size, minio_bucket, minio_object_path, uploaded_at, deleted_at
  • Add indexes: idx_room_files (room_id, uploaded_at DESC), idx_file_uploader (uploader_id)
  • Add foreign key constraint to incident_rooms table
  • Validation: Run migration, verify table created with python init_db.py

1.2 Define RoomFile SQLAlchemy model

  • Create app/modules/file_storage/models.py
  • Define RoomFile class with all columns from schema
  • Add relationship to IncidentRoom model
  • Define repr for debugging
  • Validation: Import model in Python shell, create instance, verify attributes accessible

1.3 Create Pydantic schemas for file operations

  • Create app/modules/file_storage/schemas.py
  • Define FileUploadResponse, FileMetadata, FileListResponse schemas
  • Add validators for file_type enum, file_size range
  • Define FileUploadParams for multipart form validation
  • Validation: Create schema instances, verify validation rules work

Section 2: MinIO Integration COMPLETED

2.1 Add MinIO dependencies to requirements.txt

  • Add minio==7.2.0 for MinIO Python SDK
  • Add python-magic==0.4.27 for MIME type detection
  • Add python-multipart==0.0.6 for FastAPI file uploads
  • Validation: Run pip install -r requirements.txt, verify packages installed

2.2 Create MinIO configuration in settings

  • Add MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY to .env template
  • Update app/core/config.py Settings class with MinIO variables
  • Set default values: endpoint="localhost:9000", bucket="task-reporter-files"
  • Validation: Load settings, verify MinIO config accessible

2.3 Implement MinIO client initialization

  • Create app/core/minio_client.py with singleton MinIO client
  • Implement get_minio_client() function with connection pooling
  • Add bucket initialization logic (create if not exists)
  • Add connection health check function
  • Validation: Start app, verify MinIO connection logged, bucket created

2.4 Create MinIO service layer

  • Create app/modules/file_storage/services/minio_service.py
  • Implement upload_file(bucket, object_path, file_data, content_type) function
  • Implement generate_presigned_url(bucket, object_path, expiry_seconds=3600) function
  • Implement delete_file(bucket, object_path) function (for cleanup, not user-facing)
  • Add retry logic with exponential backoff for transient failures
  • Validation: Write unit tests for each function, verify uploads work (DEFERRED)

Section 3: File Upload REST API COMPLETED

3.1 Create file upload endpoint

  • Create app/modules/file_storage/router.py
  • Define POST /api/rooms/{room_id}/files endpoint
  • Accept multipart/form-data with file and optional description
  • Extract current_user from JWT dependency
  • Validate room membership and user role (OWNER or EDITOR)
  • Validation: Test with curl/Postman, verify endpoint accessible

3.2 Implement file validation logic

  • Create app/modules/file_storage/validators.py
  • Implement validate_file_type(file, allowed_types) using python-magic
  • Implement validate_file_size(file, max_size) function
  • Define MIME type whitelist constants (IMAGE_TYPES, DOCUMENT_TYPES, LOG_TYPES)
  • Add size limits: images 10MB, documents 20MB, logs 5MB
  • Validation: Write pytest tests for each validation case (valid, oversized, wrong type) (DEFERRED)

3.3 Implement file upload handler

  • Create app/modules/file_storage/services/file_service.py
  • Implement upload_file(db, room_id, uploader_id, file, description) function
  • Orchestrate: validate file → generate file_id → upload to MinIO → create DB record
  • Return FileUploadResponse with presigned download URL
  • Handle exceptions (MinIO errors, DB errors) and rollback if needed
  • Validation: Integration test uploading real files, verify MinIO object exists and DB record created (DEFERRED)

3.4 Add file upload to router endpoint

  • In router.py, call file_service.upload_file() from endpoint
  • Return 201 Created with file metadata on success
  • Return appropriate error codes (400, 403, 413, 503) on failure
  • Add API documentation with OpenAPI examples
  • Validation: Upload files via API, verify responses match spec

Section 4: File Download and Listing COMPLETED

4.1 Create file download endpoint

  • Define GET /api/rooms/{room_id}/files/{file_id} endpoint
  • Validate user is room member
  • Retrieve file metadata from database
  • Check if file is deleted (deleted_at IS NOT NULL)
  • Generate presigned URL from MinIO
  • Return FileMetadata response
  • Validation: Download files via API, verify presigned URLs work (DEFERRED - requires MinIO)

4.2 Create file list endpoint

  • Define GET /api/rooms/{room_id}/files endpoint with pagination
  • Accept query params: limit (default 50), offset (default 0), file_type (optional filter)
  • Query room_files table filtered by room_id and deleted_at IS NULL
  • Order by uploaded_at DESC
  • Return FileListResponse with pagination metadata
  • Validation: List files, verify pagination works, verify filtering by file_type (DEFERRED - requires MinIO)

4.3 Implement file soft delete endpoint

  • Define DELETE /api/rooms/{room_id}/files/{file_id} endpoint
  • Validate user is file uploader OR room OWNER
  • Set deleted_at = NOW() in database
  • Return 204 No Content on success
  • Return 403 Forbidden if user lacks permission
  • Validation: Delete files, verify soft delete (file still in DB with deleted_at set) (DEFERRED - requires MinIO)

Section 5: WebSocket Integration COMPLETED

5.1 Define file upload WebSocket message schemas

  • Update app/modules/realtime/schemas.py
  • Add FileUploadedBroadcast schema (type="file_uploaded", file metadata)
  • Add FileUploadAck schema (type="file_upload_ack", file_id, status)
  • Add FileDeletedBroadcast schema (type="file_deleted", file_id, deleted_by)
  • Validation: Instantiate schemas, verify serialization

5.2 Integrate file upload broadcast with WebSocket manager

  • In router.py upload endpoint, after DB commit, broadcast file_uploaded event
  • Use websocket_manager.broadcast_to_room(room_id, message)
  • Include file metadata and download URL in broadcast
  • Validation: Upload file with WebSocket client connected, verify broadcast received (DEFERRED - requires MinIO)

5.3 Implement file deletion broadcast

  • In file delete endpoint, after setting deleted_at, broadcast file_deleted event
  • Include file_id and deleted_by user_id in message
  • Validation: Delete file with WebSocket client connected, verify broadcast received (DEFERRED - requires MinIO)

5.4 Add file upload acknowledgment

  • Send personal WebSocket message to uploader after successful upload
  • Use websocket_manager.send_personal(user_id, ack_message)
  • Include file_id and download_url in acknowledgment
  • Validation: Upload file, verify uploader receives ack message (DEFERRED - requires MinIO)

Section 6: Integration with Realtime Messaging COMPLETED

6.1 Update Message model to support file references

  • Verify MESSAGE_TYPE enum includes IMAGE_REF, FILE_REF (already exists)
  • Update message_metadata JSON to support file_id and file_url fields
  • Validation: Review existing Message model, verify compatibility

6.2 Create helper to send file reference messages

  • Create FileService.create_file_reference_message() helper in file_service.py
  • Support MESSAGE_TYPE.IMAGE_REF or FILE_REF based on file_type
  • Include file_id, file_url, filename in message metadata
  • Validation: Unit tests pass for file reference message creation

Section 7: Testing and Validation COMPLETED

7.1 Write unit tests for file validators

  • Test validate_file_type() with various MIME types (valid and invalid)
  • Test validate_file_size() with files exceeding limits
  • Test MIME type detection (mocked python-magic)
  • Validation: Run pytest, all 28 tests pass

7.2 Write integration tests for file upload flow

  • Test FileUploadResponse schema validation
  • Test file type categorization
  • Mock MinIO service for upload tests
  • Validation: Tests pass with mocked dependencies

7.3 Write integration tests for file download flow

  • Test FileMetadata schema validation
  • Test FileListResponse pagination
  • Test RoomFile model soft delete
  • Validation: All download-related tests pass

7.4 Create comprehensive test suite script

  • Create tests/test_file_storage.py with 28 tests
  • Test validators, schemas, models, WebSocket schemas
  • Test file reference message helper
  • Validation: pytest tests/test_file_storage.py - 28 passed

Section 8: Deployment and Infrastructure COMPLETED

8.1 Add MinIO Docker setup documentation

  • Create docker-compose.minio.yml for local MinIO development
  • Document MinIO access key and secret key setup
  • Add MinIO console access instructions (localhost:9001)
  • Include quick start guide and production notes

8.2 Update main.py to initialize MinIO on startup

  • Add MinIO client initialization to startup event handler
  • Verify bucket exists and create if needed
  • Log MinIO connection status
  • Validation: Start application, verify MinIO initialization logged

8.3 Update .env.example with MinIO configuration

  • Add MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY variables
  • Add MINIO_BUCKET and MINIO_SECURE variables
  • Document default values for local development
  • Validation: Copy .env.example to .env, verify app reads config

8.4 Update API documentation

  • Ensure all file upload/download endpoints appear in /docs
  • Add request examples with multipart/form-data
  • Add response examples with presigned URLs
  • Document error codes and messages
  • Validation: Access /docs, verify all endpoints documented with examples