Frame Photo Upload - Technical Documentation
๐ฏ Overviewโ
Frame photo upload system enabling users to upload images of beehive frames with automatic processing pipeline that triggers AI detection models, generates thumbnails, stores images in object storage, and provides real-time analysis feedback. Core workflow feature for all frame-based AI analysis.
๐๏ธ Architectureโ
Componentsโ
- FileUploader: React component for drag-drop and click-to-upload interface
- FrameSideView: Container managing upload state and detection visualization
- DetectionOverlay: Canvas-based rendering of AI detection results
- ZoomableImage: Optimized image viewer with lazy loading
Servicesโ
- image-splitter: Primary service orchestrating image processing, ML model invocation, storage
- models-bee-detector: Worker bee, drone, queen detection
- models-frame-resources: Cell detection (brood, honey, pollen)
- Clarifai API: Queen cup, varroa mite detection
- AWS S3/Minio: Object storage for original and thumbnail images
๐ Technical Specificationsโ
Image Processing Pipelineโ
1. Upload (web-app) โ Direct POST to image-splitter
2. Store original โ S3/Minio bucket
3. Create job queue entries (resize, detect_bees, detect_cells, etc.)
4. Process jobs asynchronously:
- Generate thumbnails (200px, 800px, 1600px)
- Invoke ML models
- Store detection results
5. Publish Redis events for real-time updates
6. Update GraphQL cache
GraphQL APIโ
mutation uploadFrameSide($frameId: ID!, $side: FrameSide!, $file: Upload!) {
uploadFrameSide(frameId: $frameId, side: $side, file: $file) {
id
url
thumbnailUrl
detections {
type
count
boxes {
x
y
width
height
confidence
}
}
}
}
query frameSide($id: ID!) {
frameSide(id: $id) {
id
url
resizedSmall: url(size: SMALL)
resizedMedium: url(size: MEDIUM)
resizedLarge: url(size: LARGE)
detections {
bees
queens
cells {
total
capped_brood
larvae
eggs
pollen
honey
empty
}
}
}
}
subscription frameSideProcessing($frameSideId: ID!) {
frameSideProcessing(frameSideId: $frameSideId) {
status
progress
message
}
}
REST API Endpointsโ
POST /upload/:frameSideId
- Direct file upload endpoint
- Multipart form-data
- Returns: { url, id, status }
GET /file/:frameSideId/:size?
- Retrieve image by size (original, small, medium, large)
- Returns: Image binary with appropriate Content-Type
Database Schemaโ
CREATE TABLE frame_sides (
id INT PRIMARY KEY AUTO_INCREMENT,
frame_id INT NOT NULL,
side ENUM('left', 'right') NOT NULL,
file_url VARCHAR(512),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (frame_id) REFERENCES frames(id) ON DELETE CASCADE
);
CREATE TABLE detections (
id INT PRIMARY KEY AUTO_INCREMENT,
frame_side_id INT NOT NULL,
detection_type ENUM('bee', 'queen', 'cell', 'varroa', 'cup', 'beetle', 'ant'),
bbox_json JSON,
confidence FLOAT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (frame_side_id) REFERENCES frame_sides(id) ON DELETE CASCADE
);
CREATE TABLE jobs (
id INT PRIMARY KEY AUTO_INCREMENT,
type ENUM('resize', 'detect_bees', 'detect_cells', 'detect_queens', 'detect_varroa', 'detect_cups'),
frame_side_id INT NOT NULL,
status ENUM('pending', 'processing', 'completed', 'failed'),
retries INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
processed_at TIMESTAMP NULL
);
CREATE INDEX idx_jobs_status ON jobs(status, created_at);
CREATE INDEX idx_detections_frame_side ON detections(frame_side_id, detection_type);
๐ง Implementation Detailsโ
Frontendโ
- Framework: React with TypeScript
- File Upload: Direct POST to image-splitter (bypasses GraphQL router for large files)
- State Management: Apollo Client cache + local component state
- Optimization:
- Progressive image loading (small โ medium โ large)
- Canvas-based detection rendering with GPU acceleration
- Virtual scrolling for frame lists
- Real-time Updates: GraphQL subscriptions via Redis pub/sub
Backend (image-splitter)โ
- Language: TypeScript/Node.js with Fastify
- Job Queue: MySQL-based persistent queue with retry logic
- Image Processing:
- Jimp for resizing
- webp-converter for format optimization
- 3 thumbnail sizes: 200px, 800px, 1600px
- ML Orchestration: Sequential job processing
- Resize job (creates thumbnails)
- Bee detection (internal model)
- Cell detection (internal model)
- Queen/varroa/cup detection (Clarifai)
- Storage: AWS S3 (production), Minio (development)
- Error Handling: Sentry integration, job retry mechanism (max 3 attempts)
Data Flowโ
๐งช Testingโ
Unit Testsโ
- Location:
/test/unit/upload.test.ts - Coverage: Image validation, thumbnail generation, job creation
- Mock S3 and database interactions
Integration Testsโ
- Location:
/test/integration/upload-flow.test.ts - Tests: Full upload โ storage โ job processing โ detection
- Uses Docker Compose test environment
E2E Testsโ
- Manual testing guide focuses on:
- Upload various image formats (JPEG, PNG, WebP)
- Large file handling (up to 10MB)
- Network interruption recovery
- Concurrent uploads
- Detection visualization accuracy
๐ Performance Considerationsโ
Optimizationsโ
- Direct Upload: Bypasses GraphQL router to reduce latency
- Progressive Loading: Show low-res first (200px) โ upgrade to 800px โ full resolution on zoom
- Lazy Job Processing: Background processing doesn't block upload response
- Connection Pooling: MySQL connection pool (10 connections)
- Batch Detection: Process multiple frames in single ML model request where possible
Bottlenecksโ
- ML model inference time: 5-15 seconds per frame
- Clarifai API rate limits: 10 requests/second
- S3 upload speed: Network dependent
- Large images (>5MB): Slower processing
Metricsโ
- Average upload time: under 2 seconds
- Average processing time: 15-30 seconds (all detections)
- Thumbnail generation: under 3 seconds
- Success rate: over 98%
- Job retry rate: under 5%
๐ซ Technical Limitationsโ
Current Constraintsโ
- File Size: 10MB limit (configurable)
- Formats: JPEG, PNG, WebP only
- Concurrent Uploads: 5 per user (rate limited)
- Processing Queue: FIFO, no prioritization
- Storage: No automatic cleanup of old images
- Thumbnails: Fixed sizes (200px, 800px, 1600px)
Known Issuesโ
- Large portrait images may exceed memory during resize
- Clarifai model precision for queens is low (~60% accuracy)
- No image rotation correction (EXIF orientation ignored)
- Duplicate upload detection missing
๐ Related Documentationโ
๐ Development Resourcesโ
GitHub Repositoriesโ
- image-splitter
- web-app (upload component)
- models-bee-detector
- models-frame-resources
Key Filesโ
- Frontend:
/src/page/hive/frameSide/FileUploader.tsx - Backend:
/src/routes/upload.ts - Job Processor:
/src/jobs/processor.ts - Detection Storage:
/src/db/detections.ts