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>
5.9 KiB
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:
- Integrates MinIO object storage for secure, on-premise file persistence
- Adds file upload REST API with multipart/form-data support
- Extends database schema to track file metadata (file_id, uploader, room association)
- Integrates with realtime messaging to broadcast file upload events via WebSocket
- Implements file access control based on room membership
- 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-storagespec 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
- Operator detects equipment failure on Line 3
- Opens incident room chat interface
- Clicks "Attach Image" and selects photo from device (2.5MB jpg)
- System validates file type and size
- Uploads to MinIO at
room-{room_id}/images/{file_id}.jpg - Creates database record linking file to room
- Broadcasts file upload event via WebSocket to all room members
- Other members see thumbnail preview in chat
- Clicking thumbnail opens full-resolution image in modal
- File remains accessible for report generation
Edge Case: Upload During Network Interruption
- User uploads 5MB PDF during unstable network connection
- Upload stalls at 60% completion
- Connection drops before completion
- Client detects failure, retries upload with same file hash
- Server checks if partial file exists in MinIO
- Resumes upload from 60% (if MinIO supports multipart resume) or restarts
- Upload completes, WebSocket broadcast sent
- User sees success notification
Error Case: Unauthorized File Access
- User A is member of Room-123
- User B is NOT member of Room-123
- User B attempts
GET /api/rooms/123/files/{file_id} - System validates room membership
- Returns 403 Forbidden with error message
- File remains inaccessible to User B
- Audit log records attempted unauthorized access
Performance Case: Multiple Simultaneous Uploads
- During major incident, 5 team members upload files simultaneously
- Each uploads 3-5MB images (total ~20MB concurrent)
- FastAPI handles uploads with streaming (not loading full files into memory)
- MinIO distributes writes across storage nodes
- All uploads complete within 10 seconds
- WebSocket broadcasts sent for each file
- Database records all file metadata
- No server memory exhaustion or crashes
Technical Considerations
MinIO Integration
- Use
minioPython 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-magiclibrary
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