mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 01:56:37 +00:00
add features
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# Feature: Flight Management
|
||||
|
||||
## Description
|
||||
Core REST endpoints for flight lifecycle management including CRUD operations, status retrieval, and waypoint management. This feature provides the fundamental data operations for flight entities.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `create_flight(flight_data: FlightCreateRequest) -> FlightResponse`
|
||||
- `get_flight(flight_id: str) -> FlightDetailResponse`
|
||||
- `delete_flight(flight_id: str) -> DeleteResponse`
|
||||
- `get_flight_status(flight_id: str) -> FlightStatusResponse`
|
||||
- `update_waypoint(flight_id: str, waypoint_id: str, waypoint: Waypoint) -> UpdateResponse`
|
||||
- `batch_update_waypoints(flight_id: str, waypoints: List[Waypoint]) -> BatchUpdateResponse`
|
||||
|
||||
## REST Endpoints
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/flights` | Create new flight |
|
||||
| GET | `/flights/{flightId}` | Get flight details |
|
||||
| DELETE | `/flights/{flightId}` | Delete flight |
|
||||
| GET | `/flights/{flightId}/status` | Get processing status |
|
||||
| PUT | `/flights/{flightId}/waypoints/{waypointId}` | Update single waypoint |
|
||||
| PUT | `/flights/{flightId}/waypoints/batch` | Batch update waypoints |
|
||||
|
||||
## External Tools and Services
|
||||
- **FastAPI**: Web framework for REST endpoints
|
||||
- **Pydantic**: Request/response validation and serialization
|
||||
- **Uvicorn**: ASGI server
|
||||
|
||||
## Internal Methods
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `_validate_gps_coordinates(lat, lon)` | Validate GPS coordinate ranges |
|
||||
| `_validate_camera_params(params)` | Validate camera parameter values |
|
||||
| `_validate_geofences(geofences)` | Validate geofence polygon data |
|
||||
| `_build_flight_response(flight_data)` | Build response from F02 result |
|
||||
| `_build_status_response(status_data)` | Build status response |
|
||||
|
||||
## Unit Tests
|
||||
1. **create_flight validation**
|
||||
- Valid request → calls F02.create_flight() and returns 201
|
||||
- Missing required field (name) → returns 400
|
||||
- Invalid GPS (lat > 90) → returns 400
|
||||
- Invalid camera params → returns 400
|
||||
|
||||
2. **get_flight**
|
||||
- Valid flight_id → returns 200 with flight data
|
||||
- Non-existent flight_id → returns 404
|
||||
|
||||
3. **delete_flight**
|
||||
- Valid flight_id → returns 200
|
||||
- Non-existent flight_id → returns 404
|
||||
- Processing flight → returns 409
|
||||
|
||||
4. **get_flight_status**
|
||||
- Valid flight_id → returns 200 with status
|
||||
- Non-existent flight_id → returns 404
|
||||
|
||||
5. **update_waypoint**
|
||||
- Valid update → returns 200
|
||||
- Invalid waypoint_id → returns 404
|
||||
- Invalid coordinates → returns 400
|
||||
|
||||
6. **batch_update_waypoints**
|
||||
- Valid batch → returns success with updated_count
|
||||
- Empty batch → returns success, updated_count=0
|
||||
- Partial failures → returns failed_ids
|
||||
|
||||
## Integration Tests
|
||||
1. **Flight lifecycle**
|
||||
- POST /flights → GET /flights/{id} → DELETE /flights/{id}
|
||||
- Verify data consistency across operations
|
||||
|
||||
2. **Waypoint updates during processing**
|
||||
- Create flight → Process frames → Verify waypoints updated
|
||||
- Simulate refinement updates → Verify refined=true
|
||||
|
||||
3. **Concurrent operations**
|
||||
- Create 10 flights concurrently → All succeed
|
||||
- Batch update 500 waypoints → All succeed
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Feature: Image Batch Upload
|
||||
|
||||
## Description
|
||||
REST endpoint for uploading batches of UAV images for processing. Handles multipart form data with 10-50 images per request, validates sequence numbers, and queues images for async processing via F02.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `upload_image_batch(flight_id: str, batch: ImageBatch) -> BatchResponse`
|
||||
|
||||
## REST Endpoints
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/flights/{flightId}/images/batch` | Upload batch of 10-50 images |
|
||||
|
||||
## External Tools and Services
|
||||
- **FastAPI**: Web framework for REST endpoints
|
||||
- **python-multipart**: Multipart form data handling
|
||||
- **Pydantic**: Validation
|
||||
|
||||
## Internal Methods
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `_validate_batch_size(images)` | Validate batch contains 10-50 images |
|
||||
| `_validate_sequence_numbers(metadata)` | Validate start/end sequence are valid |
|
||||
| `_validate_sequence_continuity(flight_id, start_seq)` | Validate sequence continues from last batch |
|
||||
| `_parse_multipart_images(request)` | Parse multipart form data into image list |
|
||||
| `_validate_image_format(image)` | Validate image file is valid JPEG/PNG |
|
||||
| `_build_batch_response(result)` | Build response with accepted sequences |
|
||||
|
||||
## Unit Tests
|
||||
1. **Batch size validation**
|
||||
- 20 images → accepted
|
||||
- 9 images → returns 400 (too few)
|
||||
- 51 images → returns 400 (too many)
|
||||
|
||||
2. **Sequence validation**
|
||||
- Valid sequence (start=100, end=119) → accepted
|
||||
- Invalid sequence (start > end) → returns 400
|
||||
- Gap in sequence → returns 400
|
||||
|
||||
3. **Flight validation**
|
||||
- Valid flight_id → accepted
|
||||
- Non-existent flight_id → returns 404
|
||||
|
||||
4. **Image validation**
|
||||
- Valid JPEG images → accepted
|
||||
- Corrupted image → returns 400
|
||||
- Non-image file → returns 400
|
||||
|
||||
5. **Size limits**
|
||||
- 50 × 2MB images → accepted
|
||||
- Batch > 500MB → returns 413
|
||||
|
||||
## Integration Tests
|
||||
1. **Sequential batch uploads**
|
||||
- Upload batch 1 (seq 0-49) → success
|
||||
- Upload batch 2 (seq 50-99) → success
|
||||
- Verify next_expected increments correctly
|
||||
|
||||
2. **Large image handling**
|
||||
- Upload 50 × 8MB images → success within timeout
|
||||
- Verify all images queued for processing
|
||||
|
||||
3. **Rate limiting**
|
||||
- Rapid consecutive uploads → eventually returns 429
|
||||
- Wait and retry → succeeds
|
||||
|
||||
4. **Concurrent uploads to same flight**
|
||||
- Two clients upload different batches → both succeed
|
||||
- Verify sequence integrity maintained
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# Feature: User Interaction
|
||||
|
||||
## Description
|
||||
REST endpoints for user-triggered operations: submitting GPS fixes for blocked flights and converting detected object pixel coordinates to GPS. These endpoints support the human-in-the-loop workflow when automated localization fails.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `submit_user_fix(flight_id: str, fix_data: UserFixRequest) -> UserFixResponse`
|
||||
- `convert_object_to_gps(flight_id: str, frame_id: int, pixel: Tuple[float, float]) -> ObjectGPSResponse`
|
||||
|
||||
## REST Endpoints
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/flights/{flightId}/user-fix` | Submit user-provided GPS anchor |
|
||||
| POST | `/flights/{flightId}/frames/{frameId}/object-to-gps` | Convert pixel to GPS |
|
||||
|
||||
## External Tools and Services
|
||||
- **FastAPI**: Web framework for REST endpoints
|
||||
- **Pydantic**: Request/response validation
|
||||
|
||||
## Internal Methods
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `_validate_user_fix_request(fix_data)` | Validate pixel and GPS coordinates |
|
||||
| `_validate_flight_blocked(flight_id)` | Verify flight is in blocked state |
|
||||
| `_validate_frame_processed(flight_id, frame_id)` | Verify frame has pose in Factor Graph |
|
||||
| `_validate_pixel_coordinates(pixel, resolution)` | Validate pixel within image bounds |
|
||||
| `_build_user_fix_response(result)` | Build response with processing status |
|
||||
| `_build_object_gps_response(result)` | Build GPS response with accuracy |
|
||||
|
||||
## Unit Tests
|
||||
1. **submit_user_fix validation**
|
||||
- Valid request for blocked flight → returns 200, processing_resumed=true
|
||||
- Flight not blocked → returns 409
|
||||
- Invalid GPS coordinates → returns 400
|
||||
- Non-existent flight_id → returns 404
|
||||
|
||||
2. **submit_user_fix pixel validation**
|
||||
- Pixel within image bounds → accepted
|
||||
- Negative pixel coordinates → returns 400
|
||||
- Pixel outside image bounds → returns 400
|
||||
|
||||
3. **convert_object_to_gps validation**
|
||||
- Valid processed frame → returns GPS with accuracy
|
||||
- Frame not yet processed → returns 409
|
||||
- Non-existent frame_id → returns 404
|
||||
- Invalid pixel coordinates → returns 400
|
||||
|
||||
4. **convert_object_to_gps accuracy**
|
||||
- High confidence frame → low accuracy_meters
|
||||
- Low confidence frame → high accuracy_meters
|
||||
|
||||
## Integration Tests
|
||||
1. **User fix unblocks processing**
|
||||
- Process until blocked → Submit user fix → Verify processing resumes
|
||||
- Verify SSE `processing_resumed` event sent
|
||||
|
||||
2. **Object-to-GPS workflow**
|
||||
- Process flight → Call object-to-gps for multiple pixels
|
||||
- Verify GPS coordinates are spatially consistent
|
||||
|
||||
3. **User fix with invalid anchor**
|
||||
- Submit fix with GPS far outside geofence
|
||||
- Verify appropriate error handling
|
||||
|
||||
4. **Concurrent object-to-gps calls**
|
||||
- Multiple clients request conversion simultaneously
|
||||
- All receive correct responses
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# Feature: SSE Streaming
|
||||
|
||||
## Description
|
||||
Server-Sent Events (SSE) endpoint for real-time streaming of flight processing results to clients. Manages SSE connections, handles keepalive, and supports client reconnection with event replay.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `create_sse_stream(flight_id: str) -> SSEStream`
|
||||
|
||||
## REST Endpoints
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/flights/{flightId}/stream` | Open SSE connection |
|
||||
|
||||
## SSE Events
|
||||
| Event Type | Description |
|
||||
|------------|-------------|
|
||||
| `frame_processed` | New frame GPS calculated |
|
||||
| `frame_refined` | Previous frame GPS refined |
|
||||
| `search_expanded` | Search grid expanded |
|
||||
| `user_input_needed` | User input required |
|
||||
| `processing_blocked` | Processing halted |
|
||||
| `flight_completed` | Flight processing finished |
|
||||
|
||||
## External Tools and Services
|
||||
- **FastAPI**: Web framework with SSE support
|
||||
- **sse-starlette**: SSE event streaming library
|
||||
- **asyncio**: Async event handling
|
||||
|
||||
## Internal Methods
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `_validate_flight_exists(flight_id)` | Verify flight exists before connecting |
|
||||
| `_create_sse_response(flight_id)` | Create SSE StreamingResponse |
|
||||
| `_event_generator(flight_id, client_id)` | Async generator yielding events |
|
||||
| `_handle_client_disconnect(client_id)` | Cleanup on client disconnect |
|
||||
| `_send_keepalive()` | Send ping every 30 seconds |
|
||||
| `_replay_missed_events(last_event_id)` | Replay events since last_event_id |
|
||||
| `_format_sse_event(event_type, data)` | Format event for SSE protocol |
|
||||
|
||||
## Unit Tests
|
||||
1. **Connection establishment**
|
||||
- Valid flight_id → SSE connection opens
|
||||
- Non-existent flight_id → returns 404
|
||||
- Invalid flight_id format → returns 400
|
||||
|
||||
2. **Event formatting**
|
||||
- frame_processed event → correct JSON structure
|
||||
- All event types → valid SSE format with id, event, data
|
||||
|
||||
3. **Keepalive**
|
||||
- No events for 30s → ping sent
|
||||
- Connection stays alive during idle periods
|
||||
|
||||
4. **Client disconnect handling**
|
||||
- Client closes connection → resources cleaned up
|
||||
- No memory leaks on disconnect
|
||||
|
||||
## Integration Tests
|
||||
1. **Full event flow**
|
||||
- Connect to stream → Upload images → Receive all frame_processed events
|
||||
- Verify event count matches frames processed
|
||||
|
||||
2. **Event ordering**
|
||||
- Process 100 frames → events received in order
|
||||
- Event IDs are sequential
|
||||
|
||||
3. **Reconnection with replay**
|
||||
- Connect → Process 50 frames → Disconnect → Reconnect with last_event_id
|
||||
- Receive missed events since last_event_id
|
||||
|
||||
4. **user_input_needed flow**
|
||||
- Process until blocked → Receive user_input_needed event
|
||||
- Submit user fix → Receive processing_resumed confirmation
|
||||
|
||||
5. **Multiple concurrent clients**
|
||||
- 10 clients connect to same flight
|
||||
- All receive same events
|
||||
- No cross-contamination between flights
|
||||
|
||||
6. **Long-running stream**
|
||||
- Stream 2000 frames over extended period
|
||||
- Connection remains stable
|
||||
- All events delivered
|
||||
|
||||
7. **Flight completion**
|
||||
- Process all frames → Receive flight_completed event
|
||||
- Stream closes gracefully
|
||||
|
||||
Reference in New Issue
Block a user