# Result Manager ## Interface Definition **Interface Name**: `IResultManager` ### Interface Methods ```python class IResultManager(ABC): @abstractmethod def update_frame_result(self, flight_id: str, frame_id: int, result: FrameResult) -> bool: pass @abstractmethod def publish_to_route_api(self, flight_id: str, frame_id: int) -> bool: pass @abstractmethod def get_flight_results(self, flight_id: str) -> FlightResults: pass @abstractmethod def mark_refined(self, flight_id: str, frame_ids: List[int]) -> bool: pass @abstractmethod def get_changed_frames(self, flight_id: str, since: datetime) -> List[int]: pass ``` ## Component Description ### Responsibilities - Manage trajectory results per flight - Track frame refinements and changes - Trigger per-frame Route API updates via G03 - Send incremental updates via F14 SSE - Maintain result versioning for audit trail - Convert optimized poses to GPS coordinates ### Scope - Result state management - Route API integration - SSE event triggering - Incremental update detection - Result persistence ## API Methods ### `update_frame_result(flight_id: str, frame_id: int, result: FrameResult) -> bool` **Description**: Updates result for a processed frame. **Called By**: - Main processing loop (after each frame) - F10 Factor Graph (after refinement) **Input**: ```python flight_id: str frame_id: int result: FrameResult: gps_center: GPSPoint altitude: float heading: float confidence: float timestamp: datetime refined: bool objects: List[ObjectLocation] # From external detector ``` **Output**: `bool` - True if updated **Processing Flow**: 1. Store result in memory/database 2. Call publish_to_route_api() 3. Call G14.send_frame_result() 4. Update flight statistics **Test Cases**: 1. New frame result → stored and published 2. Refined result → updates existing, marks refined=True --- ### `publish_to_route_api(flight_id: str, frame_id: int) -> bool` **Description**: Sends frame GPS to Route API via G03 client. **Called By**: - Internal (after update_frame_result) **Input**: ```python flight_id: str frame_id: int ``` **Output**: `bool` - True if published successfully **Processing Flow**: 1. Get result for frame_id 2. Convert to Waypoint format 3. Call G03.update_route_waypoint() 4. Handle errors (retry if transient) **Test Cases**: 1. Successful publish → Route API updated 2. Route API unavailable → logs error, continues --- ### `get_flight_results(flight_id: str) -> FlightResults` **Description**: Retrieves all results for a flight. **Called By**: - F01 REST API (results endpoint) - Testing/validation **Input**: `flight_id: str` **Output**: ```python FlightResults: flight_id: str frames: List[FrameResult] statistics: FlightStatistics ``` **Test Cases**: 1. Get all results → returns complete trajectory --- ### `mark_refined(flight_id: str, frame_ids: List[int]) -> bool` **Description**: Marks frames as refined after batch optimization. **Called By**: - F10 Factor Graph (after asynchronous refinement) **Input**: ```python flight_id: str frame_ids: List[int] # Frames with updated poses ``` **Output**: `bool` **Processing Flow**: 1. For each frame_id: - Get refined pose from F10 - Convert to GPS via G12 - Update result with refined=True - publish_to_route_api() - Call G14.send_refinement() **Test Cases**: 1. Batch refinement → all frames updated and published --- ### `get_changed_frames(flight_id: str, since: datetime) -> List[int]` **Description**: Gets frames changed since timestamp (for incremental updates). **Called By**: - F14 SSE Event Streamer (for reconnection replay) **Input**: ```python flight_id: str since: datetime ``` **Output**: `List[int]` - Frame IDs changed since timestamp **Test Cases**: 1. Get changes → returns only modified frames 2. No changes → returns empty list ## Integration Tests ### Test 1: Per-Frame Processing 1. Process frame 237 2. update_frame_result() → stores result 3. Verify publish_to_route_api() called 4. Verify F14 SSE event sent ### Test 2: Batch Refinement 1. Process 100 frames 2. Factor graph refines frames 10-50 3. mark_refined([10-50]) → updates all 4. Verify Route API updated 5. Verify SSE refinement events sent ### Test 3: Incremental Updates 1. Process frames 1-100 2. Client disconnects at frame 50 3. Client reconnects 4. get_changed_frames(since=frame_50_time) 5. Client receives frames 51-100 ## Non-Functional Requirements ### Performance - **update_frame_result**: < 50ms - **publish_to_route_api**: < 100ms (non-blocking) - **get_flight_results**: < 200ms for 2000 frames ### Reliability - Result persistence survives crashes - Guaranteed at-least-once delivery to Route API - Idempotent updates ## Dependencies ### Internal Components - G03 Route API Client - F10 Factor Graph Optimizer - F12 Coordinate Transformer - F14 SSE Event Streamer - F17 Database Layer ### External Dependencies - None ## Data Models ### FrameResult ```python class ObjectLocation(BaseModel): object_id: str pixel: Tuple[float, float] gps: GPSPoint class_name: str confidence: float class FrameResult(BaseModel): frame_id: int gps_center: GPSPoint altitude: float heading: float confidence: float timestamp: datetime refined: bool objects: List[ObjectLocation] updated_at: datetime ``` ### FlightResults ```python class FlightStatistics(BaseModel): total_frames: int processed_frames: int refined_frames: int mean_confidence: float processing_time: float class FlightResults(BaseModel): flight_id: str frames: List[FrameResult] statistics: FlightStatistics ```