diff --git a/specs/001-surveillance-api/data-model.md b/specs/001-surveillance-api/data-model.md index 3015e89..1f1e259 100644 --- a/specs/001-surveillance-api/data-model.md +++ b/specs/001-surveillance-api/data-model.md @@ -681,35 +681,428 @@ class AuditOutcome(str, Enum): --- +## 6. Unified Architecture Entities + +### 6.1 GeViScope Instance + +Represents a configured GeViScope server (GSCServer) connection. + +**Schema**: +```python +class GeViScopeInstance(BaseModel): + id: str = Field(..., pattern="^[a-z][a-z0-9-]*$") # "main", "parking", "warehouse" + name: str = Field(min_length=1, max_length=100) + description: Optional[str] = Field(max_length=500) + host: str # Hostname or IP address + port: int = Field(default=7700, ge=1, le=65535) + username: str + # Password stored securely (not in database) + is_default: bool = False + enabled: bool = True + connection_status: ConnectionStatus + last_connected: Optional[datetime] = None + camera_count: int = 0 + monitor_count: int = 0 + sdk_version: Optional[str] = None + created_at: datetime + updated_at: datetime + +class ConnectionStatus(str, Enum): + CONNECTED = "connected" + DISCONNECTED = "disconnected" + CONNECTING = "connecting" + ERROR = "error" +``` + +**Validation Rules**: +- `id`: Lowercase alphanumeric with dashes, starts with letter +- `host`: Valid hostname or IP address +- `is_default`: Only one instance can be default +- `enabled`: Disabled instances not available for operations + +**Relationships**: +- GeViScopeInstance → Camera (one-to-many) +- GeViScopeInstance → Monitor (one-to-many) +- GeViScopeInstance → CrossSwitchRoute (one-to-many) + +**Example**: +```json +{ + "id": "main", + "name": "Main Building", + "description": "Primary surveillance system", + "host": "localhost", + "port": 7700, + "username": "sysadmin", + "is_default": true, + "enabled": true, + "connection_status": "connected", + "last_connected": "2025-12-10T14:00:00Z", + "camera_count": 13, + "monitor_count": 256, + "sdk_version": "7.9.975.68" +} +``` + +--- + +### 6.2 Monitor (Video Output) + +Represents a video output channel (logical display channel, not physical display). + +**Schema**: +```python +class Monitor(BaseModel): + id: int # Monitor ID from GeViScope (1-256) + geviscope_instance_id: str # Which GeViScope instance + global_id: str # GeViScope GlobalID + name: str = Field(min_length=1, max_length=100) + description: Optional[str] = Field(max_length=500) + is_active: bool = True + is_enabled: bool = True + current_camera_id: Optional[int] = None # Currently routed camera + current_route_id: Optional[UUID] = None + status: MonitorStatus + created_at: datetime + updated_at: datetime + +class MonitorStatus(str, Enum): + ONLINE = "online" + OFFLINE = "offline" + ERROR = "error" +``` + +**Important Notes**: +- Monitors are **logical routing channels**, not physical displays +- CrossSwitch routes video to monitors at the server level +- **Viewer applications (GSCView)** required to actually display monitor video +- Monitor enumeration may return more IDs than physical outputs exist + +**Validation Rules**: +- `id`: Positive integer, unique within GeViScope instance +- `geviscope_instance_id`: Must reference existing instance +- `current_camera_id`: If set, must reference existing camera + +**Relationships**: +- Monitor → GeViScopeInstance (many-to-one) +- Monitor → Camera (many-to-one, optional via current_camera_id) +- Monitor → CrossSwitchRoute (one-to-many) + +**Example**: +```json +{ + "id": 1, + "geviscope_instance_id": "main", + "global_id": "b8c2d4e6-f7a8-49b0-c1d2-e3f4a5b6c7d8", + "name": "Video Output 1", + "description": "Main control room display", + "is_active": true, + "is_enabled": true, + "current_camera_id": 101038, + "current_route_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", + "status": "online" +} +``` + +--- + +### 6.3 CrossSwitch Route + +Represents an active or historical video routing (camera → monitor). + +**Schema**: +```python +class CrossSwitchRoute(BaseModel): + id: UUID = Field(default_factory=uuid4) + geviscope_instance_id: str # Which GeViScope instance + camera_id: int # Video input channel + monitor_id: int # Video output channel + mode: int = 0 # 0=normal (sm_Normal) + is_active: bool = True # False when cleared + executed_at: datetime + executed_by: UUID # User who created route + executed_by_username: str + cleared_at: Optional[datetime] = None + cleared_by: Optional[UUID] = None + sdk_success: bool = True # SDK execution result + sdk_message: Optional[str] = None + camera_name: Optional[str] = None # Cached camera info + monitor_name: Optional[str] = None # Cached monitor info + +class CrossSwitchRequest(BaseModel): + """Request model for cross-switch operation""" + camera_id: int = Field(ge=1) + monitor_id: int = Field(ge=1) + mode: int = Field(default=0, ge=0, le=2) + +class CrossSwitchResponse(BaseModel): + """Response model for cross-switch operation""" + success: bool + message: str + route: CrossSwitchRoute +``` + +**State Transitions**: +``` +Created (is_active=True) → Cleared (is_active=False) +``` + +**Validation Rules**: +- `camera_id`: Must exist and be online in the GeViScope instance +- `monitor_id`: Must exist in the GeViScope instance +- `mode`: 0=normal (sm_Normal), other modes reserved +- `executed_by`: Must be authenticated user + +**Relationships**: +- CrossSwitchRoute → GeViScopeInstance (many-to-one) +- CrossSwitchRoute → Camera (many-to-one) +- CrossSwitchRoute → Monitor (many-to-one) +- CrossSwitchRoute → User (executed_by, many-to-one) + +**Example**: +```json +{ + "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", + "geviscope_instance_id": "main", + "camera_id": 101038, + "monitor_id": 1, + "mode": 0, + "is_active": true, + "executed_at": "2025-12-10T14:30:00Z", + "executed_by": "550e8400-e29b-41d4-a716-446655440000", + "executed_by_username": "admin", + "sdk_success": true, + "sdk_message": "Cross-switch executed successfully", + "camera_name": "Entrance Camera", + "monitor_name": "Video Output 1" +} +``` + +--- + +### 6.4 Alarm (GeViSoft) + +Represents a system-wide alarm configuration in GeViSoft. + +**Schema**: +```python +class Alarm(BaseModel): + id: UUID = Field(default_factory=uuid4) + alarm_id: int # GeViSoft alarm ID + name: str = Field(min_length=1, max_length=100) + description: Optional[str] = Field(max_length=500) + priority: AlarmPriority + monitor_group_id: Optional[int] = None + cameras: List[int] = [] # Camera channels + start_actions: List[str] = [] # Actions on alarm start + stop_actions: List[str] = [] # Actions on alarm stop + acknowledge_actions: List[str] = [] # Actions on acknowledge + is_active: bool = False + triggered_at: Optional[datetime] = None + acknowledged_at: Optional[datetime] = None + acknowledged_by: Optional[UUID] = None + created_at: datetime + updated_at: datetime + +class AlarmPriority(str, Enum): + LOW = "low" + MEDIUM = "medium" + HIGH = "high" + CRITICAL = "critical" +``` + +**Validation Rules**: +- `alarm_id`: Positive integer, unique +- `cameras`: All camera IDs must exist +- `start_actions`: Valid GeViSoft action strings +- `is_active`: Set true when triggered, false when acknowledged/stopped + +**Relationships**: +- Alarm → Camera (many-to-many via cameras list) +- Alarm → User (acknowledged_by, many-to-one, optional) + +--- + +### 6.5 Action Mapping + +Represents automation rules in GeViSoft (input action → output actions). + +**Schema**: +```python +class ActionMapping(BaseModel): + id: UUID = Field(default_factory=uuid4) + name: str = Field(min_length=1, max_length=100) + description: Optional[str] = Field(max_length=500) + input_action: str # GeViSoft action that triggers mapping + output_actions: List[str] # Actions to execute + geviscope_instance_scope: Optional[str] = None # Limit to specific instance + enabled: bool = True + execution_count: int = 0 + last_executed: Optional[datetime] = None + created_at: datetime + updated_at: datetime + created_by: UUID + +class ActionMappingExecution(BaseModel): + """Execution log for action mappings""" + id: UUID = Field(default_factory=uuid4) + mapping_id: UUID + input_action: str + output_actions_executed: List[str] + success: bool + error_message: Optional[str] = None + executed_at: datetime +``` + +**Validation Rules**: +- `input_action`: Valid GeViSoft action format +- `output_actions`: Valid GeViSoft action formats +- `geviscope_instance_scope`: If set, must reference existing instance + +**Example**: +```json +{ + "id": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6", + "name": "Motion Detection Alert", + "description": "Route cameras to monitors when motion detected", + "input_action": "VMD_Start(101038)", + "output_actions": [ + "CrossSwitch(101038, 1, 0)", + "SendMail(security@example.com, Motion Detected)" + ], + "geviscope_instance_scope": "main", + "enabled": true, + "execution_count": 42, + "last_executed": "2025-12-10T14:00:00Z" +} +``` + +--- + +### 6.6 G-Core Server + +Represents a configured G-Core server (remote surveillance server connection) in GeViSoft. + +**Schema**: +```python +class GCoreServer(BaseModel): + id: str = Field(..., pattern="^[0-9]+$") # Numeric string ID + alias: str = Field(min_length=1, max_length=100) # Display name + host: str = Field(min_length=1, max_length=255) # IP address or hostname + user: str = Field(default="admin", max_length=100) # Username + password: str = Field(max_length=100) # Password (encrypted in storage) + enabled: bool = True # Enable/disable server + deactivate_echo: bool = False # Deactivate echo + deactivate_live_check: bool = False # Deactivate live check + created_at: datetime + updated_at: datetime + created_by: UUID + +class GCoreServerInput(BaseModel): + """Request model for creating/updating G-Core server""" + alias: str = Field(min_length=1, max_length=100) + host: str = Field(min_length=1, max_length=255) + user: str = Field(default="admin", max_length=100) + password: str = Field(max_length=100) + enabled: bool = True + deactivate_echo: bool = False + deactivate_live_check: bool = False +``` + +**Implementation Notes**: +- ID is auto-incremented based on highest existing numeric server ID +- Field order in configuration tree must be: Alias, DeactivateEcho, DeactivateLiveCheck, Enabled, Host, Password, User +- Bool fields must use type code 1 (bool) not type code 4 (int32) for GeViSet compatibility +- Password stored as plain text in GeViSoft configuration (SDK limitation) + +**Validation Rules**: +- `id`: Numeric string, auto-generated on CREATE +- `alias`: Required, display name for server +- `host`: Required, valid IP address or hostname +- `user`: Defaults to "admin" if not provided +- `enabled`: Controls whether server is active + +**Relationships**: +- GCoreServer → User (created_by, many-to-one) +- Configuration stored in GeViSoft .set file under GeViGCoreServer folder + +**Example**: +```json +{ + "id": "2", + "alias": "Remote Office Server", + "host": "192.168.1.100", + "user": "admin", + "password": "secure_password", + "enabled": true, + "deactivate_echo": false, + "deactivate_live_check": false, + "created_at": "2025-12-16T10:00:00Z" +} +``` + +**CRUD Operations** (2025-12-16): +- ✅ CREATE: Working - creates server with auto-incremented ID +- ✅ READ: Working - reads all servers or single server by ID +- ⚠️ UPDATE: Known bug - requires fix for "Server ID is required" error +- ✅ DELETE: Working - deletes server by ID + +**Critical Implementation Details**: +- **Cascade Deletion Prevention**: When deleting multiple servers, always delete in reverse order (highest ID first) to prevent ID shifting +- **Bool Type Handling**: Must write as bool type (type code 1) not int32, even though GeViSoft stores as int32 +- **SetupClient Required**: All configuration changes must use SetupClient for download/upload to ensure atomicity + +--- + ## Entity Relationships Diagram ``` -┌─────────┐ ┌─────────────┐ ┌────────────┐ -│ User │──1:N──│ Session │ │ AuditLog │ -└────┬────┘ └─────────────┘ └─────┬──────┘ - │ │ - │1:N │N:1 - │ │ - ▼ │ -┌─────────────────┐ │ -│ EventSubscription│ │ -└─────────────────┘ │ - │ -┌────────────┐ ┌─────────┐ ┌──────▼─────┐ -│ Camera │──1:N──│ Stream │ │ Recording │ -└─────┬──────┘ └─────────┘ └──────┬─────┘ - │ │ - │1:N │N:1 - ▼ │ -┌─────────────────┐ │ -│ AnalyticsConfig │ │ -└─────────────────┘ │ - │ │ - │1:N │ - ▼ ▼ -┌─────────────┐ ┌────────────────────────────┐ -│ PTZPreset │ │ Event │ -└─────────────┘ └────────────────────────────┘ +┌────────────────────┐ +│ GeViScopeInstance │──┐ +└────────────────────┘ │ + │1:N + ┌────────────┴──────────────┐ + │ │ + ▼ ▼ +┌────────────┐ ┌────────────┐ ┌─────────────────┐ +│ Camera │──1:N──│ Stream │ │ Monitor │ +└─────┬──────┘ └─────────┘ └────────┬────────┘ + │ │ + │1:N │1:N + ▼ ▼ +┌─────────────────┐ ┌───────────────────┐ +│ AnalyticsConfig │ │ CrossSwitchRoute │ +└─────────────────┘ └─────────┬─────────┘ + │ │ + │1:N │N:1 + ▼ │ +┌─────────────┐ │ +│ PTZPreset │ │ +└─────────────┘ ▼ + ┌─────────┐ +┌─────────┐ ┌─────────────┐ │ User │──1:N──┌──────────────────┐ +│ User │──1:N──│ Session │ └────┬────┘ │ EventSubscription│ +└────┬────┘ └─────────────┘ │ └──────────────────┘ + │ │1:N + │1:N │ + ▼ ▼ +┌────────────┐ ┌──────────────┐ +│ AuditLog │ │ Alarm │ +└────────────┘ └──────────────┘ + │M:N + ▼ + ┌────────────┐ + │ Camera │ + └────────────┘ + +┌──────────────────┐ ┌──────────┐ +│ ActionMapping │──1:N──│ Event │ +└──────────────────┘ └────┬─────┘ + │N:1 + ▼ + ┌──────────────┐ + │ Recording │ + └──────────────┘ ``` --- @@ -720,13 +1113,19 @@ class AuditOutcome(str, Enum): |--------|-----------------| | User | Unique username/email, valid role, bcrypt password | | Session | Valid JWT, IP address, TTL enforced | +| GeViScopeInstance | Unique ID, valid host, only one default | | Camera | Valid channel ID, status from SDK, capabilities match | +| Monitor | Valid ID within instance, scoped by instance ID | +| CrossSwitchRoute | Camera/monitor exist and online, valid user | | Stream | Camera online, token authentication, supported formats | | Recording | Valid time range, camera exists, ring buffer aware | | Event | Valid type, severity, camera permissions | | EventSubscription | User has camera permissions | | AnalyticsConfig | Camera supports type, valid zones/settings | | PTZPreset | Camera has PTZ, valid coordinates | +| Alarm (GeViSoft) | Valid alarm ID, cameras exist, valid actions | +| ActionMapping | Valid action formats, instance scope if specified | +| GCoreServer | Numeric ID, valid host, bool type handling | | AuditLog | Immutable, complete metadata | --- @@ -764,5 +1163,26 @@ class AuditOutcome(str, Enum): --- -**Phase 1 Status**: ✅ Data model complete -**Next**: Generate OpenAPI contracts +## CrossSwitch Route State Machine +``` +[Created] (is_active=True) ──clear_monitor──▶ [Cleared] (is_active=False) + │ + └──new_crossswitch──▶ [Replaced] (old route cleared, new route created) +``` + +--- + +## Monitor Assignment State Machine +``` +[Empty] (no camera) ──crossswitch──▶ [Assigned] (camera routed) + │ + └──clear──▶ [Empty] + │ + └──crossswitch──▶ [Reassigned] (new camera) +``` + +--- + +**Phase 1 Status**: ✅ Data model updated with unified architecture and configuration management +**Last Updated**: 2025-12-16 +**Next**: Implement multi-instance SDK bridge connections diff --git a/specs/001-surveillance-api/plan.md b/specs/001-surveillance-api/plan.md index bdf6682..74b96aa 100644 --- a/specs/001-surveillance-api/plan.md +++ b/specs/001-surveillance-api/plan.md @@ -256,7 +256,61 @@ See [SDK_INTEGRATION_LESSONS.md](../../SDK_INTEGRATION_LESSONS.md) for complete - **RecordingService**: QueryRecordings, StartRecording, StopRecording - **AnalyticsService**: ConfigureAnalytics, GetAnalyticsConfig -## Phase 2 - Tasks ⏭️ NEXT +## Phase 2 - Configuration Management ✅ COMPLETED (2025-12-16) + +**Implemented**: GeViSoft configuration management via REST API and gRPC SDK Bridge + +**Deliverables**: +- G-Core Server CRUD operations (CREATE, READ, DELETE working; UPDATE has known bug) +- Action Mapping CRUD operations (CREATE, READ, UPDATE, DELETE all working) +- SetupClient integration for configuration download/upload +- Configuration tree parsing and navigation +- Critical bug fixes (cascade deletion prevention) + +**Key Components Implemented**: + +### REST API Endpoints +- `GET /api/v1/configuration/servers` - List all G-Core servers +- `GET /api/v1/configuration/servers/{server_id}` - Get single server +- `POST /api/v1/configuration/servers` - Create new server +- `PUT /api/v1/configuration/servers/{server_id}` - Update server (⚠️ known bug) +- `DELETE /api/v1/configuration/servers/{server_id}` - Delete server +- `GET /api/v1/configuration/action-mappings` - List all action mappings +- `GET /api/v1/configuration/action-mappings/{mapping_id}` - Get single mapping +- `POST /api/v1/configuration/action-mappings` - Create mapping +- `PUT /api/v1/configuration/action-mappings/{mapping_id}` - Update mapping +- `DELETE /api/v1/configuration/action-mappings/{mapping_id}` - Delete mapping + +### gRPC SDK Bridge Implementation +- **ConfigurationService**: Complete CRUD operations for servers and action mappings +- **SetupClient Integration**: Download/upload .set configuration files +- **FolderTreeParser**: Parse GeViSoft binary configuration format +- **FolderTreeWriter**: Write configuration changes back to GeViSoft + +### Critical Fixes +- **Cascade Deletion Bug** (2025-12-16): Fixed critical bug where deleting multiple action mappings in ascending order caused ID shifting, resulting in deletion of wrong mappings + - **Solution**: Always delete in reverse order (highest ID first) + - **Impact**: Prevented data loss of ~54 mappings during testing + - **Documentation**: CRITICAL_BUG_FIX_DELETE.md + +### Test Scripts +- `comprehensive_crud_test.py` - Full CRUD verification with server and mapping operations +- `safe_delete_test.py` - Minimal test to verify cascade deletion fix +- `server_manager.py` - Production-ready server lifecycle management +- `cleanup_to_base.py` - Restore configuration to base state +- `verify_config_via_grpc.py` - Configuration verification tool + +### Known Issues +- Server UPDATE operation fails with "Server ID is required" error (documented, workaround: delete and recreate) +- Bool fields stored as int32 in GeViSoft configuration (acceptable - GeViSet reads correctly) + +**Documentation**: +- [SERVER_CRUD_IMPLEMENTATION.md](../../SERVER_CRUD_IMPLEMENTATION.md) - Complete implementation guide +- [CRITICAL_BUG_FIX_DELETE.md](../../CRITICAL_BUG_FIX_DELETE.md) - Cascade deletion bug analysis + +**Next**: Phase 3 - Implement remaining user stories (streams, events, analytics) + +## Phase 3 - Tasks ⏭️ NEXT **Command**: `/speckit.tasks` @@ -275,7 +329,7 @@ Will generate: 5. **Extended Features**: Recording management, analytics configuration 6. **Testing & Documentation**: Contract tests, integration tests, deployment docs -## Phase 3 - Implementation ⏭️ FUTURE +## Phase 4 - Implementation ⏭️ FUTURE **Command**: `/speckit.implement` @@ -389,6 +443,7 @@ async with websockets.connect(uri) as ws: ## References +### Project Documentation - **Specification**: [spec.md](./spec.md) - User stories, requirements, success criteria - **Research**: [research.md](./research.md) - Technical decisions and architectural analysis - **Data Model**: [data-model.md](./data-model.md) - Entity schemas and relationships @@ -397,7 +452,23 @@ async with websockets.connect(uri) as ws: - **SDK Lessons**: [../../SDK_INTEGRATION_LESSONS.md](../../SDK_INTEGRATION_LESSONS.md) - Critical SDK integration knowledge - **Constitution**: [../../.specify/memory/constitution.md](../../.specify/memory/constitution.md) - Development principles +### SDK Documentation (Extracted & Searchable) +**Location**: `C:\Gevisoft\Documentation\extracted_html\` + +- **Comprehensive SDK Reference**: `C:\DEV\COPILOT\gevisoft-sdk-reference.md` + - Complete guide to GeViSoft .NET SDK + - Action mapping implementation patterns + - Code examples and best practices + - Generated: 2025-12-11 + +**Key Documentation Files**: +- **Action Mapping**: `GeViSoft_SDK_Documentation\313Action Mapping.htm` +- **State Queries**: `GeViSoft_SDK_Documentation\414StateQueries.htm` +- **Database Queries**: `GeViSoft_SDK_Documentation\415DatabaseQueries.htm` +- **GeViAPIClient Reference**: `GeViSoft_API_Documentation\class_ge_vi_a_p_i_client.html` +- **CAction Reference**: `GeViSoft_API_Documentation\class_ge_vi_a_p_i___namespace_1_1_c_action.html` + --- -**Plan Status**: Phase 0 ✅ | Phase 1 ✅ | Phase 2 ⏭️ | Phase 3 ⏭️ -**Last Updated**: 2025-12-08 +**Plan Status**: Phase 0 ✅ | Phase 1 ✅ | Phase 2 ⏭️ | Phase 3 🔄 IN PROGRESS (Configuration Management ✅) +**Last Updated**: 2025-12-16 diff --git a/specs/001-surveillance-api/spec.md b/specs/001-surveillance-api/spec.md index 7f11191..44dd197 100644 --- a/specs/001-surveillance-api/spec.md +++ b/specs/001-surveillance-api/spec.md @@ -1,9 +1,43 @@ -# Feature Specification: Geutebruck Video Surveillance API +# Feature Specification: Geutebruck Unified Video Surveillance API **Feature Branch**: `001-surveillance-api` **Created**: 2025-11-13 -**Status**: Draft -**Input**: User description: "Complete RESTful API for Geutebruck GeViScope/GeViSoft video surveillance system control" +**Updated**: 2025-12-16 (Configuration Management + Critical Bug Fixes) +**Status**: In Progress +**Input**: "Complete RESTful API for Geutebruck GeViSoft/GeViScope unified video surveillance system control with multi-instance support" + +## Architecture Overview + +This API provides a **unified interface** to control both GeViSoft (management platform) and multiple GeViScope instances (video servers): + +``` +Geutebruck Unified API +│ +├── GeViSoft Layer (Management) +│ └── GeViServer Connection +│ ├── System-wide alarm management +│ ├── Event coordination across GeViScope instances +│ ├── Action mapping and automation +│ └── Cross-system orchestration +│ +└── GeViScope Layer (Video Operations) + ├── GeViScope Instance "main" (GSCServer - localhost) + │ ├── Cameras: 101027-101041 + │ └── Monitors: 1-256 + ├── GeViScope Instance "parking" (GSCServer - 192.168.1.100) + │ ├── Cameras: 201001-201020 + │ └── Monitors: 1-64 + └── GeViScope Instance "warehouse" (GSCServer - 192.168.1.101) + ├── Cameras: 301001-301050 + └── Monitors: 1-128 +``` + +**Key Concepts:** +- **GeViSoft** = Management platform controlling multiple GeViScope instances (1 per system) +- **GeViScope** = Video server instances handling cameras, monitors, video routing (N per system) +- **Monitors (Video Outputs)** = Logical display channels (NOT physical displays, require viewer apps) +- **CrossSwitch** = Video routing command (camera → monitor at server level) +- **GSCView** = Viewer application that displays video outputs ## User Scenarios & Testing *(mandatory)* @@ -24,7 +58,41 @@ As a developer integrating a custom surveillance application, I need to authenti --- -### User Story 2 - Live Video Stream Access (Priority: P1) +### User Story 2 - Multi-Instance GeViScope Management (Priority: P1) + +As a system administrator, I need to manage multiple GeViScope instances through a single API so that I can control video operations across different locations and servers. + +**Why this priority**: Multi-instance support is core to the unified architecture. Without it, the API can only control one GeViScope server, limiting scalability. + +**Independent Test**: Can be fully tested by configuring multiple GeViScope instances, querying available instances, and executing operations on specific instances. + +**Acceptance Scenarios**: + +1. **Given** three GeViScope instances configured (main, parking, warehouse), **When** a user requests `/api/v1/geviscope/instances`, **Then** they receive a list of all instances with status, camera count, and connection state +2. **Given** operations targeting a specific instance, **When** a user calls `/api/v1/geviscope/parking/cameras`, **Then** they receive only cameras from the parking instance +3. **Given** a default instance configured, **When** a user calls `/api/v1/cameras` without instance ID, **Then** the request routes to the default instance +4. **Given** one GeViScope instance is offline, **When** operations target that instance, **Then** the API returns clear error messages while other instances remain operational + +--- + +### User Story 3 - Video CrossSwitch and Monitor Control (Priority: P1) + +As a security operator, I need to route camera video feeds to specific monitors via CrossSwitch commands so that I can dynamically control what video appears on display systems. + +**Why this priority**: CrossSwitch is the core video routing mechanism in GeViScope systems. Without it, operators cannot control video distribution to displays. + +**Independent Test**: Can be fully tested by executing CrossSwitch commands to route cameras to monitors, verifying routes in the routing table, and clearing monitor assignments. + +**Acceptance Scenarios**: + +1. **Given** camera 101038 and monitor 1 exist, **When** an operator sends `POST /api/v1/crossswitch` with `{camera_id: 101038, monitor_id: 1}`, **Then** the camera video is routed to monitor 1 at the server level and a route record is created +2. **Given** an active route exists, **When** an operator queries `/api/v1/crossswitch/routing`, **Then** they receive a list of all active camera→monitor routes with timestamps and user who created them +3. **Given** a monitor displaying video, **When** an operator sends `DELETE /api/v1/crossswitch/{monitor_id}`, **Then** the monitor is cleared and the route is marked inactive +4. **Given** multiple monitors in a monitor group, **When** an alarm triggers CrossSwitch actions, **Then** all designated cameras are routed to their assigned monitors automatically + +--- + +### User Story 4 - Live Video Stream Access (Priority: P1) As a security operator, I need to view live video streams from surveillance cameras through the API so that I can monitor locations in real-time from a custom dashboard. @@ -34,14 +102,14 @@ As a security operator, I need to view live video streams from surveillance came **Acceptance Scenarios**: -1. **Given** an authenticated user with camera view permissions, **When** they request a live stream for camera channel 5, **Then** they receive a stream URL or WebSocket connection that delivers live video within 2 seconds +1. **Given** an authenticated user with camera view permissions, **When** they request a live stream for camera 101038, **Then** they receive a stream URL that delivers live video within 2 seconds 2. **Given** a camera that is offline, **When** a user requests its stream, **Then** they receive a clear error message indicating the camera is unavailable 3. **Given** multiple concurrent users, **When** they request the same camera stream, **Then** all users can view the stream simultaneously without degradation (up to 100 concurrent streams) 4. **Given** a user without permission for a specific camera, **When** they request its stream, **Then** they receive a 403 Forbidden response --- -### User Story 3 - Camera PTZ Control (Priority: P1) +### User Story 5 - Camera PTZ Control (Priority: P1) As a security operator, I need to control pan-tilt-zoom cameras remotely via the API so that I can adjust camera angles to investigate incidents or track movement. @@ -51,14 +119,14 @@ As a security operator, I need to control pan-tilt-zoom cameras remotely via the **Acceptance Scenarios**: -1. **Given** an authenticated operator with PTZ permissions, **When** they send a pan-left command to camera 3, **Then** the camera begins moving left within 500ms and they receive confirmation +1. **Given** an authenticated operator with PTZ permissions, **When** they send a pan-left command to camera 101038, **Then** the camera begins moving left within 500ms and they receive confirmation 2. **Given** a camera that doesn't support PTZ, **When** a user attempts PTZ control, **Then** they receive a clear error indicating PTZ is not available for this camera 3. **Given** two operators controlling the same PTZ camera, **When** they send conflicting commands simultaneously, **Then** the system queues commands and notifies operators of the conflict 4. **Given** a PTZ command in progress, **When** the user sends a stop command, **Then** the camera movement stops immediately --- -### User Story 4 - Real-time Event Notifications (Priority: P1) +### User Story 6 - Real-time Event Notifications (Priority: P1) As a security operator, I need to receive instant notifications when surveillance events occur (motion detection, alarms, sensor triggers) so that I can respond quickly to security incidents. @@ -68,14 +136,48 @@ As a security operator, I need to receive instant notifications when surveillanc **Acceptance Scenarios**: -1. **Given** an authenticated user with event subscription permissions, **When** they connect to the WebSocket endpoint `/api/v1/events/stream`, **Then** they receive a connection confirmation and can subscribe to specific event types -2. **Given** a motion detection event occurs on camera 7, **When** a subscribed user is listening for video analytics events, **Then** they receive a notification within 100ms containing event type, camera channel, timestamp, and relevant data -3. **Given** a network disconnection, **When** the WebSocket reconnects, **Then** the user automatically re-subscribes to their previous event types and receives any missed critical events -4. **Given** 1000+ concurrent WebSocket connections, **When** an event occurs, **Then** all subscribed users receive notifications without system degradation +1. **Given** an authenticated user with event subscription permissions, **When** they connect to `/api/v1/events/stream`, **Then** they receive a connection confirmation and can subscribe to specific event types +2. **Given** a motion detection event occurs on camera 101038, **When** a subscribed user is listening for video analytics events, **Then** they receive a notification within 100ms containing event type, camera ID, GeViScope instance, timestamp, and relevant data +3. **Given** a network disconnection, **When** the WebSocket reconnects, **Then** the user automatically re-subscribes and receives any missed critical events +4. **Given** events from multiple GeViScope instances, **When** subscribed users receive notifications, **Then** each event clearly indicates which instance it originated from --- -### User Story 5 - Recording Management (Priority: P2) +### User Story 7 - GeViSoft Alarm Management (Priority: P2) + +As a security administrator, I need to configure and manage alarms in GeViSoft so that I can automate responses to security events across multiple GeViScope instances. + +**Why this priority**: Important for advanced automation but basic video operations must work first. Alarms coordinate actions across the system. + +**Independent Test**: Can be fully tested by creating an alarm configuration, triggering the alarm via an event, and verifying that configured actions (CrossSwitch, notifications) execute correctly. + +**Acceptance Scenarios**: + +1. **Given** an authenticated administrator, **When** they create an alarm with start/stop/acknowledge actions, **Then** the alarm is saved in GeViSoft and can be triggered by configured events +2. **Given** an alarm configured to route cameras 101038 and 101039 to monitors 1-2, **When** the alarm triggers, **Then** CrossSwitch actions execute and cameras appear on designated monitors +3. **Given** an active alarm, **When** an operator acknowledges it via `/api/v1/gevisoft/alarms/{alarm_id}/acknowledge`, **Then** acknowledge actions execute and alarm state updates +4. **Given** multiple GeViScope instances, **When** an alarm spans instances (e.g., camera from instance A to monitor in instance B), **Then** the API coordinates cross-instance operations + +--- + +### User Story 8 - Monitor and Viewer Management (Priority: P2) + +As a system administrator, I need to query and manage video output monitors so that I can understand system topology and configure video routing. + +**Why this priority**: Enhances system visibility and configuration but video operations can work without detailed monitor management initially. + +**Independent Test**: Can be fully tested by querying monitor lists, checking monitor status, and understanding which cameras are currently routed to which monitors. + +**Acceptance Scenarios**: + +1. **Given** 256 monitors configured in a GeViScope instance, **When** an administrator queries `/api/v1/geviscope/main/monitors`, **Then** they receive a list of all monitors with IDs, names, status, and current camera assignments +2. **Given** a monitor displaying video, **When** queried for current assignment, **Then** the API returns which camera is currently routed to that monitor +3. **Given** multiple GeViScope instances, **When** listing monitors, **Then** each instance's monitors are clearly identified by instance ID +4. **Given** GSCView viewers connected to monitors, **When** administrators query viewer status, **Then** they can see which viewers are active and what they're displaying + +--- + +### User Story 9 - Recording Management (Priority: P2) As a security administrator, I need to manage video recording settings and query recorded footage so that I can configure retention policies and retrieve historical video for investigations. @@ -85,14 +187,14 @@ As a security administrator, I need to manage video recording settings and query **Acceptance Scenarios**: -1. **Given** an authenticated administrator, **When** they request recording start on camera 2, **Then** the camera begins recording and they receive confirmation with recording ID -2. **Given** a time range query for 2025-11-12 14:00 to 16:00 on camera 5, **When** an investigator searches for recordings, **Then** they receive a list of available recording segments with download URLs +1. **Given** an authenticated administrator, **When** they request recording start on camera 101038, **Then** the camera begins recording and they receive confirmation with recording ID +2. **Given** a time range query for 2025-11-12 14:00 to 16:00 on camera 101038, **When** an investigator searches for recordings, **Then** they receive a list of available recording segments with playback URLs 3. **Given** the ring buffer is at 90% capacity, **When** an administrator checks recording capacity, **Then** they receive an alert indicating low storage and oldest recordings that will be overwritten 4. **Given** scheduled recording configured for nighttime hours, **When** the schedule time arrives, **Then** recording automatically starts and stops according to the schedule --- -### User Story 6 - Video Analytics Configuration (Priority: P2) +### User Story 10 - Video Analytics Configuration (Priority: P2) As a security administrator, I need to configure video content analysis features (motion detection, object tracking, perimeter protection) so that the system can automatically detect security-relevant events. @@ -102,259 +204,282 @@ As a security administrator, I need to configure video content analysis features **Acceptance Scenarios**: -1. **Given** an authenticated administrator, **When** they configure motion detection zones on camera 4, **Then** the configuration is saved and motion detection activates within those zones +1. **Given** an authenticated administrator, **When** they configure motion detection zones on camera 101038, **Then** the configuration is saved and motion detection activates within those zones 2. **Given** motion detection configured with sensitivity level 7, **When** motion occurs in the detection zone, **Then** a motion detection event is generated and sent to event subscribers -3. **Given** object tracking enabled on camera 6, **When** a person enters the frame, **Then** the system assigns a tracking ID and sends position updates for the duration they remain visible +3. **Given** object tracking enabled on camera 101038, **When** a person enters the frame, **Then** the system assigns a tracking ID and sends position updates for the duration they remain visible 4. **Given** multiple analytics enabled on one camera (VMD + OBTRACK), **When** events occur, **Then** all configured analytics generate appropriate events without interfering with each other --- -### User Story 7 - Multi-Camera Management (Priority: P2) +### User Story 11 - Action Mapping and Automation (Priority: P3) -As a security operator, I need to view and manage multiple cameras simultaneously via the API so that I can coordinate surveillance across different locations and camera views. +As a security administrator, I need to configure action mappings in GeViSoft so that specific events automatically trigger corresponding actions across the system. -**Why this priority**: Enhances operational efficiency but single-camera operations must work first. Important for professional surveillance operations managing multiple sites. +**Why this priority**: Valuable for automation but requires basic event and action functionality to be working first. -**Independent Test**: Can be fully tested by retrieving a list of all available cameras, requesting multiple streams simultaneously, and grouping cameras by location, delivering multi-camera coordination. +**Independent Test**: Can be fully tested by creating an action mapping (e.g., motion detected → CrossSwitch), triggering the input action, and verifying the mapped actions execute. **Acceptance Scenarios**: -1. **Given** an authenticated user, **When** they request the camera list from `/api/v1/cameras`, **Then** they receive all cameras they have permission to view with status, channel ID, capabilities, and location metadata -2. **Given** multiple cameras in the same location, **When** a user requests grouped camera data, **Then** cameras are organized by configured location/zone for easy navigation -3. **Given** a user viewing 16 camera streams, **When** they request streams via the API, **Then** all 16 streams initialize and display without individual stream degradation -4. **Given** a camera goes offline while being viewed, **When** the API detects the disconnection, **Then** the camera status updates and subscribers receive a notification +1. **Given** an action mapping configured (InputContact closed → CrossSwitch cameras to monitors), **When** the input contact event occurs, **Then** the mapped CrossSwitch actions execute automatically +2. **Given** multiple output actions mapped to one input, **When** the input event triggers, **Then** all output actions execute in sequence +3. **Given** action mappings spanning GeViScope instances, **When** triggered, **Then** the API coordinates actions across instances correctly +4. **Given** an action mapping fails (e.g., target camera offline), **When** execution occurs, **Then** errors are logged and administrators are notified without blocking other actions --- -### User Story 8 - License Plate Recognition Integration (Priority: P3) +### User Story 12 - GeViSoft Configuration Management (Priority: P1) ✅ IMPLEMENTED -As a security operator monitoring vehicle access, I need to receive automatic license plate recognition events so that I can track vehicle entry/exit and match against watchlists. +As a system administrator, I need to manage GeViSoft configuration (G-Core servers, action mappings) via the API so that I can programmatically configure and maintain the surveillance system without manual GeViSet operations. -**Why this priority**: Valuable for specific use cases (parking, access control) but not universal. Only relevant if NPR hardware is available and configured. +**Why this priority**: Configuration management is essential for automation, infrastructure-as-code, and maintaining consistent configurations across environments. -**Independent Test**: Can be fully tested by configuring NPR zones, driving a test vehicle through the zone, and verifying plate recognition events with captured plate numbers, delivering automated vehicle tracking. +**Independent Test**: Can be fully tested by creating/reading/updating/deleting servers and action mappings, verifying changes persist in GeViSoft, and confirming no data loss occurs. **Acceptance Scenarios**: -1. **Given** NPR configured on camera 9 with recognition zone defined, **When** a vehicle with readable plate enters the zone, **Then** an NPR event is generated containing plate number, country code, timestamp, confidence score, and image snapshot -2. **Given** a watchlist of plates configured, **When** a matching plate is recognized, **Then** a high-priority alert is sent to subscribers with match details -3. **Given** poor lighting or plate obstruction, **When** recognition fails or confidence is low (<70%), **Then** the event includes the best-guess plate and confidence level so operators can manually verify -4. **Given** continuous vehicle traffic, **When** multiple vehicles pass through rapidly, **Then** each vehicle generates a separate NPR event with unique tracking ID +1. **Given** an authenticated administrator, **When** they create a new G-Core server via `POST /api/v1/configuration/servers`, **Then** the server is added to GeViSoft configuration with correct bool types and appears in GeViSet +2. **Given** existing servers in configuration, **When** an administrator queries `/api/v1/configuration/servers`, **Then** they receive a list of all servers with IDs, aliases, hosts, and connection settings +3. **Given** multiple action mappings to delete, **When** deletion occurs in reverse order (highest ID first), **Then** only intended mappings are deleted without cascade deletion +4. **Given** a server ID auto-increment requirement, **When** creating servers, **Then** the system automatically assigns the next available numeric ID based on existing servers + +**Implementation Status** (2025-12-16): +- ✅ Server CRUD: CREATE, READ, DELETE working; UPDATE has known bug +- ✅ Action Mapping CRUD: CREATE, READ, UPDATE, DELETE all working +- ✅ Critical Fix: Cascade deletion bug fixed (delete in reverse order) +- ✅ Configuration tree navigation and parsing +- ✅ SetupClient integration for configuration download/upload +- ✅ Bool type handling for server fields (Enabled, DeactivateEcho, DeactivateLiveCheck) +- ⚠️ Known Issue: Server UpdateServer method requires bug fix for "Server ID is required" error + +**Documentation**: +- SERVER_CRUD_IMPLEMENTATION.md +- CRITICAL_BUG_FIX_DELETE.md --- -### User Story 9 - Video Export and Backup (Priority: P3) - -As a security investigator, I need to export specific video segments for evidence or sharing so that I can provide footage to law enforcement or use in incident reports. - -**Why this priority**: Useful for investigations but not needed for live monitoring or basic recording. Can be added as an enhancement after core features are stable. - -**Independent Test**: Can be fully tested by requesting export of a 10-minute segment from camera 3, receiving a download URL, and verifying the exported file plays correctly, delivering evidence export capability. - -**Acceptance Scenarios**: - -1. **Given** an authenticated investigator, **When** they request export of camera 8 footage from 10:00-10:15 on 2025-11-12, **Then** they receive an export job ID and can poll for completion status -2. **Given** an export job in progress, **When** the investigator checks job status, **Then** they receive progress percentage and estimated completion time -3. **Given** a completed export, **When** the investigator downloads the file, **Then** they receive a standard video format (MP4/AVI) playable in common media players with embedded timestamps -4. **Given** an export request for a time range with no recordings, **When** processing occurs, **Then** the user receives a clear message indicating no footage available for that timeframe - ---- - -### User Story 10 - System Health Monitoring (Priority: P3) +### User Story 13 - System Health Monitoring (Priority: P3) As a system administrator, I need to monitor API and surveillance system health status so that I can proactively identify and resolve issues before they impact operations. **Why this priority**: Important for production systems but not required for initial deployment. Health monitoring is an operational enhancement that can be added incrementally. -**Independent Test**: Can be fully tested by querying the health endpoint, checking SDK connectivity status, and verifying alerts when components fail, delivering system observability. +**Independent Test**: Can be fully tested by querying the health endpoint, checking SDK connectivity status for all instances, and verifying alerts when components fail. **Acceptance Scenarios**: -1. **Given** the API is running, **When** an unauthenticated user requests `/api/v1/health`, **Then** they receive system status including API uptime, SDK connectivity, database status, and overall health score -2. **Given** the GeViScope SDK connection fails, **When** health is checked, **Then** the health endpoint returns degraded status with specific SDK error details +1. **Given** the API is running, **When** an unauthenticated user requests `/api/v1/health`, **Then** they receive system status including API uptime, GeViSoft connectivity, all GeViScope instance statuses, and overall health score +2. **Given** one GeViScope instance fails, **When** health is checked, **Then** the health endpoint returns degraded status with specific instance error details while other instances show healthy 3. **Given** disk space for recordings drops below 10%, **When** monitoring checks run, **Then** a warning is included in health status and administrators receive notification -4. **Given** an administrator monitoring performance, **When** they request detailed metrics, **Then** they receive statistics on request throughput, average response times, active WebSocket connections, and concurrent streams +4. **Given** an administrator monitoring performance, **When** they request detailed metrics, **Then** they receive statistics on request throughput, active streams per instance, and connection status for all instances --- ### Edge Cases -- What happens when a camera is physically disconnected while being actively viewed by 20 users? -- How does the system handle authentication when the GeViScope SDK is temporarily unavailable? -- What occurs when a user requests PTZ control on a camera that another user is already controlling? -- How does recording behave when the ring buffer reaches capacity during an active alarm event? -- What happens when network latency causes event notifications to queue up - does the system batch or drop old events? -- How does the API respond when a user has permission for 50 cameras but only 30 are currently online? -- What occurs when a WebSocket connection drops mid-event notification? -- How does the system handle time zone differences between the API server, GeViScope SDK, and client applications? -- What happens when an export request spans a time range that crosses a recording gap (camera was off)? -- How does analytics configuration respond when applied to a camera that doesn't support the requested analytics type (e.g., NPR on a camera without NPR hardware)? +- What happens when a GeViScope instance disconnects while operators are viewing cameras from that instance? +- How does CrossSwitch behave when routing a camera from one GeViScope instance to a monitor on a different instance (if supported)? +- What occurs when GeViSoft connection fails but GeViScope instances remain online? +- How does the API handle monitor IDs that overlap across different GeViScope instances? +- What happens when a GSCView viewer is configured to display a monitor that has no active camera route? +- How does the system respond when CrossSwitch commands execute successfully at the server but no viewer is displaying the monitor? +- What occurs when an alarm in GeViSoft references cameras or monitors from a GeViScope instance that is offline? +- How does the API handle time synchronization issues between GeViSoft, multiple GeViScope instances, and the API server? +- What happens when monitor enumeration returns different results than expected (e.g., 256 monitors vs 16 actual video outputs)? +- How does the system handle authentication when GeViSoft credentials differ from GeViScope credentials? ## Requirements *(mandatory)* ### Functional Requirements -- **FR-001**: System MUST authenticate all API requests using JWT tokens with configurable expiration (default 1 hour for access tokens, 7 days for refresh tokens) -- **FR-002**: System MUST implement role-based access control with at least three roles: viewer (read-only camera access), operator (camera control + viewing), administrator (full system configuration) -- **FR-003**: System MUST provide granular permissions allowing access restriction per camera channel -- **FR-004**: System MUST expose live video streams for all configured GeViScope channels with initialization time under 2 seconds -- **FR-005**: System MUST support PTZ control operations (pan, tilt, zoom, preset positions) with command response time under 500ms -- **FR-006**: System MUST provide WebSocket endpoint for real-time event notifications with delivery latency under 100ms -- **FR-007**: System MUST support event subscriptions by type (alarms, analytics, system events) and by camera channel -- **FR-008**: System MUST translate all GeViScope SDK actions to RESTful API endpoints following the pattern `/api/v1/{resource}/{id}/{action}` -- **FR-009**: System MUST handle concurrent video stream requests from minimum 100 simultaneous users without degradation -- **FR-010**: System MUST support WebSocket connections from minimum 1000 concurrent clients for event notifications -- **FR-011**: System MUST provide recording management including start/stop recording, schedule configuration, and recording status queries -- **FR-012**: System MUST expose recording capacity metrics including total capacity, free space, recording depth in hours, and oldest recording timestamp -- **FR-013**: System MUST support video analytics configuration for VMD (Video Motion Detection), OBTRACK (object tracking and people counting), NPR (license plate recognition), and G-Tect (perimeter protection) where hardware supports these features -- **FR-014**: System MUST provide query capabilities for recorded footage by channel, time range, and event association -- **FR-015**: System MUST export video segments in standard formats (MP4 or AVI) with embedded timestamps and metadata -- **FR-016**: System MUST log all authentication attempts (successful and failed) with username, source IP, and timestamp -- **FR-017**: System MUST audit log all privileged operations including PTZ control, recording management, configuration changes, and user management with operator ID, action, target, and timestamp -- **FR-018**: System MUST gracefully handle camera offline scenarios by returning appropriate error codes and status information -- **FR-019**: System MUST implement retry logic for transient SDK communication failures (3 attempts with exponential backoff) -- **FR-020**: System MUST provide health check endpoint returning API status, SDK connectivity, database availability, and system resource usage -- **FR-021**: System MUST serve auto-generated OpenAPI/Swagger documentation at `/docs` endpoint -- **FR-022**: System MUST return meaningful error messages with error codes for all failure scenarios without exposing internal stack traces -- **FR-023**: System MUST support API versioning in URL path (v1, v2) to allow backward-compatible evolution -- **FR-024**: System MUST rate limit authentication attempts to prevent brute force attacks (max 5 attempts per IP per minute) -- **FR-025**: System MUST enforce TLS 1.2+ for all API communication in production environments -- **FR-026**: System MUST translate Windows error codes from GeViScope SDK to appropriate HTTP status codes with user-friendly messages -- **FR-027**: System MUST support filtering and pagination for endpoints returning lists (camera lists, recording lists, event histories) -- **FR-028**: System MUST handle GeViScope SDK ring buffer architecture by exposing recording depth and capacity warnings when storage approaches limits -- **FR-029**: System MUST support event correlation using ForeignKey parameter to link events with external system identifiers -- **FR-030**: System MUST allow configuration of pre-alarm and post-alarm recording duration for event-triggered recordings +**Architecture & Multi-Instance:** +- **FR-001**: System MUST support connecting to one GeViSoft instance (GeViServer) for management operations +- **FR-002**: System MUST support connecting to multiple GeViScope instances (GSCServer) with configurable instance IDs, hostnames, and credentials +- **FR-003**: System MUST provide instance discovery endpoint listing all configured GeViScope instances with connection status +- **FR-004**: System MUST support default instance configuration for convenience endpoints without instance ID +- **FR-005**: System MUST clearly identify which GeViScope instance each resource (camera, monitor, event) belongs to + +**Authentication & Authorization:** +- **FR-006**: System MUST authenticate all API requests using JWT tokens with configurable expiration (default 1 hour for access, 7 days for refresh) +- **FR-007**: System MUST implement role-based access control with roles: viewer (read-only), operator (control), administrator (full configuration) +- **FR-008**: System MUST provide granular permissions allowing access restriction per camera, monitor, and GeViScope instance +- **FR-009**: System MUST audit log all authentication attempts and privileged operations + +**CrossSwitch & Monitor Management:** +- **FR-010**: System MUST provide CrossSwitch endpoint to route cameras to monitors: `POST /api/v1/crossswitch` and instance-specific variant +- **FR-011**: System MUST track active CrossSwitch routes in database with camera ID, monitor ID, mode, timestamp, and user +- **FR-012**: System MUST provide endpoint to clear monitor assignments: `DELETE /api/v1/crossswitch/{monitor_id}` +- **FR-013**: System MUST provide routing status endpoint showing all active camera→monitor routes +- **FR-014**: System MUST use typed SDK actions (GeViAct_CrossSwitch) instead of string-based commands for reliable execution +- **FR-015**: System MUST enumerate and expose all video output monitors with IDs, names, status, and current assignments +- **FR-016**: System MUST support monitor grouping and bulk operations on monitor groups + +**Video Operations:** +- **FR-017**: System MUST expose live video streams for all cameras with initialization time under 2 seconds +- **FR-018**: System MUST support PTZ control operations with command response time under 500ms +- **FR-019**: System MUST handle concurrent video stream requests from minimum 100 simultaneous users +- **FR-020**: System MUST gracefully handle camera offline scenarios with appropriate error codes + +**Event Management:** +- **FR-021**: System MUST provide WebSocket endpoint for real-time event notifications with delivery latency under 100ms +- **FR-022**: System MUST support event subscriptions by type, camera, and GeViScope instance +- **FR-023**: System MUST handle events from multiple GeViScope instances with clear instance identification +- **FR-024**: System MUST support WebSocket connections from minimum 1000 concurrent clients + +**GeViSoft Integration:** +- **FR-025**: System MUST provide alarm management endpoints for GeViSoft alarm configuration and triggering +- **FR-026**: System MUST support action mapping configuration and execution +- **FR-027**: System MUST coordinate cross-instance operations when alarms or actions span multiple GeViScope instances +- **FR-028**: System MUST provide endpoints for querying and managing GeViSoft system configuration + +**Configuration Management:** ✅ IMPLEMENTED (2025-12-16) +- **FR-039**: System MUST provide CRUD operations for G-Core server management with proper bool type handling +- **FR-040**: System MUST provide CRUD operations for action mapping management +- **FR-041**: System MUST delete multiple action mappings in reverse order (highest ID first) to prevent cascade deletion +- **FR-042**: System MUST auto-increment server IDs based on highest existing numeric ID +- **FR-043**: System MUST persist configuration changes to GeViSoft and verify changes are visible in GeViSet +- **FR-044**: System MUST parse and navigate GeViSoft configuration tree structure (.set file format) +- **FR-045**: System MUST use SetupClient for reliable configuration download/upload operations + +**Recording & Analytics:** +- **FR-029**: System MUST provide recording management including start/stop, queries, and capacity metrics +- **FR-030**: System MUST support video analytics configuration (VMD, OBTRACK, NPR, G-Tect) where hardware supports +- **FR-031**: System MUST provide query capabilities for recorded footage by channel, time range, and event association +- **FR-032**: System MUST export video segments in standard formats (MP4/AVI) with metadata + +**System Management:** +- **FR-033**: System MUST provide health check endpoint returning status for GeViSoft, all GeViScope instances, database, and SDK bridges +- **FR-034**: System MUST implement retry logic for transient SDK communication failures (3 attempts with exponential backoff) +- **FR-035**: System MUST serve auto-generated OpenAPI/Swagger documentation at `/docs` +- **FR-036**: System MUST support API versioning in URL path (v1, v2) for backward compatibility +- **FR-037**: System MUST rate limit authentication attempts (max 5/minute per IP) +- **FR-038**: System MUST enforce TLS 1.2+ for all API communication in production ### Key Entities -- **Camera**: Represents a video input channel with properties including channel ID, name, location, capabilities (PTZ support, analytics support), current status (online/offline/recording), stream URL, and permissions -- **User**: Authentication entity with username, hashed password, assigned role, permissions list, JWT tokens, and audit trail of actions -- **Event**: Surveillance occurrence with type ID (motion, alarm, analytics), event ID (instance), channel, timestamp, severity, associated data (e.g., NPR plate number, object tracking ID), and foreign key for external correlation -- **Recording**: Video footage segment with channel, start time, end time, file size, recording trigger (scheduled, event, manual), and retention policy -- **Stream**: Active video stream session with channel, user, start time, format, quality level, and connection status -- **Analytics Configuration**: Video content analysis settings with type (VMD, NPR, OBTRACK, G-Tect, CPA), channel, enabled zones/regions, sensitivity parameters, and alert thresholds -- **PTZ Preset**: Saved camera position with preset ID, channel, name, pan/tilt/zoom values -- **Audit Log Entry**: Security and operations record with timestamp, user, action type, target resource, outcome (success/failure), and detailed parameters +- **GeViScope Instance**: Configuration for a GSCServer connection with ID, hostname, credentials, status, camera count, monitor count +- **Camera**: Video input channel with ID, global ID, name, GeViScope instance, capabilities, status, stream URL +- **Monitor (Video Output)**: Logical display channel with ID, name, GeViScope instance, status, current camera assignment +- **CrossSwitch Route**: Video routing record with camera ID, monitor ID, mode, GeViScope instance, created timestamp, created by user, active status +- **User**: Authentication entity with username, password hash, role, permissions, JWT tokens, audit trail +- **Event**: Surveillance occurrence with type, event ID, camera, GeViScope instance, timestamp, severity, data, foreign key +- **Alarm (GeViSoft)**: System-wide alarm with ID, name, priority, monitor group, cameras, trigger actions, active status +- **Action Mapping**: Automation rule with input action, output actions, GeViScope instance scope +- **Recording**: Video footage segment with camera, GeViScope instance, start/end time, file size, trigger type +- **Audit Log Entry**: Security record with timestamp, user, action, target resource, GeViScope instance, outcome ## Success Criteria *(mandatory)* ### Measurable Outcomes -- **SC-001**: Developers can authenticate and make their first successful API call within 10 minutes of reading the quick start documentation -- **SC-002**: Security operators can view live video from any authorized camera with video appearing on screen within 2 seconds of request -- **SC-003**: PTZ camera movements respond to operator commands within 500ms, providing responsive control for incident investigation -- **SC-004**: Real-time event notifications are delivered to subscribed clients within 100ms of event occurrence, enabling rapid incident response -- **SC-005**: System supports 100 concurrent video streams without any individual stream experiencing frame drops or quality degradation -- **SC-006**: System handles 1000+ concurrent WebSocket connections for event notifications with message delivery rates exceeding 99.9% -- **SC-007**: API metadata queries (camera lists, status checks, user info) return results in under 200ms for 95% of requests -- **SC-008**: System maintains 99.9% uptime during production operation, measured as availability of the health check endpoint -- **SC-009**: Operators can successfully complete all primary surveillance tasks (view cameras, control PTZ, receive alerts, query recordings) without requiring technical support -- **SC-010**: API documentation is sufficiently complete that 90% of integration questions can be answered by reading the OpenAPI specification and examples -- **SC-011**: Failed authentication attempts are logged and administrators receive alerts for potential security threats within 5 minutes of detection -- **SC-012**: Video export requests for segments up to 1 hour complete within 5 minutes and produce files playable in standard media players -- **SC-013**: System gracefully handles camera failures, with offline cameras clearly indicated and the API remaining operational for all other cameras -- **SC-014**: Recording capacity warnings are provided when storage reaches 80% capacity, allowing administrators to take action before recordings are lost -- **SC-015**: During peak load (500 requests/second), the system maintains response time targets with no more than 0.1% of requests timing out or failing +- **SC-001**: Developers can authenticate and make their first successful API call within 10 minutes +- **SC-002**: Operators can execute CrossSwitch to route cameras to monitors with routes visible in system within 1 second +- **SC-003**: Multi-instance operations work correctly with 3+ GeViScope instances configured +- **SC-004**: Security operators can view live video from any authorized camera with video appearing within 2 seconds +- **SC-005**: PTZ camera movements respond to commands within 500ms +- **SC-006**: Real-time event notifications delivered within 100ms across all GeViScope instances +- **SC-007**: System supports 100 concurrent video streams across all instances without degradation +- **SC-008**: System handles 1000+ concurrent WebSocket connections with 99.9% message delivery +- **SC-009**: CrossSwitch routes created via API are visible in GeViAPI Test Client and affect GSCView displays +- **SC-010**: API maintains 99.9% uptime with automatic failover if one GeViScope instance fails ### Business Impact -- **BI-001**: Custom surveillance applications can be developed and deployed in under 1 week using the API, compared to 4-6 weeks with direct SDK integration -- **BI-002**: Reduction in support requests by 60% compared to direct SDK usage, as API abstracts SDK complexity and provides clear error messages -- **BI-003**: Enable integration with third-party systems (access control, building management, alarm systems) that previously couldn't interface with GeViScope -- **BI-004**: Support mobile and web-based surveillance clients that can't run Windows SDK, expanding platform compatibility +- **BI-001**: Custom surveillance applications can be developed in under 1 week using the API +- **BI-002**: Support for multiple GeViScope instances enables scalable multi-site deployments +- **BI-003**: Unified API reduces integration complexity by 70% compared to separate GeViSoft/GeViScope integrations +- **BI-004**: CrossSwitch automation reduces operator workload for video routing by 80% ## Dependencies *(mandatory)* ### External Dependencies -- **GeViScope SDK 7.9.975.68+**: Core surveillance system SDK providing video streams, camera control, and event management -- **Windows Server 2016+** or **Windows 10/11**: Required platform for GeViScope SDK operation -- **Active Geutebruck Surveillance System**: Physical cameras, recording servers, and network infrastructure must be configured and operational +- **GeViScope SDK 7.9.975.68+**: Core SDK for video operations +- **GeViSoft SDK 6.0.1.5+**: Management platform SDK +- **Windows Server 2016+** or **Windows 10/11**: Required for both SDKs +- **Active GeViSoft System**: Configured with GeViScope instances +- **Active GeViScope Instances**: One or more GSCServer instances with cameras and monitors ### Assumptions -- GeViScope SDK is already installed and configured with cameras connected and functional -- Network connectivity exists between API server and GeViScope SDK service -- Sufficient storage capacity available for ring buffer recording as configured in GeViScope -- Client applications can consume RESTful APIs and WebSocket connections -- Authentication credentials for GeViScope SDK are available for API integration -- Standard industry retention and performance expectations apply unless otherwise specified by regulations -- JWT-based authentication is acceptable for client applications (OAuth2 flow not required initially) -- Video streaming will use existing GeViScope streaming protocols (direct URL or stream proxy to be determined during technical planning) -- Redis or similar in-memory database available for session management and caching -- SSL/TLS certificates can be obtained and configured for production deployment +- GeViSoft and GeViScope instances are installed, configured, and operational +- Network connectivity exists between API server and all GeViScope/GeViSoft instances +- Authentication credentials available for all instances +- Sufficient storage for ring buffer recording +- CrossSwitch commands execute at server level, viewer applications (GSCView) required for actual video display +- Monitor IDs may not be unique across instances (scoped by instance ID in API) ### Out of Scope -- Direct camera hardware management (firmware updates, network configuration) - handled by GeViScope -- Video storage architecture changes - API uses existing GeViScope ring buffer -- Custom video codec development - API uses GeViScope's supported formats -- Mobile native SDKs - this specification covers REST API only, client SDKs are separate future work -- Video wall display management - API provides data, UI implementation is client responsibility -- Bi-directional audio communication - audio monitoring may be included but two-way audio is deferred -- Access control system integration - API provides data interfaces but integration logic is external -- Custom analytics algorithm development - API configures existing GeViScope analytics, custom algorithms are separate work +- Direct camera hardware management (firmware, network config) +- GSCView configuration and deployment +- Custom video codec development +- Mobile native SDKs (REST API only) +- Video wall display management UI +- Bi-directional audio communication +- Custom analytics algorithm development ## Constraints ### Technical Constraints -- API must run on Windows platform due to GeViScope SDK dependency -- All video operations must use GeViScope's channel-based architecture (Channel ID parameter required) -- Event notifications limited to events supported by GeViScope SDK action system -- Recording capabilities bounded by GeViScope SDK's ring buffer architecture -- Analytics features only available for cameras with hardware support (cannot enable NPR on camera without NPR hardware) +- API must run on Windows platform due to SDK dependencies +- All video operations use GeViScope's channel-based architecture +- Event notifications limited to SDK-supported events +- Recording capabilities bounded by ring buffer architecture +- CrossSwitch routes video at server level, does NOT control physical displays (requires viewers) +- Monitor enumeration may return more monitors than physically exist (SDK implementation detail) ### Performance Constraints -- Maximum concurrent streams limited by GeViScope SDK license and hardware capacity -- WebSocket connection limits determined by operating system socket limits and available memory -- API response times dependent on GeViScope SDK response characteristics -- Video stream initialization time includes SDK processing delay (targeted under 2 seconds total) +- Maximum concurrent streams limited by GeViScope SDK licenses and hardware +- WebSocket connection limits determined by OS socket limits +- Multi-instance operations may have higher latency than single-instance +- CrossSwitch execution time depends on SDK response (typically <100ms) ### Security Constraints - All API communication must use TLS 1.2+ in production -- JWT tokens must have configurable expiration to balance security and usability -- Audit logging must be tamper-evident (append-only, with checksums or write to immutable storage) -- Credentials for GeViScope SDK must be stored securely (environment variables, key vault) +- JWT tokens must have configurable expiration +- Audit logging must be tamper-evident +- Credentials for GeViSoft and GeViScope instances must be stored securely ## Risk Analysis ### High Impact Risks -1. **GeViScope SDK Stability**: If SDK crashes or becomes unresponsive, API loses all functionality - - *Mitigation*: Implement circuit breaker pattern, health monitoring, automatic SDK reconnection logic +1. **Multi-Instance Complexity**: Managing connections to multiple GeViScope instances increases failure modes + - *Mitigation*: Circuit breaker per instance, independent health monitoring, graceful degradation -2. **Performance Under Load**: Concurrent stream limits may be lower than target (100 streams) - - *Mitigation*: Load testing early in development, potentially implement stream quality adaptation +2. **CrossSwitch Verification**: Confirming routes are active requires viewer applications + - *Mitigation*: Document viewer requirements, provide route tracking in database, API-level route verification -3. **Windows Platform Dependency**: Restricts deployment options and increases operational complexity - - *Mitigation*: Document Windows container approach, design SDK bridge for potential future Linux support via proxy +3. **GeViSoft/GeViScope Coordination**: Cross-system operations may have complex failure scenarios + - *Mitigation*: Transaction-like patterns, compensating actions, clear error reporting ### Medium Impact Risks -4. **SDK Version Compatibility**: Future GeViScope SDK updates may break API integration - - *Mitigation*: Version testing before SDK upgrades, maintain SDK abstraction layer +4. **Instance Configuration Management**: Adding/removing instances requires careful config management + - *Mitigation*: Configuration validation, instance health checks, hot-reload support -5. **WebSocket Scalability**: 1000+ concurrent connections may stress resources - - *Mitigation*: Connection pooling, message batching, load testing, potential horizontal scaling +5. **SDK Version Compatibility**: Different GeViScope instances may run different SDK versions + - *Mitigation*: Version detection, compatibility matrix, graceful feature detection -6. **Network Latency**: Event notifications and video streams sensitive to network conditions - - *Mitigation*: Document network requirements, implement connection quality monitoring - -### Low Impact Risks - -7. **Documentation Drift**: API changes may outpace documentation updates - - *Mitigation*: Auto-generated OpenAPI specs from code, documentation review in PR process +6. **Monitor ID Confusion**: Monitor IDs overlap across instances + - *Mitigation*: Always scope monitors by instance ID in API, clear documentation ## Notes -This specification focuses on **WHAT** the API enables users to do and **WHY** it's valuable, avoiding **HOW** it will be implemented. Technical decisions about Python/FastAPI, specific database choices, video streaming protocols, and SDK integration mechanisms will be made during the `/speckit.plan` phase. +This updated specification reflects the **unified architecture** supporting both GeViSoft management and multiple GeViScope instances. The API serves as a central control plane for the entire Geutebruck surveillance ecosystem. -The user stories are prioritized for iterative development: -- **P1 stories** (1-4) form the MVP: authentication, live viewing, PTZ control, event notifications -- **P2 stories** (5-7) add operational capabilities: recording management, analytics configuration, multi-camera coordination -- **P3 stories** (8-10) provide enhancements: specialized analytics (NPR), evidence export, system monitoring +**Key Architectural Decisions:** +- Single API with two layers: GeViSoft (management) and GeViScope (operations) +- Instance-based routing for GeViScope operations +- CrossSwitch implemented with typed SDK actions for reliability +- Monitor management reflects SDK's video output concept (logical channels, not physical displays) +- Database tracks routes and provides audit trail -Each story is independently testable and delivers standalone value, enabling flexible development sequencing and incremental delivery to users. +**Priority Sequencing:** +- **P1** (Stories 1-6): MVP with auth, multi-instance, CrossSwitch, live video, PTZ, events +- **P2** (Stories 7-10): GeViSoft integration, monitor management, recording, analytics +- **P3** (Stories 11-12): Automation, advanced monitoring diff --git a/specs/001-surveillance-api/tasks-revised-mvp.md b/specs/001-surveillance-api/tasks-revised-mvp.md index d8045eb..d326cae 100644 --- a/specs/001-surveillance-api/tasks-revised-mvp.md +++ b/specs/001-surveillance-api/tasks-revised-mvp.md @@ -407,5 +407,31 @@ GET /metrics # Prometheus metrics --- **Generated**: 2025-12-08 -**Scope**: Cross-switching MVP with authentication, expandable to GeViSet configuration +**Updated**: 2025-12-16 (Configuration Management implemented) +**Scope**: Cross-switching MVP with authentication + GeViSet configuration management ✅ **Architecture**: Python FastAPI + C# gRPC Bridge + GeViScope SDK + +--- + +## UPDATE: Configuration Management (2025-12-16) ✅ COMPLETED + +**Status**: Phase 9 (GeViSet Configuration Management) has been implemented ahead of schedule + +**Implemented Features**: +- ✅ G-Core Server CRUD operations (CREATE, READ, DELETE working; UPDATE has known bug) +- ✅ Action Mapping CRUD operations (all CRUD operations working) +- ✅ SetupClient integration for configuration file operations +- ✅ Configuration tree parsing and navigation +- ✅ Critical bug fixes (cascade deletion prevention) + +**API Endpoints Added**: +- `GET/POST/PUT/DELETE /api/v1/configuration/servers` - G-Core server management +- `GET/POST/PUT/DELETE /api/v1/configuration/action-mappings` - Action mapping management + +**Documentation**: +- [SERVER_CRUD_IMPLEMENTATION.md](../../SERVER_CRUD_IMPLEMENTATION.md) +- [CRITICAL_BUG_FIX_DELETE.md](../../CRITICAL_BUG_FIX_DELETE.md) + +See Phase 9 section below for original planned tasks. + +--- diff --git a/specs/001-surveillance-api/tasks.md b/specs/001-surveillance-api/tasks.md index 44e830f..c386105 100644 --- a/specs/001-surveillance-api/tasks.md +++ b/specs/001-surveillance-api/tasks.md @@ -459,7 +459,60 @@ This project uses **web application structure**: --- -## Phase 13: Polish & Cross-Cutting Concerns +## Phase 13: User Story 12 - GeViSoft Configuration Management (Priority: P1) ✅ IMPLEMENTED (2025-12-16) + +**Goal**: Manage GeViSoft configuration (G-Core servers, action mappings) via REST API + +**Implementation Status**: CRUD operations working with critical bug fixes applied + +### Implementation Summary (Completed) + +**REST API Endpoints**: +- ✅ `GET /api/v1/configuration/servers` - List all G-Core servers +- ✅ `GET /api/v1/configuration/servers/{server_id}` - Get single server +- ✅ `POST /api/v1/configuration/servers` - Create new server +- ⚠️ `PUT /api/v1/configuration/servers/{server_id}` - Update server (known bug) +- ✅ `DELETE /api/v1/configuration/servers/{server_id}` - Delete server +- ✅ `GET /api/v1/configuration/action-mappings` - List all action mappings +- ✅ `GET /api/v1/configuration/action-mappings/{mapping_id}` - Get single mapping +- ✅ `POST /api/v1/configuration/action-mappings` - Create mapping +- ✅ `PUT /api/v1/configuration/action-mappings/{mapping_id}` - Update mapping +- ✅ `DELETE /api/v1/configuration/action-mappings/{mapping_id}` - Delete mapping + +**gRPC SDK Bridge**: +- ✅ ConfigurationService implementation +- ✅ SetupClient integration for .set file operations +- ✅ FolderTreeParser for binary configuration parsing +- ✅ FolderTreeWriter for configuration updates +- ✅ CreateServer, UpdateServer, DeleteServer methods +- ✅ CreateActionMapping, UpdateActionMapping, DeleteActionMapping methods +- ✅ ReadConfigurationTree for querying configuration + +**Critical Fixes**: +- ✅ **Cascade Deletion Bug**: Fixed deletion order issue (delete in reverse order) +- ✅ **Bool Type Handling**: Proper bool type usage for GeViSet compatibility +- ✅ **Auto-increment Server IDs**: Find highest numeric ID and increment + +**Test Scripts**: +- ✅ `comprehensive_crud_test.py` - Full CRUD verification +- ✅ `safe_delete_test.py` - Cascade deletion fix verification +- ✅ `server_manager.py` - Production server management +- ✅ `cleanup_to_base.py` - Configuration reset utility +- ✅ `verify_config_via_grpc.py` - Configuration verification + +**Documentation**: +- ✅ `SERVER_CRUD_IMPLEMENTATION.md` - Complete implementation guide +- ✅ `CRITICAL_BUG_FIX_DELETE.md` - Bug analysis and fix documentation +- ✅ Updated spec.md with User Story 12 and functional requirements + +**Known Issues**: +- ⚠️ Server UPDATE method has "Server ID is required" bug (workaround: delete and recreate) + +**Checkpoint**: Configuration management complete - can manage G-Core servers and action mappings via API + +--- + +## Phase 14: Polish & Cross-Cutting Concerns **Purpose**: Improvements that affect multiple user stories @@ -535,6 +588,7 @@ Phase 13: Polish - **US8 (NPR Integration)**: Depends on US4, US6 completion - **US9 (Video Export)**: Depends on US5 completion - **US10 (Health Monitoring)**: Can start after Foundational +- **US12 (Configuration Management)**: ✅ COMPLETED - Depends on Foundational only ### Parallel Opportunities @@ -552,13 +606,13 @@ Phase 13: Polish - [Similar pattern for all user stories] **Across User Stories** (if team capacity allows): -- After Foundational completes: US1 can start +- After Foundational completes: US1, US10, US12 can start in parallel - After US1 completes: US2, US5 can start in parallel - After US2 completes: US3, US4, US7 can start in parallel - After US4 completes: US6 can start - After US5 completes: US9 can start - After US6 completes: US8 can start -- US10 can start any time after Foundational +- US12 ✅ COMPLETED (Configuration Management) **Polish Phase**: T198-T212, T214-T215 all marked [P] can run in parallel @@ -683,9 +737,11 @@ With 3 developers after Foundational phase completes: - Phase 10 (US8 - NPR Integration): 12 tasks - Phase 11 (US9 - Video Export): 14 tasks - Phase 12 (US10 - Health Monitoring): 14 tasks -- Phase 13 (Polish): 18 tasks +- Phase 13 (US12 - Configuration Management): ✅ COMPLETED (2025-12-16) +- Phase 14 (Polish): 18 tasks **MVP Tasks** (Phases 1-6): 112 tasks +**Configuration Management**: ✅ Implemented separately (not part of original task breakdown) **Tests**: 80+ test tasks (all marked TDD - write first, ensure FAIL) @@ -711,4 +767,5 @@ With 3 developers after Foundational phase completes: --- **Generated**: 2025-12-08 -**Based on**: spec.md (10 user stories), plan.md (tech stack), data-model.md (7 entities), contracts/openapi.yaml (17 endpoints) +**Updated**: 2025-12-16 (Configuration Management implemented) +**Based on**: spec.md (12 user stories), plan.md (tech stack), data-model.md (8 entities), contracts/openapi.yaml (27+ endpoints)