component decomposition is done

This commit is contained in:
Oleksandr Bezdieniezhnykh
2025-11-24 14:09:23 +02:00
parent acec83018b
commit f50006d100
34 changed files with 8637 additions and 0 deletions
@@ -0,0 +1,338 @@
# Route Data Manager
## Interface Definition
**Interface Name**: `IRouteDataManager`
### Interface Methods
```python
class IRouteDataManager(ABC):
@abstractmethod
def save_route(self, route: Route) -> str:
pass
@abstractmethod
def load_route(self, route_id: str) -> Optional[Route]:
pass
@abstractmethod
def update_waypoint(self, route_id: str, waypoint_id: str, waypoint: Waypoint) -> bool:
pass
@abstractmethod
def delete_waypoint(self, route_id: str, waypoint_id: str) -> bool:
pass
@abstractmethod
def get_route_metadata(self, route_id: str) -> Optional[RouteMetadata]:
pass
@abstractmethod
def delete_route(self, route_id: str) -> bool:
pass
```
## Component Description
### Responsibilities
- Manage route persistence and retrieval
- Coordinate with Route Database Layer for data operations
- Handle waypoint CRUD operations within routes
- Manage route metadata (timestamps, statistics)
- Ensure data consistency and transaction management
### Scope
- Business logic layer between REST API and Database Layer
- Route lifecycle management
- Waypoint batch operations
- Query optimization for large route datasets
- Caching layer for frequently accessed routes (optional)
## API Methods
### `save_route(route: Route) -> str`
**Description**: Persists a new route with initial waypoints and geofences.
**Called By**:
- R01 Route REST API
**Input**:
```python
Route:
id: Optional[str] # Generated if not provided
name: str
description: str
points: List[Waypoint]
geofences: Geofences
```
**Output**:
```python
route_id: str # UUID of saved route
```
**Error Conditions**:
- `DuplicateRouteError`: Route with same ID exists
- `ValidationError`: Invalid route data
- `DatabaseError`: Database connection or constraint violation
**Test Cases**:
1. **New route**: Valid route → returns routeId, verifies in DB
2. **Route with 1000 waypoints**: Large route → saves successfully
3. **Duplicate ID**: Existing route ID → raises DuplicateRouteError
4. **Transaction rollback**: DB error mid-save → no partial data persisted
---
### `load_route(route_id: str) -> Optional[Route]`
**Description**: Retrieves complete route data including all waypoints.
**Called By**:
- R01 Route REST API
- R03 Waypoint Validator (for context validation)
**Input**:
```python
route_id: str
```
**Output**:
```python
Route or None if not found
```
**Error Conditions**:
- `DatabaseError`: Database connection error
- Returns `None`: Route not found (not an error condition)
**Test Cases**:
1. **Existing route**: Valid ID → returns complete Route object
2. **Non-existent route**: Invalid ID → returns None
3. **Large route**: 3000 waypoints → returns all data efficiently
4. **Concurrent reads**: Multiple simultaneous loads → all succeed
---
### `update_waypoint(route_id: str, waypoint_id: str, waypoint: Waypoint) -> bool`
**Description**: Updates a single waypoint within a route. Optimized for high-frequency GPS-Denied updates.
**Called By**:
- R01 Route REST API
**Input**:
```python
route_id: str
waypoint_id: str
waypoint: Waypoint
```
**Output**:
```python
bool: True if updated, False if route/waypoint not found
```
**Error Conditions**:
- `ValidationError`: Invalid waypoint data
- `DatabaseError`: Database error
**Test Cases**:
1. **Update existing waypoint**: Valid data → returns True
2. **Non-existent waypoint**: Invalid waypoint_id → returns False
3. **Concurrent updates**: 100 simultaneous updates to different waypoints → all succeed
4. **Update timestamp**: Automatically updates route.updated_at
---
### `delete_waypoint(route_id: str, waypoint_id: str) -> bool`
**Description**: Deletes a specific waypoint from a route.
**Called By**:
- R01 Route REST API (rare, for manual corrections)
**Input**:
```python
route_id: str
waypoint_id: str
```
**Output**:
```python
bool: True if deleted, False if not found
```
**Error Conditions**:
- `DatabaseError`: Database error
**Test Cases**:
1. **Delete existing waypoint**: Valid IDs → returns True
2. **Delete non-existent waypoint**: Invalid ID → returns False
3. **Delete all waypoints**: Delete all waypoints one by one → succeeds
---
### `get_route_metadata(route_id: str) -> Optional[RouteMetadata]`
**Description**: Retrieves route metadata without loading all waypoints (lightweight operation).
**Called By**:
- R01 Route REST API
- Client applications (route listing)
**Input**:
```python
route_id: str
```
**Output**:
```python
RouteMetadata:
route_id: str
name: str
description: str
waypoint_count: int
created_at: datetime
updated_at: datetime
```
**Error Conditions**:
- Returns `None`: Route not found
**Test Cases**:
1. **Get metadata**: Valid ID → returns metadata without waypoints
2. **Performance**: Metadata retrieval < 50ms even for 3000-waypoint route
---
### `delete_route(route_id: str) -> bool`
**Description**: Deletes a route and all associated waypoints.
**Called By**:
- R01 Route REST API
**Input**:
```python
route_id: str
```
**Output**:
```python
bool: True if deleted, False if not found
```
**Error Conditions**:
- `DatabaseError`: Database error
**Test Cases**:
1. **Delete route**: Valid ID → deletes route and all waypoints
2. **Cascade delete**: Verify all waypoints deleted
3. **Non-existent route**: Invalid ID → returns False
## Integration Tests
### Test 1: Complete Route Lifecycle
1. save_route() with 100 waypoints
2. load_route() and verify all data
3. update_waypoint() for 50 waypoints
4. delete_waypoint() for 10 waypoints
5. get_route_metadata() and verify count
6. delete_route() and verify removal
### Test 2: High-Frequency Update Simulation (GPS-Denied Pattern)
1. save_route() with 2000 waypoints
2. Simulate per-frame updates: update_waypoint() × 2000 in sequence
3. Verify all updates persisted correctly
4. Measure total time < 200 seconds (100ms per update)
### Test 3: Concurrent Route Operations
1. Create 10 routes concurrently
2. Update different waypoints in parallel (100 concurrent updates)
3. Delete 5 routes concurrently while updating others
4. Verify data consistency
## Non-Functional Requirements
### Performance
- **save_route**: < 300ms for routes with 100 waypoints
- **load_route**: < 150ms for routes with 2000 waypoints
- **update_waypoint**: < 50ms (critical path for GPS-Denied)
- **get_route_metadata**: < 30ms
- **delete_route**: < 200ms
### Scalability
- Support 1000+ concurrent route operations
- Handle routes with up to 3000 waypoints efficiently
- Optimize for read-heavy workload (90% reads, 10% writes)
### Reliability
- ACID transaction guarantees
- Automatic retry on transient database errors (3 attempts)
- Data validation before persistence
### Maintainability
- Clear separation from database implementation
- Support for future caching layer integration
- Comprehensive error handling and logging
## Dependencies
### Internal Components
- **R03 Waypoint Validator**: Validates waypoints before persistence
- **R04 Route Database Layer**: For all database operations
### External Dependencies
- None (pure business logic layer)
## Data Models
### Route
```python
class Route(BaseModel):
id: str # UUID
name: str
description: str
points: List[Waypoint]
geofences: Geofences
created_at: datetime
updated_at: datetime
```
### RouteMetadata
```python
class RouteMetadata(BaseModel):
route_id: str
name: str
description: str
waypoint_count: int
geofence_count: int
created_at: datetime
updated_at: datetime
```
### Waypoint
```python
class Waypoint(BaseModel):
id: str
lat: float
lon: float
altitude: Optional[float]
confidence: float
timestamp: datetime
refined: bool
```
### Geofences
```python
class Polygon(BaseModel):
north_west: GPSPoint
south_east: GPSPoint
class Geofences(BaseModel):
polygons: List[Polygon]
```