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

5.9 KiB

Add File Upload with MinIO

Why

Production line incident response requires comprehensive evidence collection through images, PDFs, and equipment logs. Currently, the system supports text-based realtime messaging, but lacks the ability to attach critical visual evidence (defect photos, equipment screenshots) and documentation (inspection reports, maintenance logs) to incident rooms.

Without file upload capability:

  • Operators cannot share defect images or equipment failure photos directly in incident rooms
  • Engineers must rely on verbal descriptions instead of visual evidence
  • Critical documentation remains scattered across email/LINE instead of centralized
  • AI report generation cannot reference actual evidence files

This change implements MinIO-based file storage, enabling users to upload and reference files within incident rooms while maintaining data sovereignty (all files stay on corporate servers at localhost:9000).

What Changes

This proposal adds a new file-storage capability that:

  1. Integrates MinIO object storage for secure, on-premise file persistence
  2. Adds file upload REST API with multipart/form-data support
  3. Extends database schema to track file metadata (file_id, uploader, room association)
  4. Integrates with realtime messaging to broadcast file upload events via WebSocket
  5. Implements file access control based on room membership
  6. Supports file types critical for production incidents: images (jpg, png), documents (pdf), logs (txt, log)

Dependencies

  • Requires: authentication (user identity), chat-room (room membership validation), realtime-messaging (upload event broadcasting)
  • Enables: Future AI report generation (needs file references to embed images in .docx)

Spec Deltas

  • ADDED file-storage spec with 5 requirements covering upload, download, metadata management, access control, and realtime integration

Risks

  • MinIO service must be running at localhost:9000 (deployment dependency)
  • Large file uploads may impact server memory (mitigation: streaming uploads, size limits)
  • File storage costs scale with incident volume (mitigation: retention policies, compression)

Scenarios

Happy Path: Upload Equipment Failure Photo

  1. Operator detects equipment failure on Line 3
  2. Opens incident room chat interface
  3. Clicks "Attach Image" and selects photo from device (2.5MB jpg)
  4. System validates file type and size
  5. Uploads to MinIO at room-{room_id}/images/{file_id}.jpg
  6. Creates database record linking file to room
  7. Broadcasts file upload event via WebSocket to all room members
  8. Other members see thumbnail preview in chat
  9. Clicking thumbnail opens full-resolution image in modal
  10. File remains accessible for report generation

Edge Case: Upload During Network Interruption

  1. User uploads 5MB PDF during unstable network connection
  2. Upload stalls at 60% completion
  3. Connection drops before completion
  4. Client detects failure, retries upload with same file hash
  5. Server checks if partial file exists in MinIO
  6. Resumes upload from 60% (if MinIO supports multipart resume) or restarts
  7. Upload completes, WebSocket broadcast sent
  8. User sees success notification

Error Case: Unauthorized File Access

  1. User A is member of Room-123
  2. User B is NOT member of Room-123
  3. User B attempts GET /api/rooms/123/files/{file_id}
  4. System validates room membership
  5. Returns 403 Forbidden with error message
  6. File remains inaccessible to User B
  7. Audit log records attempted unauthorized access

Performance Case: Multiple Simultaneous Uploads

  1. During major incident, 5 team members upload files simultaneously
  2. Each uploads 3-5MB images (total ~20MB concurrent)
  3. FastAPI handles uploads with streaming (not loading full files into memory)
  4. MinIO distributes writes across storage nodes
  5. All uploads complete within 10 seconds
  6. WebSocket broadcasts sent for each file
  7. Database records all file metadata
  8. No server memory exhaustion or crashes

Technical Considerations

MinIO Integration

  • Use minio Python SDK (https://min.io/docs/minio/linux/developers/python/minio-py.html)
  • Connection endpoint: localhost:9000
  • Bucket naming: task-reporter-files (single bucket for all rooms)
  • Object path pattern: room-{room_id}/{file_type}/{file_id}.{ext}
  • Authentication: MinIO access key + secret key from environment variables

File Size and Type Limits

  • Images: jpg, jpeg, png, gif | Max 10MB per file
  • Documents: pdf | Max 20MB per file
  • Logs: txt, log, csv | Max 5MB per file
  • Total uploads per room: No limit (subject to storage capacity)
  • MIME type validation using python-magic library

Database Schema Extension

CREATE TABLE room_files (
    file_id VARCHAR(36) PRIMARY KEY,
    room_id VARCHAR(36) NOT NULL REFERENCES incident_rooms(room_id),
    uploader_id VARCHAR(255) NOT NULL,
    filename VARCHAR(255) NOT NULL,
    file_type VARCHAR(20) NOT NULL,  -- 'image', 'document', 'log'
    mime_type VARCHAR(100) NOT NULL,
    file_size BIGINT NOT NULL,  -- bytes
    minio_bucket VARCHAR(100) NOT NULL,
    minio_object_path VARCHAR(500) NOT NULL,
    uploaded_at TIMESTAMP DEFAULT NOW(),
    deleted_at TIMESTAMP,  -- soft delete
    INDEX idx_room_files (room_id, uploaded_at DESC),
    INDEX idx_file_uploader (uploader_id)
);

Security Considerations

  • Access control: Validate user is room member before upload/download
  • File type whitelist: Reject executables, scripts, or unknown MIME types
  • Virus scanning: (Future) integrate ClamAV for uploaded files
  • Presigned URLs: Generate time-limited download URLs (expires in 1 hour)
  • CORS: Restrict file upload endpoints to internal network only

Performance Requirements

  • File upload latency < 2s for 5MB files on local network
  • Download presigned URL generation < 50ms
  • Support 10 concurrent uploads without degradation
  • File list query < 100ms for rooms with 100+ files