feat: Geutebruck GeViScope/GeViSoft Action Mapping System - MVP

This MVP release provides a complete full-stack solution for managing action mappings
in Geutebruck's GeViScope and GeViSoft video surveillance systems.

## Features

### Flutter Web Application (Port 8081)
- Modern, responsive UI for managing action mappings
- Action picker dialog with full parameter configuration
- Support for both GSC (GeViScope) and G-Core server actions
- Consistent UI for input and output actions with edit/delete capabilities
- Real-time action mapping creation, editing, and deletion
- Server categorization (GSC: prefix for GeViScope, G-Core: prefix for G-Core servers)

### FastAPI REST Backend (Port 8000)
- RESTful API for action mapping CRUD operations
- Action template service with comprehensive action catalog (247 actions)
- Server management (G-Core and GeViScope servers)
- Configuration tree reading and writing
- JWT authentication with role-based access control
- PostgreSQL database integration

### C# SDK Bridge (gRPC, Port 50051)
- Native integration with GeViSoft SDK (GeViProcAPINET_4_0.dll)
- Action mapping creation with correct binary format
- Support for GSC and G-Core action types
- Proper Camera parameter inclusion in action strings (fixes CrossSwitch bug)
- Action ID lookup table with server-specific action IDs
- Configuration reading/writing via SetupClient

## Bug Fixes
- **CrossSwitch Bug**: GSC and G-Core actions now correctly display camera/PTZ head parameters in GeViSet
- Action strings now include Camera parameter: `@ PanLeft (Comment: "", Camera: 101028)`
- Proper filter flags and VideoInput=0 for action mappings
- Correct action ID assignment (4198 for GSC, 9294 for G-Core PanLeft)

## Technical Stack
- **Frontend**: Flutter Web, Dart, Dio HTTP client
- **Backend**: Python FastAPI, PostgreSQL, Redis
- **SDK Bridge**: C# .NET 8.0, gRPC, GeViSoft SDK
- **Authentication**: JWT tokens
- **Configuration**: GeViSoft .set files (binary format)

## Credentials
- GeViSoft/GeViScope: username=sysadmin, password=masterkey
- Default admin: username=admin, password=admin123

## Deployment
All services run on localhost:
- Flutter Web: http://localhost:8081
- FastAPI: http://localhost:8000
- SDK Bridge gRPC: localhost:50051
- GeViServer: localhost (default port)

Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Administrator
2025-12-31 18:10:54 +01:00
commit 14893e62a5
4189 changed files with 1395076 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,572 @@
# Implementation Plan: Geutebruck Surveillance API
**Branch**: `001-surveillance-api` | **Date**: 2025-12-08 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/001-surveillance-api/spec.md`
## Summary
Build a production-ready REST API for Geutebruck GeViScope/GeViSoft video surveillance systems, enabling developers to integrate surveillance capabilities into custom applications without direct SDK complexity. The system uses a C# gRPC bridge to interface with the GeViScope SDK, exposing clean REST/WebSocket endpoints through Python FastAPI.
**Technical Approach**: Python FastAPI + C# gRPC SDK Bridge + GeViScope SDK → delivers <200ms API responses, supports 100+ concurrent video streams, and handles 1000+ WebSocket event subscribers.
## Geutebruck System Architecture
**IMPORTANT**: Understanding the Geutebruck architecture is critical for correct implementation:
### GeViSoft (GeViServer.exe) - Central Matrix Server
- **Role**: Video matrix/central management server
- **Purpose**: Manages and routes video between multiple GeViScope servers
- **Does NOT**: Have cameras or monitors directly connected
- **Connects to**: Multiple GeViScope servers (configured as G-Core servers)
- **Location**: Typically runs on central management machine
- **Configuration**: TestMKS.set contains G-Core server connections
### GeViScope (GSCServer.exe) - Storage/Recording Servers
- **Role**: Video recording and storage servers
- **Purpose**: Record video, manage local cameras and monitors
- **Has**: IP cameras and video monitors directly connected
- **Multiple instances**: You can have many GeViScope servers
- **Location**: Typically runs on-site at camera locations
- **Configuration**: Each has its own camera/monitor setup
### System Hierarchy
```
┌─────────────────────────────────────────────────────┐
│ GeViSoft (GeViServer.exe) │
│ - Central video matrix │
│ - Routes video between GeViScope servers │
│ - NO cameras directly attached │
│ │
│ Connects to G-Core Servers (configured in │
│ TestMKS.set GeViGCoreServer folder): │
├─────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ GeViScope Server 1 (GSCServer.exe) │ │
│ │ Host: 192.168.1.100 │ │
│ │ ├─ IP Camera 1 │ │
│ │ ├─ IP Camera 2 │ │
│ │ ├─ IP Camera 3 │ │
│ │ └─ Monitor 1 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ GeViScope Server 2 (GSCServer.exe) │ │
│ │ Host: 192.168.1.200 │ │
│ │ ├─ IP Camera 4 │ │
│ │ ├─ IP Camera 5 │ │
│ │ └─ Monitor 2 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ GeViScope Server 3 (localhost) │ │
│ │ Host: localhost OR 127.0.0.1 │ │
│ │ ├─ IP Camera 6 │ │
│ │ ├─ IP Camera 7 │ │
│ │ └─ Monitor 3 │ │
│ └────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
```
### API Data Flow
```
REST API Request (GET /cameras)
SDK Bridge (gRPC)
GeViScope SDK (GeViProcAPINET_4_0.dll)
GeViSoft (GeViServer.exe) - Central matrix
↓ Queries all connected G-Core servers
├──> GeViScope Server 1 → Returns cameras 1-3
├──> GeViScope Server 2 → Returns cameras 4-5
└──> GeViScope Server 3 → Returns cameras 6-7
Combined camera list returned to API
```
### G-Core Server Configuration
The **GeViGCoreServer** entries in TestMKS.set are connection definitions telling GeViSoft which GeViScope servers to connect to:
```
TestMKS.set/
GeViGCoreServer/
Server_1/ ← Connection to GeViScope at 192.168.1.100
Alias: "Office Building"
Host: "192.168.1.100"
Enabled: true
Server_2/ ← Connection to GeViScope at 192.168.1.200
Alias: "Warehouse"
Host: "192.168.1.200"
Enabled: true
Server_localhost/ ← Connection to LOCAL GeViScope
Alias: "Local Storage"
Host: "localhost"
Enabled: true
```
**Critical**: For cameras to appear in the API, GeViSoft must successfully connect to at least one GeViScope server that has cameras configured.
## Technical Context
**Language/Version**: Python 3.11+, C# .NET Framework 4.8 (SDK bridge), C# .NET 8.0 (gRPC service)
**Primary Dependencies**:
- **Python**: FastAPI, Uvicorn, SQLAlchemy, Redis (aioredis), protobuf, grpcio, PyJWT, asyncio
- **C#**: GeViScope SDK (GeViProcAPINET_4_0.dll), Grpc.Core, Google.Protobuf
**Storage**: PostgreSQL 14+ (user management, session storage, audit logs), Redis 6.0+ (session cache, pub/sub for WebSocket events)
**Testing**: pytest (Python), xUnit (.NET), 80% minimum coverage, TDD enforced
**Target Platform**: Windows Server 2016+ (SDK bridge + GeViServer), Linux (FastAPI server - optional)
**Project Type**: Web (backend API + SDK bridge service)
**Performance Goals**:
- <200ms p95 for metadata queries (camera lists, status)
- <2s stream initialization
- <100ms event notification delivery
- 100+ concurrent video streams
- 1000+ concurrent WebSocket connections
**Constraints**:
- SDK requires Windows x86 (32-bit) runtime
- Visual C++ 2010 Redistributable (x86) mandatory
- Full GeViSoft installation required (not just SDK)
- GeViServer must be running on network-accessible host
- All SDK operations must use Channel-based architecture
**Scale/Scope**:
- Support 50+ cameras per installation
- Handle 10k+ events/hour during peak activity
- Store 90 days audit logs (configurable)
- Support 100+ concurrent operators
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
### Constitution Alignment
**Single Source of Truth**: OpenAPI spec serves as the contract, auto-generated from code
**Test-First Development**: TDD enforced with pytest/xUnit, 80% minimum coverage
**Simplicity**: REST over custom protocols, JWT over session cookies, direct stream URLs over proxying
**Clear Abstractions**: SDK Bridge isolates SDK complexity from Python API layer
**Error Handling**: SDK errors translated to HTTP status codes with user-friendly messages
**Documentation**: Auto-generated OpenAPI docs at `/docs`, quickstart guide provided
**Security First**: JWT authentication, RBAC, rate limiting, audit logging, TLS enforcement
### Exceptions to Constitution
None. All design decisions align with constitution principles.
## Project Structure
### Documentation (this feature)
```text
specs/001-surveillance-api/
├── plan.md # This file (implementation plan)
├── spec.md # Feature specification (user stories, requirements)
├── research.md # Phase 0 output (technical research, architectural decisions)
├── data-model.md # Phase 1 output (entity schemas, relationships, validation)
├── quickstart.md # Phase 1 output (developer quick start guide)
├── contracts/ # Phase 1 output (API contracts)
│ └── openapi.yaml # Complete OpenAPI 3.0 specification
└── tasks.md # Phase 2 output (will be generated by /speckit.tasks)
```
### Source Code (repository root)
```text
geutebruck-api/
├── src/
│ ├── api/ # Python FastAPI application
│ │ ├── main.py # FastAPI app entry point
│ │ ├── config.py # Configuration management (env vars)
│ │ ├── models/ # SQLAlchemy ORM models
│ │ │ ├── user.py
│ │ │ ├── camera.py
│ │ │ ├── event.py
│ │ │ └── audit_log.py
│ │ ├── schemas/ # Pydantic request/response models
│ │ │ ├── auth.py
│ │ │ ├── camera.py
│ │ │ ├── stream.py
│ │ │ ├── event.py
│ │ │ └── recording.py
│ │ ├── routers/ # FastAPI route handlers
│ │ │ ├── auth.py # /api/v1/auth/*
│ │ │ ├── cameras.py # /api/v1/cameras/*
│ │ │ ├── events.py # /api/v1/events/*
│ │ │ ├── recordings.py # /api/v1/recordings/*
│ │ │ ├── analytics.py # /api/v1/analytics/*
│ │ │ └── system.py # /api/v1/health, /status
│ │ ├── services/ # Business logic layer
│ │ │ ├── auth_service.py
│ │ │ ├── camera_service.py
│ │ │ ├── stream_service.py
│ │ │ ├── event_service.py
│ │ │ └── recording_service.py
│ │ ├── clients/ # External service clients
│ │ │ ├── sdk_bridge_client.py # gRPC client for SDK bridge
│ │ │ └── redis_client.py # Redis connection pooling
│ │ ├── middleware/ # FastAPI middleware
│ │ │ ├── auth_middleware.py
│ │ │ ├── rate_limiter.py
│ │ │ └── error_handler.py
│ │ ├── websocket/ # WebSocket event streaming
│ │ │ ├── connection_manager.py
│ │ │ └── event_broadcaster.py
│ │ ├── utils/ # Utility functions
│ │ │ ├── jwt_utils.py
│ │ │ └── error_translation.py
│ │ └── migrations/ # Alembic database migrations
│ │ └── versions/
│ │
│ └── sdk-bridge/ # C# gRPC service (SDK wrapper)
│ ├── GeViScopeBridge.sln
│ ├── GeViScopeBridge/
│ │ ├── Program.cs # gRPC server entry point
│ │ ├── Services/
│ │ │ ├── CameraService.cs # Camera operations
│ │ │ ├── StreamService.cs # Stream management
│ │ │ ├── EventService.cs # Event subscriptions
│ │ │ ├── RecordingService.cs # Recording management
│ │ │ └── AnalyticsService.cs # Analytics configuration
│ │ ├── SDK/
│ │ │ ├── GeViDatabaseWrapper.cs
│ │ │ ├── StateQueryHandler.cs
│ │ │ ├── DatabaseQueryHandler.cs
│ │ │ └── ActionDispatcher.cs
│ │ ├── Models/ # Internal data models
│ │ └── Utils/
│ └── Protos/ # gRPC protocol definitions
│ ├── camera.proto
│ ├── stream.proto
│ ├── event.proto
│ ├── recording.proto
│ └── analytics.proto
├── tests/
│ ├── api/
│ │ ├── unit/ # Unit tests for Python services
│ │ │ ├── test_auth_service.py
│ │ │ ├── test_camera_service.py
│ │ │ └── test_event_service.py
│ │ ├── integration/ # Integration tests with SDK bridge
│ │ │ ├── test_camera_operations.py
│ │ │ ├── test_stream_lifecycle.py
│ │ │ └── test_event_notifications.py
│ │ └── contract/ # OpenAPI contract validation
│ │ └── test_openapi_compliance.py
│ │
│ └── sdk-bridge/
│ ├── Unit/ # C# unit tests
│ │ ├── CameraServiceTests.cs
│ │ └── StateQueryTests.cs
│ └── Integration/ # Tests with actual SDK
│ └── SdkIntegrationTests.cs
├── docs/
│ ├── architecture.md # System architecture diagram
│ ├── sdk-integration.md # SDK integration patterns
│ └── deployment.md # Production deployment guide
├── scripts/
│ ├── setup_dev_environment.ps1 # Development environment setup
│ ├── start_services.ps1 # Start all services (Redis, SDK Bridge, API)
│ └── run_tests.sh # Test execution script
├── .env.example # Environment variable template
├── requirements.txt # Python dependencies
├── pyproject.toml # Python project configuration
├── alembic.ini # Database migration configuration
└── README.md # Project overview
```
**Structure Decision**: Web application structure selected (backend API + SDK bridge service) because:
1. SDK requires Windows runtime isolated C# bridge service
2. API layer can run on Linux flexibility for deployment
3. Clear separation between SDK complexity and API logic
4. gRPC provides high-performance, typed communication between layers
5. Python layer handles web concerns (HTTP, WebSocket, auth, validation)
## Phase 0 - Research ✅ COMPLETED
**Deliverable**: [research.md](./research.md)
**Key Decisions**:
1. **SDK Integration Method**: C# gRPC bridge service (not pythonnet, subprocess, or COM)
- Rationale: Isolates SDK crashes, maintains type safety, enables independent scaling
2. **Stream Architecture**: Direct RTSP URLs with token authentication (not API proxy)
- Rationale: Reduces API latency, leverages existing streaming infrastructure
3. **Event Distribution**: FastAPI WebSocket + Redis Pub/Sub
- Rationale: Supports 1000+ concurrent connections, horizontal scaling capability
4. **Authentication**: JWT with Redis session storage
- Rationale: Stateless validation, flexible permissions, Redis for quick invalidation
5. **Performance Strategy**: Async Python + gRPC connection pooling
- Rationale: Non-blocking I/O for concurrent operations, <200ms response targets
**Critical Discoveries**:
- Visual C++ 2010 Redistributable (x86) mandatory for SDK DLL loading
- Full GeViSoft installation required (not just SDK)
- Windows Forms context needed for mixed-mode C++/CLI assemblies
- GeViServer ports: 7700, 7701, 7703 (NOT 7707 as initially assumed)
- SDK connection pattern: Create RegisterCallback Connect (order matters!)
- State Queries use GetFirst/GetNext iteration for enumerating entities
See [SDK_INTEGRATION_LESSONS.md](../../SDK_INTEGRATION_LESSONS.md) for complete details.
## Phase 1 - Design ✅ COMPLETED
**Deliverables**:
- [data-model.md](./data-model.md) - Entity schemas, relationships, validation rules
- [contracts/openapi.yaml](./contracts/openapi.yaml) - Complete REST API specification
- [quickstart.md](./quickstart.md) - Developer quick start guide
**Key Components**:
### Data Model
- **User**: Authentication, RBAC (viewer/operator/administrator), permissions
- **Camera**: Channel-based, capabilities (PTZ, analytics), status tracking
- **Stream**: Active sessions with token-authenticated URLs
- **Event**: Surveillance occurrences (motion, alarms, analytics)
- **Recording**: Video segments with ring buffer management
- **AnalyticsConfig**: VMD, NPR, OBTRACK configuration per camera
### API Endpoints (RESTful)
- `POST /api/v1/auth/login` - Authenticate and get JWT tokens
- `POST /api/v1/auth/refresh` - Refresh access token
- `POST /api/v1/auth/logout` - Invalidate tokens
- `GET /api/v1/cameras` - List cameras with filtering
- `GET /api/v1/cameras/{id}` - Get camera details
- `POST /api/v1/cameras/{id}/stream` - Start video stream
- `DELETE /api/v1/cameras/{id}/stream/{stream_id}` - Stop stream
- `POST /api/v1/cameras/{id}/ptz` - PTZ control commands
- `WS /api/v1/events/stream` - WebSocket event notifications
- `GET /api/v1/events` - Query event history
- `GET /api/v1/recordings` - Query recordings
- `POST /api/v1/recordings/{id}/export` - Export video segment
- `GET /api/v1/analytics/{camera_id}` - Get analytics configuration
- `POST /api/v1/analytics/{camera_id}` - Configure analytics
- `GET /api/v1/health` - System health check
- `GET /api/v1/status` - Detailed system status
### gRPC Service Definitions
- **CameraService**: ListCameras, GetCameraDetails, GetCameraStatus
- **StreamService**: StartStream, StopStream, GetStreamStatus
- **PTZService**: MoveCamera, SetPreset, GotoPreset
- **EventService**: SubscribeEvents, UnsubscribeEvents (server streaming)
- **RecordingService**: QueryRecordings, StartRecording, StopRecording
- **AnalyticsService**: ConfigureAnalytics, GetAnalyticsConfig
## 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`
Will generate:
- Task breakdown with dependencies
- Implementation order (TDD-first)
- Test plan for each task
- Acceptance criteria per task
- Time estimates
**Expected Task Categories**:
1. **Infrastructure Setup**: Repository structure, development environment, CI/CD
2. **SDK Bridge Foundation**: gRPC server, SDK wrapper, basic camera queries
3. **API Foundation**: FastAPI app, authentication, middleware
4. **Core Features**: Camera management, stream lifecycle, event notifications
5. **Extended Features**: Recording management, analytics configuration
6. **Testing & Documentation**: Contract tests, integration tests, deployment docs
## Phase 4 - Implementation ⏭️ FUTURE
**Command**: `/speckit.implement`
Will execute TDD implementation:
- Red: Write failing test
- Green: Minimal code to pass test
- Refactor: Clean up while maintaining passing tests
- Repeat for each task
## Complexity Tracking
No constitution violations. All design decisions follow simplicity and clarity principles:
- REST over custom protocols
- JWT over session management
- Direct streaming over proxying
- Clear layer separation (API Bridge SDK)
- Standard patterns (FastAPI, gRPC, SQLAlchemy)
## Technology Stack Summary
### Python API Layer
- **Web Framework**: FastAPI 0.104+
- **ASGI Server**: Uvicorn with uvloop
- **ORM**: SQLAlchemy 2.0+
- **Database**: PostgreSQL 14+
- **Cache/PubSub**: Redis 6.0+ (aioredis)
- **Authentication**: PyJWT, passlib (bcrypt)
- **gRPC Client**: grpcio, protobuf
- **Validation**: Pydantic v2
- **Testing**: pytest, pytest-asyncio, httpx
- **Code Quality**: ruff (linting), black (formatting), mypy (type checking)
### C# SDK Bridge
- **Framework**: .NET Framework 4.8 (SDK runtime), .NET 8.0 (gRPC service)
- **gRPC**: Grpc.Core, Grpc.Tools
- **SDK**: GeViScope SDK 7.9.975.68+ (GeViProcAPINET_4_0.dll)
- **Testing**: xUnit, Moq
- **Logging**: Serilog
### Infrastructure
- **Database**: PostgreSQL 14+ (user data, audit logs)
- **Cache**: Redis 6.0+ (sessions, pub/sub)
- **Deployment**: Docker (API layer), Windows Service (SDK bridge)
- **CI/CD**: GitHub Actions
- **Monitoring**: Prometheus metrics, Grafana dashboards
## Commands Reference
### Development
```bash
# Setup environment
.\scripts\setup_dev_environment.ps1
# Start all services
.\scripts\start_services.ps1
# Run API server (development)
cd src/api
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# Run SDK bridge (development)
cd src/sdk-bridge
dotnet run --configuration Debug
# Run tests
pytest tests/api -v --cov=src/api --cov-report=html # Python
dotnet test tests/sdk-bridge/ # C#
# Format code
ruff check src/api --fix # Python linting
black src/api # Python formatting
# Database migrations
alembic upgrade head # Apply migrations
alembic revision --autogenerate -m "description" # Create migration
```
### API Usage
```bash
# Authenticate
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "sysadmin", "password": "masterkey"}'
# List cameras
curl -X GET http://localhost:8000/api/v1/cameras \
-H "Authorization: Bearer YOUR_TOKEN"
# Start stream
curl -X POST http://localhost:8000/api/v1/cameras/{id}/stream \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"resolution": {"width": 1920, "height": 1080, "fps": 30}, "format": "h264"}'
# WebSocket events (Python)
import websockets
uri = f"ws://localhost:8000/api/v1/events/stream?token={TOKEN}"
async with websockets.connect(uri) as ws:
await ws.send('{"action": "subscribe", "filters": {"event_types": ["motion_detected"]}}')
while True:
event = await ws.recv()
print(event)
```
## Next Steps
1. **Run `/speckit.tasks`** to generate Phase 2 task breakdown
2. **Review tasks** for sequencing and dependencies
3. **Execute `/speckit.implement`** to begin TDD implementation
4. **Iterate** through tasks following Red-Green-Refactor cycle
## 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
- **API Contract**: [contracts/openapi.yaml](./contracts/openapi.yaml) - Complete REST API spec
- **Quick Start**: [quickstart.md](./quickstart.md) - Developer onboarding guide
- **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 🔄 IN PROGRESS (Configuration Management ✅)
**Last Updated**: 2025-12-16

View File

@@ -0,0 +1,700 @@
# Quick Start Guide
**Geutebruck Surveillance API** - REST API for GeViScope/GeViSoft video surveillance systems
---
## Overview
This API provides RESTful access to Geutebruck surveillance systems, enabling:
- **Camera Management**: List cameras, get status, control PTZ
- **Live Streaming**: Start/stop video streams with token authentication
- **Event Monitoring**: Subscribe to real-time surveillance events (motion, alarms, analytics)
- **Recording Access**: Query and export recorded video segments
- **Analytics Configuration**: Configure video analytics (VMD, NPR, object tracking)
**Architecture**: Python FastAPI + C# gRPC SDK Bridge + GeViScope SDK
---
## Prerequisites
### System Requirements
- **Operating System**: Windows 10/11 or Windows Server 2016+
- **GeViSoft Installation**: Full GeViSoft application + SDK
- **Visual C++ 2010 Redistributable (x86)**: Required for SDK
- **Python**: 3.11+ (for API server)
- **.NET Framework**: 4.8 (for SDK bridge)
- **Redis**: 6.0+ (for session management and pub/sub)
### GeViSoft SDK Setup
**CRITICAL**: Install in this exact order:
1. **Install Visual C++ 2010 Redistributable (x86)**
```powershell
# Download and install
Invoke-WebRequest -Uri 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe' -OutFile 'vcredist_x86_2010.exe'
Start-Process -FilePath 'vcredist_x86_2010.exe' -ArgumentList '/install', '/quiet', '/norestart' -Wait
```
2. **Install GeViSoft Full Application**
- Download from Geutebruck
- Run installer
- Complete setup wizard
3. **Install GeViSoft SDK**
- Download SDK installer
- Run SDK setup
- Verify installation in `C:\Program Files (x86)\GeViScopeSDK\`
4. **Start GeViServer**
```cmd
cd C:\GEVISOFT
GeViServer.exe console
```
**Verification**:
```powershell
# Check GeViServer is running
netstat -an | findstr "7700 7701 7703"
# Should show LISTENING on these ports
```
See [SDK_INTEGRATION_LESSONS.md](../../SDK_INTEGRATION_LESSONS.md) for complete deployment details.
---
## Installation
### 1. Clone Repository
```bash
git clone https://github.com/your-org/geutebruck-api.git
cd geutebruck-api
```
### 2. Install Dependencies
**Python API Server**:
```bash
cd src/api
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
```
**C# SDK Bridge**:
```bash
cd src/sdk-bridge
dotnet restore
dotnet build --configuration Release
```
### 3. Install Redis
**Using Chocolatey**:
```powershell
choco install redis-64
redis-server
```
Or download from: https://redis.io/download
---
## Configuration
### Environment Variables
Create `.env` file in `src/api/`:
```env
# API Configuration
API_HOST=0.0.0.0
API_PORT=8000
API_TITLE=Geutebruck Surveillance API
API_VERSION=1.0.0
# GeViScope Connection
GEVISCOPE_HOST=localhost
GEVISCOPE_USERNAME=sysadmin
GEVISCOPE_PASSWORD=masterkey
# SDK Bridge gRPC
SDK_BRIDGE_HOST=localhost
SDK_BRIDGE_PORT=50051
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=
# JWT Authentication
JWT_SECRET_KEY=your-secret-key-change-in-production
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=60
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# Stream URLs
STREAM_BASE_URL=rtsp://localhost:8554
STREAM_TOKEN_EXPIRE_MINUTES=15
# Logging
LOG_LEVEL=INFO
LOG_FORMAT=json
```
**Security Note**: Change `JWT_SECRET_KEY` and `GEVISCOPE_PASSWORD` in production!
### Database Migrations
```bash
cd src/api
alembic upgrade head
```
---
## Starting the Services
### 1. Start GeViServer
```cmd
cd C:\GEVISOFT
GeViServer.exe console
```
### 2. Start Redis
```bash
redis-server
```
### 3. Start SDK Bridge
```bash
cd src/sdk-bridge
dotnet run --configuration Release
```
### 4. Start API Server
```bash
cd src/api
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```
**Verify Services**:
- API: http://localhost:8000/api/v1/health
- API Docs: http://localhost:8000/docs
- SDK Bridge: gRPC on localhost:50051
---
## First API Call
### 1. Authenticate
**Request**:
```bash
curl -X POST "http://localhost:8000/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "sysadmin",
"password": "masterkey"
}'
```
**Response**:
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600
}
```
**Save the access token** - you'll need it for all subsequent requests.
### 2. List Cameras
**Request**:
```bash
curl -X GET "http://localhost:8000/api/v1/cameras" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Response**:
```json
{
"total": 2,
"page": 1,
"page_size": 50,
"cameras": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"channel": 1,
"name": "Front Entrance",
"description": "Main entrance camera",
"status": "online",
"capabilities": {
"ptz": true,
"audio": false,
"analytics": ["motion_detection", "people_counting"]
},
"resolutions": [
{"width": 1920, "height": 1080, "fps": 30},
{"width": 1280, "height": 720, "fps": 60}
]
}
]
}
```
### 3. Start Video Stream
**Request**:
```bash
curl -X POST "http://localhost:8000/api/v1/cameras/550e8400-e29b-41d4-a716-446655440001/stream" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resolution": {"width": 1920, "height": 1080, "fps": 30},
"format": "h264"
}'
```
**Response**:
```json
{
"stream_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"camera_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "rtsp://localhost:8554/stream/7c9e6679?token=eyJhbGc...",
"format": "h264",
"resolution": {"width": 1920, "height": 1080, "fps": 30},
"started_at": "2025-12-08T15:30:00Z",
"expires_at": "2025-12-08T15:45:00Z"
}
```
**Use the stream URL** in your video player (VLC, ffplay, etc.):
```bash
ffplay "rtsp://localhost:8554/stream/7c9e6679?token=eyJhbGc..."
```
---
## Common Use Cases
### Python SDK Example
```python
import requests
from typing import Dict, Any
class GeutebruckAPI:
def __init__(self, base_url: str = "http://localhost:8000"):
self.base_url = base_url
self.access_token = None
def login(self, username: str, password: str) -> Dict[str, Any]:
"""Authenticate and get access token"""
response = requests.post(
f"{self.base_url}/api/v1/auth/login",
json={"username": username, "password": password}
)
response.raise_for_status()
data = response.json()
self.access_token = data["access_token"]
return data
def get_cameras(self) -> Dict[str, Any]:
"""List all cameras"""
response = requests.get(
f"{self.base_url}/api/v1/cameras",
headers={"Authorization": f"Bearer {self.access_token}"}
)
response.raise_for_status()
return response.json()
def start_stream(self, camera_id: str, width: int = 1920, height: int = 1080) -> Dict[str, Any]:
"""Start video stream from camera"""
response = requests.post(
f"{self.base_url}/api/v1/cameras/{camera_id}/stream",
headers={"Authorization": f"Bearer {self.access_token}"},
json={
"resolution": {"width": width, "height": height, "fps": 30},
"format": "h264"
}
)
response.raise_for_status()
return response.json()
# Usage
api = GeutebruckAPI()
api.login("sysadmin", "masterkey")
cameras = api.get_cameras()
stream = api.start_stream(cameras["cameras"][0]["id"])
print(f"Stream URL: {stream['url']}")
```
### WebSocket Event Monitoring
```python
import asyncio
import websockets
import json
async def monitor_events(access_token: str):
"""Subscribe to real-time surveillance events"""
uri = f"ws://localhost:8000/api/v1/events/stream?token={access_token}"
async with websockets.connect(uri) as websocket:
# Subscribe to specific event types
await websocket.send(json.dumps({
"action": "subscribe",
"filters": {
"event_types": ["motion_detected", "alarm_triggered"],
"camera_ids": ["550e8400-e29b-41d4-a716-446655440001"]
}
}))
# Receive events
while True:
message = await websocket.recv()
event = json.loads(message)
print(f"Event: {event['event_type']} on camera {event['camera_id']}")
print(f" Timestamp: {event['timestamp']}")
print(f" Details: {event['details']}")
# Run
asyncio.run(monitor_events("YOUR_ACCESS_TOKEN"))
```
### PTZ Camera Control
```bash
# Move camera to preset position
curl -X POST "http://localhost:8000/api/v1/cameras/550e8400-e29b-41d4-a716-446655440001/ptz" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"command": "goto_preset",
"preset": 1
}'
# Pan/tilt/zoom control
curl -X POST "http://localhost:8000/api/v1/cameras/550e8400-e29b-41d4-a716-446655440001/ptz" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"command": "move",
"pan": 50,
"tilt": 30,
"zoom": 2.5,
"speed": 50
}'
```
### Query Recordings
```python
import requests
from datetime import datetime, timedelta
def get_recordings(camera_id: str, access_token: str):
"""Get recordings from last 24 hours"""
end_time = datetime.utcnow()
start_time = end_time - timedelta(hours=24)
response = requests.get(
"http://localhost:8000/api/v1/recordings",
headers={"Authorization": f"Bearer {access_token}"},
params={
"camera_id": camera_id,
"start_time": start_time.isoformat() + "Z",
"end_time": end_time.isoformat() + "Z",
"event_type": "motion_detected"
}
)
response.raise_for_status()
return response.json()
# Usage
recordings = get_recordings("550e8400-e29b-41d4-a716-446655440001", "YOUR_ACCESS_TOKEN")
for rec in recordings["recordings"]:
print(f"Recording: {rec['start_time']} - {rec['end_time']}")
print(f" Size: {rec['size_bytes'] / 1024 / 1024:.2f} MB")
print(f" Export URL: {rec['export_url']}")
```
### Configure Video Analytics
```bash
# Enable motion detection
curl -X POST "http://localhost:8000/api/v1/analytics/550e8400-e29b-41d4-a716-446655440001" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "motion_detection",
"enabled": true,
"configuration": {
"sensitivity": 75,
"regions": [
{
"name": "entrance",
"points": [
{"x": 100, "y": 100},
{"x": 500, "y": 100},
{"x": 500, "y": 400},
{"x": 100, "y": 400}
]
}
],
"schedule": {
"enabled": true,
"start_time": "18:00:00",
"end_time": "06:00:00",
"days": [1, 2, 3, 4, 5, 6, 7]
}
}
}'
```
---
## Testing
### Run Unit Tests
```bash
cd src/api
pytest tests/unit -v --cov=app --cov-report=html
```
### Run Integration Tests
```bash
# Requires running GeViServer and SDK Bridge
pytest tests/integration -v
```
### Test Coverage
Minimum 80% coverage enforced. View coverage report:
```bash
# Open coverage report
start htmlcov/index.html # Windows
open htmlcov/index.html # macOS
```
---
## API Documentation
### Interactive Docs
Once the API is running, visit:
- **Swagger UI**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
- **OpenAPI JSON**: http://localhost:8000/openapi.json
### Complete API Reference
See [contracts/openapi.yaml](./contracts/openapi.yaml) for the complete OpenAPI 3.0 specification.
### Data Model
See [data-model.md](./data-model.md) for entity schemas, relationships, and validation rules.
### Architecture
See [research.md](./research.md) for:
- System architecture decisions
- SDK integration patterns
- Performance considerations
- Security implementation
---
## Troubleshooting
### Common Issues
**1. "Could not load file or assembly 'GeViProcAPINET_4_0.dll'"**
**Solution**: Install Visual C++ 2010 Redistributable (x86):
```powershell
Invoke-WebRequest -Uri 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe' -OutFile 'vcredist_x86_2010.exe'
Start-Process -FilePath 'vcredist_x86_2010.exe' -ArgumentList '/install', '/quiet', '/norestart' -Wait
```
**2. "Connection refused to GeViServer"**
**Solution**: Ensure GeViServer is running:
```cmd
cd C:\GEVISOFT
GeViServer.exe console
```
Check ports: `netstat -an | findstr "7700 7701 7703"`
**3. "Redis connection failed"**
**Solution**: Start Redis server:
```bash
redis-server
```
**4. "SDK Bridge gRPC not responding"**
**Solution**: Check SDK Bridge logs and restart:
```bash
cd src/sdk-bridge
dotnet run --configuration Release
```
**5. "401 Unauthorized" on API calls**
**Solution**: Check your access token hasn't expired (1 hour lifetime). Use refresh token to get new access token:
```bash
curl -X POST "http://localhost:8000/api/v1/auth/refresh" \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "YOUR_REFRESH_TOKEN"
}'
```
### Debug Mode
Enable debug logging:
```env
LOG_LEVEL=DEBUG
```
View logs:
```bash
# API logs
tail -f logs/api.log
# SDK Bridge logs
tail -f src/sdk-bridge/logs/bridge.log
```
### Health Check
```bash
# API health
curl http://localhost:8000/api/v1/health
# Expected response
{
"status": "healthy",
"timestamp": "2025-12-08T15:30:00Z",
"version": "1.0.0",
"dependencies": {
"sdk_bridge": "connected",
"redis": "connected",
"database": "connected"
}
}
```
---
## Performance Tuning
### Response Time Optimization
**Target**: <200ms for most endpoints
```env
# Connection pooling
SDK_BRIDGE_POOL_SIZE=10
SDK_BRIDGE_MAX_OVERFLOW=20
# Redis connection pool
REDIS_MAX_CONNECTIONS=50
# Async workers
UVICORN_WORKERS=4
```
### WebSocket Scaling
**Target**: 1000+ concurrent connections
```env
# Redis pub/sub
REDIS_PUBSUB_MAX_CONNECTIONS=100
# WebSocket timeouts
WEBSOCKET_PING_INTERVAL=30
WEBSOCKET_PING_TIMEOUT=10
```
### Stream URL Caching
Stream URLs are cached for token lifetime (15 minutes) to reduce SDK bridge calls.
---
## Security Considerations
### Production Deployment
**CRITICAL**: Before deploying to production:
1. **Change default credentials**:
```env
GEVISCOPE_PASSWORD=your-secure-password-here
JWT_SECRET_KEY=generate-with-openssl-rand-hex-32
REDIS_PASSWORD=your-redis-password
```
2. **Enable HTTPS**:
- Use reverse proxy (nginx/Caddy) with SSL certificates
- Redirect HTTP to HTTPS
3. **Network security**:
- GeViServer should NOT be exposed to internet
- API should be behind firewall/VPN
- Use internal network for SDK Bridge ↔ GeViServer communication
4. **Rate limiting**:
```env
RATE_LIMIT_PER_MINUTE=60
RATE_LIMIT_BURST=10
```
5. **Audit logging**:
```env
AUDIT_LOG_ENABLED=true
AUDIT_LOG_PATH=/var/log/geutebruck-api/audit.log
```
See [security.md](./security.md) for complete security guidelines.
---
## Next Steps
1. **Read the Architecture**: [research.md](./research.md) - Understanding system design decisions
2. **Explore Data Model**: [data-model.md](./data-model.md) - Entity schemas and relationships
3. **API Reference**: [contracts/openapi.yaml](./contracts/openapi.yaml) - Complete endpoint documentation
4. **SDK Integration**: [../../SDK_INTEGRATION_LESSONS.md](../../SDK_INTEGRATION_LESSONS.md) - Deep dive into SDK usage
5. **Join Development**: [CONTRIBUTING.md](../../CONTRIBUTING.md) - Contributing guidelines
---
## Support
- **Issues**: https://github.com/your-org/geutebruck-api/issues
- **Documentation**: https://docs.geutebruck-api.example.com
- **GeViScope SDK**: See `C:\GEVISOFT\Documentation\`
---
**Version**: 1.0.0
**Last Updated**: 2025-12-08

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,485 @@
# Feature Specification: Geutebruck Unified Video Surveillance API
**Feature Branch**: `001-surveillance-api`
**Created**: 2025-11-13
**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)*
### User Story 1 - Secure API Access (Priority: P1)
As a developer integrating a custom surveillance application, I need to authenticate to the API securely so that only authorized users can access camera feeds and control functions.
**Why this priority**: Without authentication, the entire system is insecure and unusable. This is the foundation for all other features and must be implemented first.
**Independent Test**: Can be fully tested by attempting to access protected endpoints without credentials (should fail), then with valid JWT tokens (should succeed), and delivers a working authentication system that all other features depend on.
**Acceptance Scenarios**:
1. **Given** a developer with valid credentials, **When** they request a JWT token from `/api/v1/auth/login`, **Then** they receive a token valid for 1 hour with appropriate user claims
2. **Given** an expired JWT token, **When** they attempt to access a protected endpoint, **Then** they receive a 401 Unauthorized response with clear error message
3. **Given** a valid refresh token, **When** they request a new access token, **Then** they receive a fresh JWT token without re-authenticating
4. **Given** invalid credentials, **When** they attempt to login, **Then** they receive a 401 response and the failed attempt is logged for security monitoring
---
### 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.
**Why this priority**: Live video viewing is the core function of surveillance systems. Without this, the system cannot fulfill its primary purpose.
**Independent Test**: Can be fully tested by requesting stream URLs for configured cameras and verifying that video playback works, delivering immediate value as a basic surveillance viewer.
**Acceptance Scenarios**:
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 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.
**Why this priority**: PTZ control is essential for active surveillance operations and incident response, making it critical for operational use.
**Independent Test**: Can be fully tested by sending PTZ commands (pan left/right, tilt up/down, zoom in/out) to a PTZ-capable camera and verifying movement occurs, delivering functional camera control capabilities.
**Acceptance Scenarios**:
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 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.
**Why this priority**: Real-time alerts are critical for security effectiveness. Without event notifications, operators must constantly monitor all cameras manually.
**Independent Test**: Can be fully tested by subscribing to event notifications via WebSocket, triggering a test alarm, and verifying notification delivery within 100ms, providing functional event monitoring.
**Acceptance Scenarios**:
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 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.
**Why this priority**: Important for compliance and investigations but not required for basic live monitoring. Can be added after core live viewing is functional.
**Independent Test**: Can be fully tested by configuring recording schedules, starting/stopping recording on specific cameras, and querying recorded footage by time range, delivering complete recording management.
**Acceptance Scenarios**:
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 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.
**Why this priority**: Enhances system capabilities but requires basic video viewing to already be working. Analytics configuration is valuable but not essential for day-one operation.
**Independent Test**: Can be fully tested by configuring motion detection zones on a camera, triggering motion, and verifying analytics events are generated, delivering automated detection capabilities.
**Acceptance Scenarios**:
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 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 11 - Action Mapping and Automation (Priority: P3)
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**: Valuable for automation but requires basic event and action functionality to be working first.
**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 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 12 - GeViSoft Configuration Management (Priority: P1) ✅ IMPLEMENTED
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**: Configuration management is essential for automation, infrastructure-as-code, and maintaining consistent configurations across environments.
**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** 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 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 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, 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, active streams per instance, and connection status for all instances
---
### Edge Cases
- 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
**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
- **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
- **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 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 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
- 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, 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 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 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
- Audit logging must be tamper-evident
- Credentials for GeViSoft and GeViScope instances must be stored securely
## Risk Analysis
### High Impact Risks
1. **Multi-Instance Complexity**: Managing connections to multiple GeViScope instances increases failure modes
- *Mitigation*: Circuit breaker per instance, independent health monitoring, graceful degradation
2. **CrossSwitch Verification**: Confirming routes are active requires viewer applications
- *Mitigation*: Document viewer requirements, provide route tracking in database, API-level route verification
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. **Instance Configuration Management**: Adding/removing instances requires careful config management
- *Mitigation*: Configuration validation, instance health checks, hot-reload support
5. **SDK Version Compatibility**: Different GeViScope instances may run different SDK versions
- *Mitigation*: Version detection, compatibility matrix, graceful feature detection
6. **Monitor ID Confusion**: Monitor IDs overlap across instances
- *Mitigation*: Always scope monitors by instance ID in API, clear documentation
## Notes
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.
**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
**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

View File

@@ -0,0 +1,437 @@
# Tasks: Geutebruck Cross-Switching API (Revised MVP)
**Scope**: Cross-switching REST API with authentication, focusing on GeViSet-compatible configuration
**MVP Goal**: Control GSCView viewers via cross-switching, no UI needed
**Future Expansion**: GeViSet configuration management, action mapping, CSV import/export
---
## MVP User Stories
### US1: Authentication & Connection
Connect to GeViServer, authenticate users, maintain sessions
### US2: Camera Discovery
List all video inputs (cameras) with metadata
### US3: Monitor Discovery
List all video outputs (GSCView viewers/monitors) with status
### US4: Cross-Switching Operations
Route cameras to viewers, clear viewers, query routing state
---
## Revised Data Model (Simplified)
```
User:
- id, username, password_hash, role (viewer/operator/admin)
Camera:
- id (channel), name, description, has_ptz, has_video_sensor, status
Monitor:
- id (output channel), name, is_active, current_camera_id
CrossSwitchRoute:
- id, camera_id, monitor_id, switched_at, switched_by_user_id
AuditLog:
- id, user_id, action, target, timestamp, details
```
---
## Phase 1: Foundation (Setup & Core Infrastructure)
**Purpose**: Project structure, dependencies, SDK bridge foundation
- [ ] T001 Create project structure (src/api, src/sdk-bridge, tests, docs, scripts)
- [ ] T002 Create .gitignore for Python and C#
- [ ] T003 Create requirements.txt with FastAPI, SQLAlchemy, Redis, grpcio, PyJWT, pytest
- [ ] T004 Create SDK Bridge .csproj with .NET 8.0, Grpc.AspNetCore, GeViScope SDK reference
- [ ] T005 Create .env.example with config variables (DB, Redis, JWT secret, GeViServer host/credentials)
- [ ] T006 Create alembic.ini for database migrations
- [ ] T007 [P] Create pyproject.toml with ruff, black, mypy configuration
- [ ] T008 [P] Create scripts/setup_dev_environment.ps1 (install dependencies, setup DB, start services)
- [ ] T009 [P] Create scripts/start_services.ps1 (start Redis, SDK Bridge, FastAPI)
- [ ] T010 [P] Create docs/architecture.md documenting system design
**Checkpoint**: Project structure complete, dependencies defined
---
## Phase 2: SDK Bridge Foundation (C# gRPC Service)
**Purpose**: Wrap GeViScope SDK with gRPC for Python consumption
### gRPC Protocol Definitions
- [ ] T011 Define common.proto (Status, Error, Timestamp, Empty messages)
- [ ] T012 Define camera.proto (ListCamerasRequest/Response, CameraInfo with channel, name, has_ptz)
- [ ] T013 Define monitor.proto (ListMonitorsRequest/Response, MonitorInfo with channel, name, current_camera)
- [ ] T014 Define crossswitch.proto (CrossSwitchRequest, ClearMonitorRequest, GetRoutingStateRequest/Response)
### SDK Wrapper Implementation
- [ ] T015 Create GeViDatabaseWrapper.cs (Create, RegisterCallback, Connect, Disconnect, error handling)
- [ ] T016 Implement connection lifecycle with retry logic (3 attempts, exponential backoff)
- [ ] T017 Create StateQueryHandler.cs for GetFirst/GetNext enumeration pattern
- [ ] T018 Implement EnumerateCameras() using CSQGetFirstVideoInput / CSQGetNextVideoInput
- [ ] T019 Implement EnumerateMonitors() using CSQGetFirstVideoOutput / CSQGetNextVideoOutput
- [ ] T020 Create ErrorTranslator.cs to map Windows error codes to gRPC status codes
- [ ] T021 Create ActionDispatcher.cs for sending SDK actions (CrossSwitch, ClearVideoOutput)
### gRPC Service Implementation
- [ ] T022 Create CameraService.cs implementing camera.proto with ListCameras RPC
- [ ] T023 Create MonitorService.cs implementing monitor.proto with ListMonitors RPC
- [ ] T024 Create CrossSwitchService.cs with ExecuteCrossSwitch, ClearMonitor, GetRoutingState RPCs
- [ ] T025 Create Program.cs gRPC server with Serilog logging, service registration
- [ ] T026 Add configuration loading from appsettings.json (GeViServer host, port, credentials)
**Checkpoint**: SDK Bridge can connect to GeViServer, enumerate resources, execute cross-switch
---
## Phase 3: Python API Foundation
**Purpose**: FastAPI application structure, configuration, database setup
### Core Setup
- [ ] T027 Create main.py with FastAPI app, CORS middleware, exception handlers
- [ ] T028 Create config.py loading settings from environment (Pydantic BaseSettings)
- [ ] T029 Setup PostgreSQL connection with SQLAlchemy async engine in models/__init__.py
- [ ] T030 Create initial Alembic migration for users and audit_logs tables
- [ ] T031 Setup Redis client with connection pooling in clients/redis_client.py
- [ ] T032 Create gRPC SDK Bridge client in clients/sdk_bridge_client.py with connection pooling
- [ ] T033 [P] Create JWT utilities in utils/jwt_utils.py (encode, decode, verify)
- [ ] T034 [P] Create error translation utilities in utils/error_translation.py (gRPC → HTTP status)
- [ ] T035 Implement global error handler middleware in middleware/error_handler.py
### Database Models
- [ ] T036 [P] Create User model in models/user.py (id, username, password_hash, role, created_at)
- [ ] T037 [P] Create AuditLog model in models/audit_log.py (id, user_id, action, target, timestamp)
- [ ] T038 Run alembic upgrade head to create tables
**Checkpoint**: Python API can start, connect to DB/Redis, communicate with SDK Bridge via gRPC
---
## Phase 4: Authentication (User Story 1)
**Purpose**: JWT-based authentication with role-based access control
### Tests (TDD - Write FIRST, Ensure FAIL)
- [ ] T039 [P] Write contract test for POST /api/v1/auth/login in tests/api/contract/test_auth.py (should FAIL)
- [ ] T040 [P] Write contract test for POST /api/v1/auth/logout in tests/api/contract/test_auth.py (should FAIL)
- [ ] T041 [P] Write unit test for AuthService in tests/api/unit/test_auth_service.py (should FAIL)
### Implementation
- [ ] T042 [P] Create auth schemas in schemas/auth.py (LoginRequest, TokenResponse, UserInfo)
- [ ] T043 Implement AuthService in services/auth_service.py (login, logout, validate_token, hash_password)
- [ ] T044 Implement JWT token generation (access: 1hr, refresh: 7 days) with Redis session storage
- [ ] T045 Implement authentication middleware in middleware/auth_middleware.py (verify JWT, extract user)
- [ ] T046 Implement role checking decorator in utils/permissions.py (@require_role("operator"))
- [ ] T047 Create auth router in routers/auth.py with POST /auth/login, POST /auth/logout
- [ ] T048 Add audit logging for authentication attempts (success and failures)
**Verify**: Run tests T039-T041 - should now PASS
**Checkpoint**: Can login with credentials, receive JWT token, use token for authenticated requests
---
## Phase 5: Camera Discovery (User Story 2)
**Purpose**: List all cameras (video inputs) from GeViServer
### Tests (TDD - Write FIRST, Ensure FAIL)
- [ ] T049 [P] Write contract test for GET /api/v1/cameras in tests/api/contract/test_cameras.py (should FAIL)
- [ ] T050 [P] Write unit test for CameraService in tests/api/unit/test_camera_service.py (should FAIL)
### Implementation
- [ ] T051 [P] Create camera schemas in schemas/camera.py (CameraInfo, CameraList)
- [ ] T052 Implement CameraService in services/camera_service.py (list_cameras via gRPC to SDK Bridge)
- [ ] T053 Create cameras router in routers/cameras.py with GET /cameras
- [ ] T054 Add permission check: authenticated users only
- [ ] T055 Add caching in Redis (cache camera list for 60 seconds to reduce SDK Bridge load)
**Verify**: Run tests T049-T050 - should now PASS
**Checkpoint**: GET /api/v1/cameras returns list of all cameras from GeViServer
---
## Phase 6: Monitor Discovery (User Story 3)
**Purpose**: List all monitors/viewers (video outputs) from GeViServer
### Tests (TDD - Write FIRST, Ensure FAIL)
- [ ] T056 [P] Write contract test for GET /api/v1/monitors in tests/api/contract/test_monitors.py (should FAIL)
- [ ] T057 [P] Write unit test for MonitorService in tests/api/unit/test_monitor_service.py (should FAIL)
### Implementation
- [ ] T058 [P] Create monitor schemas in schemas/monitor.py (MonitorInfo, MonitorList)
- [ ] T059 Implement MonitorService in services/monitor_service.py (list_monitors via gRPC to SDK Bridge)
- [ ] T060 Create monitors router in routers/monitors.py with GET /monitors
- [ ] T061 Add permission check: authenticated users only
- [ ] T062 Add caching in Redis (cache monitor list for 60 seconds)
**Verify**: Run tests T056-T057 - should now PASS
**Checkpoint**: GET /api/v1/monitors returns list of all monitors/viewers from GeViServer
---
## Phase 7: Cross-Switching Operations (User Story 4)
**Purpose**: Execute cross-switch, clear monitors, query routing state
### Tests (TDD - Write FIRST, Ensure FAIL)
- [ ] T063 [P] Write contract test for POST /api/v1/crossswitch in tests/api/contract/test_crossswitch.py (should FAIL)
- [ ] T064 [P] Write contract test for DELETE /api/v1/monitors/{id} in tests/api/contract/test_crossswitch.py (should FAIL)
- [ ] T065 [P] Write contract test for GET /api/v1/routing/state in tests/api/contract/test_crossswitch.py (should FAIL)
- [ ] T066 [P] Write integration test for cross-switch workflow in tests/api/integration/test_crossswitch.py (should FAIL)
### Implementation
- [ ] T067 [P] Create crossswitch schemas in schemas/crossswitch.py (CrossSwitchRequest, RoutingState, ClearMonitorRequest)
- [ ] T068 Create CrossSwitchRoute model in models/crossswitch_route.py (id, camera_id, monitor_id, switched_at, user_id)
- [ ] T069 Create Alembic migration for crossswitch_routes table
- [ ] T070 Implement CrossSwitchService in services/crossswitch_service.py:
- execute_crossswitch(camera_id, monitor_id, mode=0) → gRPC to SDK Bridge
- clear_monitor(monitor_id) → gRPC ClearVideoOutput
- get_routing_state() → query current routes
- [ ] T071 Create crossswitch router in routers/crossswitch.py:
- POST /crossswitch (requires operator or admin role)
- DELETE /monitors/{id} (requires operator or admin role)
- GET /routing/state (all authenticated users)
- [ ] T072 Add audit logging for all cross-switch operations
- [ ] T073 Add validation: camera_id and monitor_id must exist
- [ ] T074 Store routing state in database for history/tracking
**Verify**: Run tests T063-T066 - should now PASS
**Checkpoint**: Can execute cross-switch via API, clear monitors, query current routing
---
## Phase 8: MVP Polish & Documentation
**Purpose**: Complete MVP with documentation and deployment readiness
- [ ] T075 [P] Create API documentation in docs/api-usage.md with curl examples
- [ ] T076 [P] Create deployment guide in docs/deployment.md (Windows Server setup, service installation)
- [ ] T077 [P] Add Prometheus metrics endpoint at /metrics (request count, latency, active connections)
- [ ] T078 [P] Create health check endpoint GET /health (SDK Bridge connectivity, DB, Redis status)
- [ ] T079 [P] Add request logging with correlation IDs
- [ ] T080 Create README.md with project overview, quick start, architecture diagram
- [ ] T081 Update OpenAPI specification to include only MVP endpoints
- [ ] T082 Create Postman collection for API testing
- [ ] T083 Run full integration tests with actual GeViServer connection
- [ ] T084 Security audit: Remove stack traces in production, sanitize logs
**Checkpoint**: MVP complete - REST API for cross-switching with authentication
---
## Phase 9: Future - GeViSet Configuration Management (Phase 2)
**Purpose**: GeViSet-like functionality via API (action mapping configuration)
**Note**: These tasks will be detailed after MVP is complete and working
### High-Level Tasks:
- [ ] T085 Research GeViSet configuration file format and action mapping structure
- [ ] T086 Implement GET /api/v1/config/actions to retrieve action mappings from GeViServer
- [ ] T087 Implement PUT /api/v1/config/actions to push action mappings to GeViServer
- [ ] T088 Implement POST /api/v1/config/actions/export to export configuration to CSV
- [ ] T089 Implement POST /api/v1/config/actions/import to import configuration from CSV
- [ ] T090 Add validation for action mapping syntax and constraints
- [ ] T091 Add versioning for configuration changes (track who changed what, when)
- [ ] T092 Add backup/restore functionality for configurations
**Checkpoint**: GeViSet configuration management available via API
---
## Dependencies & Execution Order
### Phase Dependencies
```
Phase 1 (Setup)
Phase 2 (SDK Bridge Foundation) ← BLOCKS all Python API work
Phase 3 (Python API Foundation) ← BLOCKS all feature work
Phase 4 (Authentication) ← BLOCKS all protected endpoints
Phases 5, 6, 7 can proceed in parallel (after Phase 4)
Phase 8 (Polish & Documentation)
Phase 9 (Future - GeViSet config) ← After MVP validated
```
### Critical Path (Sequential)
1. Setup → SDK Bridge → Python API → Authentication
2. Then parallel: Camera Discovery + Monitor Discovery + Cross-Switching
3. Then: Polish & Documentation
4. Finally: GeViSet configuration (Phase 2)
### Parallel Opportunities
- Phase 2: T020 (ErrorTranslator) parallel with T017-T019 (StateQuery implementation)
- Phase 3: T033-T034, T036-T037 can run in parallel
- Phase 4: T039-T041 tests can run in parallel
- Phase 5-7: These entire phases can run in parallel after Phase 4 completes
- Phase 8: T075-T082 can run in parallel
---
## Implementation Strategy
### Week 1: Foundation
- Days 1-2: Phase 1 (Setup)
- Days 3-5: Phase 2 (SDK Bridge)
### Week 2: API Core
- Days 1-3: Phase 3 (Python API Foundation)
- Days 4-5: Phase 4 (Authentication)
### Week 3: Cross-Switching
- Days 1-2: Phase 5 (Camera Discovery)
- Days 2-3: Phase 6 (Monitor Discovery)
- Days 4-5: Phase 7 (Cross-Switching Operations)
### Week 4: Polish & Validation
- Days 1-3: Phase 8 (Polish, Documentation)
- Days 4-5: Integration testing with real GeViServer, bug fixes
**MVP Delivery**: End of Week 4
### Week 5+: Phase 2 Features
- GeViSet configuration management
- Action mapping CRUD
- CSV import/export
---
## Task Summary
**MVP Total**: 84 tasks
**By Phase**:
- Phase 1 (Setup): 10 tasks
- Phase 2 (SDK Bridge): 16 tasks
- Phase 3 (API Foundation): 12 tasks
- Phase 4 (Authentication): 10 tasks
- Phase 5 (Camera Discovery): 7 tasks
- Phase 6 (Monitor Discovery): 7 tasks
- Phase 7 (Cross-Switching): 12 tasks
- Phase 8 (Polish): 10 tasks
**Phase 2 (Future)**: 8+ tasks (detailed after MVP)
**Tests**: 12 test tasks (TDD approach)
**Parallel Tasks**: 20+ tasks marked [P]
**Estimated Timeline**:
- MVP: 3-4 weeks (1 developer, focused work)
- Phase 2 (GeViSet config): +1-2 weeks
---
## MVP Endpoints Summary
```
# Authentication
POST /api/v1/auth/login # Get JWT token
POST /api/v1/auth/logout # Invalidate token
# Cameras
GET /api/v1/cameras # List all cameras
# Monitors
GET /api/v1/monitors # List all monitors/viewers
# Cross-Switching
POST /api/v1/crossswitch # Execute cross-switch
Body: { camera_id: 7, monitor_id: 3, mode: 0 }
DELETE /api/v1/monitors/{id} # Clear monitor (stop video)
GET /api/v1/routing/state # Get current routing state
# System
GET /api/v1/health # Health check (SDK Bridge, DB, Redis)
GET /metrics # Prometheus metrics
```
---
## Testing Strategy
### TDD Approach
1. Write contract test (should FAIL)
2. Write unit tests (should FAIL)
3. Implement feature
4. Run tests (should PASS)
5. Refactor if needed
6. Commit
### Test Coverage Goal
- Minimum 70% coverage for MVP
- 100% coverage for authentication and cross-switching logic
### Manual Testing
- Test with Postman collection
- Test with curl commands
- Integration test with actual GeViServer
---
**Generated**: 2025-12-08
**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.
---

View File

@@ -0,0 +1,771 @@
# Tasks: Geutebruck Surveillance API
**Input**: Design documents from `/specs/001-surveillance-api/`
**Prerequisites**: plan.md ✅, spec.md ✅, research.md ✅, data-model.md ✅, contracts/openapi.yaml ✅
**Tests**: TDD approach enforced - all tests MUST be written first and FAIL before implementation begins.
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
---
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
---
## Path Conventions
This project uses **web application structure**:
- **Python API**: `src/api/` (FastAPI application)
- **C# SDK Bridge**: `src/sdk-bridge/` (gRPC service)
- **Tests**: `tests/api/` (Python), `tests/sdk-bridge/` (C#)
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Project initialization and basic structure
- [ ] T001 Create Python project structure: src/api/ with subdirs (models/, schemas/, routers/, services/, clients/, middleware/, websocket/, utils/, migrations/)
- [ ] T002 Create C# SDK Bridge structure: src/sdk-bridge/ with GeViScopeBridge.sln, Services/, SDK/, Protos/
- [ ] T003 Create test structure: tests/api/ (unit/, integration/, contract/) and tests/sdk-bridge/ (Unit/, Integration/)
- [ ] T004 [P] Initialize Python dependencies in requirements.txt (FastAPI, Uvicorn, SQLAlchemy, Redis, grpcio, PyJWT, pytest)
- [ ] T005 [P] Initialize C# project with .NET 8.0 gRPC and .NET Framework 4.8 SDK dependencies
- [ ] T006 [P] Configure Python linting/formatting (ruff, black, mypy) in pyproject.toml
- [ ] T007 [P] Create .env.example with all required environment variables
- [ ] T008 [P] Create scripts/setup_dev_environment.ps1 for automated development environment setup
- [ ] T009 [P] Create scripts/start_services.ps1 to start Redis, SDK Bridge, and API
- [ ] T010 [P] Setup Alembic for database migrations in src/api/migrations/
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
### C# SDK Bridge Foundation
- [ ] T011 Define gRPC protocol buffer for common types in src/sdk-bridge/Protos/common.proto (Status, Error, Timestamp)
- [ ] T012 Create GeViDatabaseWrapper.cs in src/sdk-bridge/SDK/ (wraps GeViDatabase connection lifecycle)
- [ ] T013 Implement connection management: Create → RegisterCallback → Connect pattern with retry logic
- [ ] T014 [P] Create StateQueryHandler.cs for GetFirst/GetNext enumeration pattern
- [ ] T015 [P] Create DatabaseQueryHandler.cs for historical query sessions
- [ ] T016 Implement error translation from Windows error codes to gRPC status codes in src/sdk-bridge/Utils/ErrorTranslator.cs
- [ ] T017 Setup gRPC server in src/sdk-bridge/Program.cs with service registration
### Python API Foundation
- [ ] T018 Create FastAPI app initialization in src/api/main.py with CORS, middleware registration
- [ ] T019 [P] Create configuration management in src/api/config.py loading from environment variables
- [ ] T020 [P] Setup PostgreSQL connection with SQLAlchemy in src/api/models/__init__.py
- [ ] T021 [P] Setup Redis client with connection pooling in src/api/clients/redis_client.py
- [ ] T022 Create gRPC SDK Bridge client in src/api/clients/sdk_bridge_client.py with connection pooling
- [ ] T023 [P] Implement JWT utilities in src/api/utils/jwt_utils.py (encode, decode, verify)
- [ ] T024 [P] Create error translation utilities in src/api/utils/error_translation.py (SDK errors → HTTP status)
- [ ] T025 Implement global error handler middleware in src/api/middleware/error_handler.py
- [ ] T026 [P] Create base Pydantic schemas in src/api/schemas/__init__.py (ErrorResponse, SuccessResponse)
### Database & Testing Infrastructure
- [ ] T027 Create initial Alembic migration for database schema (users, audit_logs tables)
- [ ] T028 [P] Setup pytest configuration in tests/api/conftest.py with fixtures (test_db, test_redis, test_client)
- [ ] T029 [P] Setup xUnit test infrastructure in tests/sdk-bridge/ with test SDK connection
**Checkpoint**: Foundation ready - user story implementation can now begin in parallel
---
## Phase 3: User Story 1 - Secure API Access (Priority: P1) 🎯 MVP
**Goal**: Implement JWT-based authentication with role-based access control (viewer, operator, administrator)
**Independent Test**: Can authenticate with valid credentials to receive JWT token, access protected endpoints with token, and receive 401 for invalid/expired tokens
### Tests for User Story 1 (TDD - Write FIRST, Ensure FAIL)
- [ ] T030 [P] [US1] Write contract test for POST /api/v1/auth/login in tests/api/contract/test_auth_contract.py (should FAIL)
- [ ] T031 [P] [US1] Write contract test for POST /api/v1/auth/refresh in tests/api/contract/test_auth_contract.py (should FAIL)
- [ ] T032 [P] [US1] Write contract test for POST /api/v1/auth/logout in tests/api/contract/test_auth_contract.py (should FAIL)
- [ ] T033 [P] [US1] Write integration test for authentication flow in tests/api/integration/test_auth_flow.py (should FAIL)
- [ ] T034 [P] [US1] Write unit test for AuthService in tests/api/unit/test_auth_service.py (should FAIL)
### Implementation for User Story 1
- [ ] T035 [P] [US1] Create User model in src/api/models/user.py (id, username, password_hash, role, permissions, created_at, updated_at)
- [ ] T036 [P] [US1] Create AuditLog model in src/api/models/audit_log.py (id, user_id, action, target, outcome, timestamp, details)
- [ ] T037 [US1] Create Alembic migration for User and AuditLog tables
- [ ] T038 [P] [US1] Create auth request/response schemas in src/api/schemas/auth.py (LoginRequest, TokenResponse, RefreshRequest)
- [ ] T039 [US1] Implement AuthService in src/api/services/auth_service.py (login, refresh, logout, validate_token)
- [ ] T040 [US1] Implement password hashing with bcrypt in AuthService
- [ ] T041 [US1] Implement JWT token generation (access: 1hr, refresh: 7 days) with Redis session storage
- [ ] T042 [US1] Implement authentication middleware in src/api/middleware/auth_middleware.py (verify JWT, extract user)
- [ ] T043 [US1] Implement rate limiting middleware for auth endpoints in src/api/middleware/rate_limiter.py (5 attempts/min)
- [ ] T044 [US1] Create auth router in src/api/routers/auth.py with login, refresh, logout endpoints
- [ ] T045 [US1] Implement audit logging for authentication attempts (success and failures)
- [ ] T046 [US1] Add role-based permission checking utilities in src/api/utils/permissions.py
**Verify**: Run tests T030-T034 - they should now PASS
**Checkpoint**: Authentication system complete - can login, get tokens, access protected endpoints
---
## Phase 4: User Story 2 - Live Video Stream Access (Priority: P1)
**Goal**: Enable users to view live video streams from surveillance cameras with <2s initialization time
**Independent Test**: Authenticate, request stream URL for camera, receive RTSP URL with token, play stream in video player
### gRPC Protocol Definitions
- [ ] T047 [US2] Define camera.proto in src/sdk-bridge/Protos/ (ListCamerasRequest/Response, GetCameraRequest/Response, CameraInfo)
- [ ] T048 [US2] Define stream.proto in src/sdk-bridge/Protos/ (StartStreamRequest/Response, StopStreamRequest/Response, StreamInfo)
### Tests for User Story 2 (TDD - Write FIRST, Ensure FAIL)
- [ ] T049 [P] [US2] Write contract test for GET /api/v1/cameras in tests/api/contract/test_cameras_contract.py (should FAIL)
- [ ] T050 [P] [US2] Write contract test for GET /api/v1/cameras/{id} in tests/api/contract/test_cameras_contract.py (should FAIL)
- [ ] T051 [P] [US2] Write contract test for POST /api/v1/cameras/{id}/stream in tests/api/contract/test_cameras_contract.py (should FAIL)
- [ ] T052 [P] [US2] Write contract test for DELETE /api/v1/cameras/{id}/stream/{stream_id} in tests/api/contract/test_cameras_contract.py (should FAIL)
- [ ] T053 [P] [US2] Write integration test for stream lifecycle in tests/api/integration/test_stream_lifecycle.py (should FAIL)
- [ ] T054 [P] [US2] Write unit test for CameraService in tests/api/unit/test_camera_service.py (should FAIL)
- [ ] T055 [P] [US2] Write C# unit test for CameraService gRPC in tests/sdk-bridge/Unit/CameraServiceTests.cs (should FAIL)
### Implementation - SDK Bridge (C#)
- [ ] T056 [US2] Implement CameraService.cs in src/sdk-bridge/Services/ with ListCameras (GetFirstVideoInput/GetNextVideoInput pattern)
- [ ] T057 [US2] Implement GetCameraDetails in CameraService.cs (query video input info: channel, name, capabilities)
- [ ] T058 [US2] Implement GetCameraStatus in CameraService.cs (online/offline detection)
- [ ] T059 [US2] Implement StreamService.cs in src/sdk-bridge/Services/ with StartStream method
- [ ] T060 [US2] Generate RTSP URL with token in StreamService.cs (format: rtsp://host:port/stream/{id}?token={jwt})
- [ ] T061 [US2] Implement StopStream method in StreamService.cs
- [ ] T062 [US2] Track active streams with channel mapping in StreamService.cs
### Implementation - Python API
- [ ] T063 [P] [US2] Create Camera model in src/api/models/camera.py (id, channel, name, description, status, capabilities)
- [ ] T064 [P] [US2] Create Stream model in src/api/models/stream.py (id, camera_id, user_id, url, started_at, expires_at)
- [ ] T065 [US2] Create Alembic migration for Camera and Stream tables
- [ ] T066 [P] [US2] Create camera schemas in src/api/schemas/camera.py (CameraInfo, CameraList, CameraCapabilities)
- [ ] T067 [P] [US2] Create stream schemas in src/api/schemas/stream.py (StartStreamRequest, StreamResponse)
- [ ] T068 [US2] Implement CameraService in src/api/services/camera_service.py (list, get_details, sync from SDK bridge)
- [ ] T069 [US2] Implement StreamService in src/api/services/stream_service.py (start, stop, track active streams)
- [ ] T070 [US2] Implement token generation for stream URLs (15min expiration)
- [ ] T071 [US2] Create cameras router in src/api/routers/cameras.py with GET /cameras, GET /cameras/{id}
- [ ] T072 [US2] Implement stream endpoints: POST /cameras/{id}/stream, DELETE /cameras/{id}/stream/{stream_id}
- [ ] T073 [US2] Add permission checks: users can only access cameras they have permission for (403 if unauthorized)
- [ ] T074 [US2] Implement camera offline error handling (clear error message when camera unavailable)
**Verify**: Run tests T049-T055 - they should now PASS
**Checkpoint**: Live streaming functional - can list cameras, start/stop streams, play video
---
## Phase 5: User Story 3 - Camera PTZ Control (Priority: P1)
**Goal**: Enable remote pan-tilt-zoom control for PTZ-capable cameras with <500ms response time
**Independent Test**: Send PTZ command (pan left/right, tilt up/down, zoom in/out) to PTZ camera, verify movement occurs
### gRPC Protocol Definitions
- [ ] T075 [US3] Define ptz.proto in src/sdk-bridge/Protos/ (PTZMoveRequest, PTZPresetRequest, PTZResponse)
### Tests for User Story 3 (TDD - Write FIRST, Ensure FAIL)
- [ ] T076 [P] [US3] Write contract test for POST /api/v1/cameras/{id}/ptz in tests/api/contract/test_ptz_contract.py (should FAIL)
- [ ] T077 [P] [US3] Write integration test for PTZ control in tests/api/integration/test_ptz_control.py (should FAIL)
- [ ] T078 [P] [US3] Write unit test for PTZService in tests/api/unit/test_ptz_service.py (should FAIL)
- [ ] T079 [P] [US3] Write C# unit test for PTZService gRPC in tests/sdk-bridge/Unit/PTZServiceTests.cs (should FAIL)
### Implementation - SDK Bridge (C#)
- [ ] T080 [US3] Implement PTZService.cs in src/sdk-bridge/Services/ with MoveCamera method (pan, tilt, zoom, speed)
- [ ] T081 [US3] Implement SetPreset and GotoPreset methods in PTZService.cs
- [ ] T082 [US3] Implement StopMovement method in PTZService.cs
- [ ] T083 [US3] Add PTZ command queuing for concurrent control conflict resolution
### Implementation - Python API
- [ ] T084 [P] [US3] Create PTZ schemas in src/api/schemas/ptz.py (PTZMoveCommand, PTZPresetCommand, PTZResponse)
- [ ] T085 [US3] Implement PTZService in src/api/services/ptz_service.py (move, set_preset, goto_preset, stop)
- [ ] T086 [US3] Add PTZ endpoints to cameras router: POST /cameras/{id}/ptz
- [ ] T087 [US3] Implement PTZ capability validation (return error if camera doesn't support PTZ)
- [ ] T088 [US3] Implement operator role requirement for PTZ control (viewers can't control PTZ)
- [ ] T089 [US3] Add audit logging for all PTZ commands
**Verify**: Run tests T076-T079 - they should now PASS
**Checkpoint**: PTZ control functional - can move cameras, use presets, operators have control
---
## Phase 6: User Story 4 - Real-time Event Notifications (Priority: P1)
**Goal**: Deliver real-time surveillance event notifications via WebSocket with <100ms latency to 1000+ concurrent clients
**Independent Test**: Connect to WebSocket, subscribe to event types, trigger test alarm, receive notification within 100ms
### gRPC Protocol Definitions
- [ ] T090 [US4] Define event.proto in src/sdk-bridge/Protos/ (SubscribeEventsRequest, EventNotification with server streaming)
### Tests for User Story 4 (TDD - Write FIRST, Ensure FAIL)
- [ ] T091 [P] [US4] Write contract test for WebSocket /api/v1/events/stream in tests/api/contract/test_events_contract.py (should FAIL)
- [ ] T092 [P] [US4] Write contract test for GET /api/v1/events in tests/api/contract/test_events_contract.py (should FAIL)
- [ ] T093 [P] [US4] Write integration test for event notification flow in tests/api/integration/test_event_notifications.py (should FAIL)
- [ ] T094 [P] [US4] Write unit test for EventService in tests/api/unit/test_event_service.py (should FAIL)
- [ ] T095 [P] [US4] Write C# unit test for EventService gRPC in tests/sdk-bridge/Unit/EventServiceTests.cs (should FAIL)
### Implementation - SDK Bridge (C#)
- [ ] T096 [US4] Implement EventService.cs in src/sdk-bridge/Services/ with SubscribeEvents (server streaming)
- [ ] T097 [US4] Register SDK event callbacks for motion, alarms, analytics, system events
- [ ] T098 [US4] Map SDK events to gRPC EventNotification messages
- [ ] T099 [US4] Implement event filtering by type and camera channel
### Implementation - Python API
- [ ] T100 [P] [US4] Create Event model in src/api/models/event.py (id, type, camera_id, timestamp, severity, data)
- [ ] T101 [US4] Create Alembic migration for Event table
- [ ] T102 [P] [US4] Create event schemas in src/api/schemas/event.py (EventNotification, EventQuery, EventFilter)
- [ ] T103 [US4] Implement WebSocket connection manager in src/api/websocket/connection_manager.py (add, remove, broadcast)
- [ ] T104 [US4] Implement Redis pub/sub event broadcaster in src/api/websocket/event_broadcaster.py (subscribe to SDK bridge events)
- [ ] T105 [US4] Create background task to consume SDK bridge event stream and publish to Redis
- [ ] T106 [US4] Implement WebSocket endpoint in src/api/routers/events.py: WS /events/stream
- [ ] T107 [US4] Implement event subscription management (subscribe, unsubscribe to event types)
- [ ] T108 [US4] Implement client reconnection handling with missed event recovery
- [ ] T109 [US4] Implement EventService in src/api/services/event_service.py (query historical events)
- [ ] T110 [US4] Create REST endpoint: GET /events (query with filters: camera, type, time range)
- [ ] T111 [US4] Implement permission filtering (users only receive events for authorized cameras)
**Verify**: Run tests T091-T095 - they should now PASS
**Checkpoint**: Event notifications working - WebSocket delivers real-time alerts, query historical events
---
## Phase 7: User Story 5 - Recording Management (Priority: P2)
**Goal**: Manage video recording settings and query recorded footage for investigations
**Independent Test**: Start recording on camera, query recordings by time range, receive list with download URLs
### gRPC Protocol Definitions
- [ ] T112 [US5] Define recording.proto in src/sdk-bridge/Protos/ (QueryRecordingsRequest, StartRecordingRequest, RecordingInfo)
### Tests for User Story 5 (TDD - Write FIRST, Ensure FAIL)
- [ ] T113 [P] [US5] Write contract test for GET /api/v1/recordings in tests/api/contract/test_recordings_contract.py (should FAIL)
- [ ] T114 [P] [US5] Write contract test for POST /api/v1/recordings/{id}/export in tests/api/contract/test_recordings_contract.py (should FAIL)
- [ ] T115 [P] [US5] Write integration test for recording management in tests/api/integration/test_recording_management.py (should FAIL)
- [ ] T116 [P] [US5] Write unit test for RecordingService in tests/api/unit/test_recording_service.py (should FAIL)
- [ ] T117 [P] [US5] Write C# unit test for RecordingService gRPC in tests/sdk-bridge/Unit/RecordingServiceTests.cs (should FAIL)
### Implementation - SDK Bridge (C#)
- [ ] T118 [US5] Implement RecordingService.cs in src/sdk-bridge/Services/ with QueryRecordings (database query with time range)
- [ ] T119 [US5] Implement StartRecording and StopRecording methods
- [ ] T120 [US5] Implement GetRecordingCapacity method (ring buffer metrics)
- [ ] T121 [US5] Query recording segments using CDBQCreateActionQuery pattern
### Implementation - Python API
- [ ] T122 [P] [US5] Create Recording model in src/api/models/recording.py (id, camera_id, start_time, end_time, size_bytes, trigger_type)
- [ ] T123 [US5] Create Alembic migration for Recording table
- [ ] T124 [P] [US5] Create recording schemas in src/api/schemas/recording.py (RecordingQuery, RecordingInfo, ExportRequest)
- [ ] T125 [US5] Implement RecordingService in src/api/services/recording_service.py (query, start, stop, export)
- [ ] T126 [US5] Create recordings router in src/api/routers/recordings.py: GET /recordings, POST /recordings/{id}/export
- [ ] T127 [US5] Implement recording query with filters (camera, time range, event type)
- [ ] T128 [US5] Implement export job creation (async job with progress tracking)
- [ ] T129 [US5] Implement ring buffer capacity monitoring and warnings (alert at 90%)
- [ ] T130 [US5] Add administrator role requirement for starting/stopping recording
**Verify**: Run tests T113-T117 - they should now PASS
**Checkpoint**: Recording management functional - query, export, capacity monitoring
---
## Phase 8: User Story 6 - Video Analytics Configuration (Priority: P2)
**Goal**: Configure video content analysis features (VMD, object tracking, perimeter protection)
**Independent Test**: Configure motion detection zone on camera, trigger motion, verify analytics event generated
### gRPC Protocol Definitions
- [ ] T131 [US6] Define analytics.proto in src/sdk-bridge/Protos/ (ConfigureAnalyticsRequest, AnalyticsConfig with union types for VMD/NPR/OBTRACK/G-Tect)
### Tests for User Story 6 (TDD - Write FIRST, Ensure FAIL)
- [ ] T132 [P] [US6] Write contract test for GET /api/v1/analytics/{camera_id} in tests/api/contract/test_analytics_contract.py (should FAIL)
- [ ] T133 [P] [US6] Write contract test for POST /api/v1/analytics/{camera_id} in tests/api/contract/test_analytics_contract.py (should FAIL)
- [ ] T134 [P] [US6] Write integration test for analytics configuration in tests/api/integration/test_analytics_config.py (should FAIL)
- [ ] T135 [P] [US6] Write unit test for AnalyticsService in tests/api/unit/test_analytics_service.py (should FAIL)
- [ ] T136 [P] [US6] Write C# unit test for AnalyticsService gRPC in tests/sdk-bridge/Unit/AnalyticsServiceTests.cs (should FAIL)
### Implementation - SDK Bridge (C#)
- [ ] T137 [US6] Implement AnalyticsService.cs in src/sdk-bridge/Services/ with ConfigureAnalytics method
- [ ] T138 [US6] Implement GetAnalyticsConfig method (query current analytics settings)
- [ ] T139 [US6] Map analytics types to SDK sensor types (VMD, NPR, OBTRACK, G-Tect, CPA)
- [ ] T140 [US6] Implement region/zone configuration for analytics
### Implementation - Python API
- [ ] T141 [P] [US6] Create AnalyticsConfig model in src/api/models/analytics_config.py (id, camera_id, type, enabled, configuration JSON)
- [ ] T142 [US6] Create Alembic migration for AnalyticsConfig table
- [ ] T143 [P] [US6] Create analytics schemas in src/api/schemas/analytics.py (AnalyticsConfigRequest, VMDConfig, NPRConfig, OBTRACKConfig)
- [ ] T144 [US6] Implement AnalyticsService in src/api/services/analytics_service.py (configure, get_config, validate)
- [ ] T145 [US6] Create analytics router in src/api/routers/analytics.py: GET/POST /analytics/{camera_id}
- [ ] T146 [US6] Implement analytics capability validation (return error if camera doesn't support requested analytics)
- [ ] T147 [US6] Add administrator role requirement for analytics configuration
- [ ] T148 [US6] Implement schedule support for analytics (enable/disable by time/day)
**Verify**: Run tests T132-T136 - they should now PASS
**Checkpoint**: Analytics configuration functional - configure VMD, NPR, OBTRACK, receive analytics events
---
## Phase 9: User Story 7 - Multi-Camera Management (Priority: P2)
**Goal**: View and manage multiple cameras simultaneously with location grouping
**Independent Test**: Request camera list, verify all authorized cameras returned with metadata, group by location
### Tests for User Story 7 (TDD - Write FIRST, Ensure FAIL)
- [ ] T149 [P] [US7] Write contract test for camera list with filtering/pagination in tests/api/contract/test_camera_list_contract.py (should FAIL)
- [ ] T150 [P] [US7] Write integration test for multi-camera operations in tests/api/integration/test_multi_camera.py (should FAIL)
### Implementation
- [ ] T151 [P] [US7] Add location field to Camera model (update migration)
- [ ] T152 [US7] Implement camera list filtering by location, status, capabilities in CameraService
- [ ] T153 [US7] Implement pagination for camera list (page, page_size parameters)
- [ ] T154 [US7] Update GET /cameras endpoint with query parameters (location, status, capabilities, page, page_size)
- [ ] T155 [US7] Implement camera grouping by location in response
- [ ] T156 [US7] Implement concurrent stream limit tracking (warn if approaching limit)
- [ ] T157 [US7] Add camera status change notifications via WebSocket (camera goes offline event)
**Verify**: Run tests T149-T150 - they should now PASS
**Checkpoint**: Multi-camera management functional - filtering, grouping, concurrent access
---
## Phase 10: User Story 8 - License Plate Recognition Integration (Priority: P3)
**Goal**: Receive automatic license plate recognition events with watchlist matching
**Independent Test**: Configure NPR zone, drive test vehicle through zone, receive NPR event with plate number
### Tests for User Story 8 (TDD - Write FIRST, Ensure FAIL)
- [ ] T158 [P] [US8] Write integration test for NPR events in tests/api/integration/test_npr_events.py (should FAIL)
- [ ] T159 [P] [US8] Write unit test for NPR watchlist matching in tests/api/unit/test_npr_service.py (should FAIL)
### Implementation
- [ ] T160 [P] [US8] Create NPREvent model extending Event in src/api/models/event.py (plate_number, country_code, confidence, image_url)
- [ ] T161 [US8] Create Alembic migration for NPREvent table
- [ ] T162 [P] [US8] Create Watchlist model in src/api/models/watchlist.py (id, plate_number, alert_level, notes)
- [ ] T163 [US8] Create Alembic migration for Watchlist table
- [ ] T164 [P] [US8] Create NPR schemas in src/api/schemas/npr.py (NPREventData, WatchlistEntry)
- [ ] T165 [US8] Implement NPR event handling in EventService (parse NPR data from SDK)
- [ ] T166 [US8] Implement watchlist matching service (check incoming plates against watchlist)
- [ ] T167 [US8] Implement high-priority alerts for watchlist matches
- [ ] T168 [US8] Add NPR-specific filtering to GET /events endpoint
- [ ] T169 [US8] Create watchlist management endpoints: GET/POST/DELETE /api/v1/watchlist
**Verify**: Run tests T158-T159 - they should now PASS
**Checkpoint**: NPR integration functional - receive plate events, watchlist matching, alerts
---
## Phase 11: User Story 9 - Video Export and Backup (Priority: P3)
**Goal**: Export specific video segments for evidence with progress tracking
**Independent Test**: Request export of 10-minute segment, poll job status, download exported file
### Tests for User Story 9 (TDD - Write FIRST, Ensure FAIL)
- [ ] T170 [P] [US9] Write contract test for export job in tests/api/contract/test_export_contract.py (should FAIL)
- [ ] T171 [P] [US9] Write integration test for export workflow in tests/api/integration/test_export_workflow.py (should FAIL)
- [ ] T172 [P] [US9] Write unit test for ExportService in tests/api/unit/test_export_service.py (should FAIL)
### Implementation
- [ ] T173 [P] [US9] Create ExportJob model in src/api/models/export_job.py (id, camera_id, start_time, end_time, status, progress, file_path)
- [ ] T174 [US9] Create Alembic migration for ExportJob table
- [ ] T175 [P] [US9] Create export schemas in src/api/schemas/export.py (ExportRequest, ExportJobStatus)
- [ ] T176 [US9] Implement ExportService in src/api/services/export_service.py (create_job, get_status, download)
- [ ] T177 [US9] Implement background worker for export processing (query recordings, concatenate, encode to MP4)
- [ ] T178 [US9] Implement progress tracking and updates (percentage complete, ETA)
- [ ] T179 [US9] Update POST /recordings/{id}/export to create export job and return job ID
- [ ] T180 [US9] Create GET /api/v1/exports/{job_id} endpoint for job status polling
- [ ] T181 [US9] Create GET /api/v1/exports/{job_id}/download endpoint for file download
- [ ] T182 [US9] Implement cleanup of old export files (auto-delete after 24 hours)
- [ ] T183 [US9] Add timestamp watermarking to exported video
**Verify**: Run tests T170-T172 - they should now PASS
**Checkpoint**: Video export functional - create jobs, track progress, download files
---
## Phase 12: User Story 10 - System Health Monitoring (Priority: P3)
**Goal**: Monitor API and surveillance system health with proactive alerts
**Independent Test**: Query health endpoint, verify SDK connectivity status, simulate component failure
### Tests for User Story 10 (TDD - Write FIRST, Ensure FAIL)
- [ ] T184 [P] [US10] Write contract test for GET /api/v1/health in tests/api/contract/test_health_contract.py (should FAIL)
- [ ] T185 [P] [US10] Write contract test for GET /api/v1/status in tests/api/contract/test_health_contract.py (should FAIL)
- [ ] T186 [P] [US10] Write integration test for health monitoring in tests/api/integration/test_health_monitoring.py (should FAIL)
### Implementation
- [ ] T187 [P] [US10] Create health schemas in src/api/schemas/health.py (HealthResponse, SystemStatus, ComponentHealth)
- [ ] T188 [US10] Implement HealthService in src/api/services/health_service.py (check all components)
- [ ] T189 [US10] Implement SDK Bridge health check (gRPC connectivity test)
- [ ] T190 [US10] Implement Redis health check (ping test)
- [ ] T191 [US10] Implement PostgreSQL health check (simple query)
- [ ] T192 [US10] Implement disk space check for recordings (warn if <10%)
- [ ] T193 [US10] Create system router in src/api/routers/system.py: GET /health, GET /status
- [ ] T194 [US10] Implement GET /health endpoint (public, returns basic status)
- [ ] T195 [US10] Implement GET /status endpoint (authenticated, returns detailed metrics)
- [ ] T196 [US10] Add Prometheus metrics endpoint at /metrics (request count, latency, errors, active streams, WebSocket connections)
- [ ] T197 [US10] Implement background health monitoring task (check every 30s, alert on failures)
**Verify**: Run tests T184-T186 - they should now PASS
**Checkpoint**: Health monitoring functional - status endpoints, metrics, component checks
---
## 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
- [ ] T198 [P] Add comprehensive API documentation to all endpoints (docstrings, parameter descriptions)
- [ ] T199 [P] Create architecture diagram in docs/architecture.md with component interaction flows
- [ ] T200 [P] Create SDK integration guide in docs/sdk-integration.md with connection patterns
- [ ] T201 [P] Create deployment guide in docs/deployment.md (Windows Server, Docker, environment setup)
- [ ] T202 [P] Add OpenAPI specification auto-generation from code annotations
- [ ] T203 [P] Implement request/response logging with correlation IDs for debugging
- [ ] T204 [P] Add performance profiling endpoints (debug mode only)
- [ ] T205 [P] Create load testing scripts for concurrent streams and WebSocket connections
- [ ] T206 [P] Implement graceful shutdown handling (close connections, flush logs)
- [ ] T207 [P] Add TLS/HTTPS configuration guide and certificate management
- [ ] T208 [P] Security hardening: Remove stack traces from production errors, sanitize logs
- [ ] T209 [P] Add database connection pooling optimization
- [ ] T210 [P] Implement API response caching for camera lists (Redis cache, 60s TTL)
- [ ] T211 [P] Create GitHub Actions CI/CD pipeline (run tests, build Docker images)
- [ ] T212 [P] Add code coverage reporting (target 80% minimum)
- [ ] T213 Validate quickstart.md by following guide end-to-end
- [ ] T214 Create README.md with project overview, links to documentation
- [ ] T215 Final security audit: Check for OWASP top 10 vulnerabilities
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies - can start immediately
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
- **User Stories (Phase 3-12)**: All depend on Foundational phase completion
- User Story 1 (P1): Authentication - NO dependencies on other stories
- User Story 2 (P1): Live Streaming - Requires User Story 1 (auth for protected endpoints)
- User Story 3 (P1): PTZ Control - Requires User Story 1 (auth) and User Story 2 (camera service exists)
- User Story 4 (P1): Event Notifications - Requires User Story 1 (auth), User Story 2 (camera service)
- User Story 5 (P2): Recording Management - Requires User Story 1 (auth), User Story 2 (camera service)
- User Story 6 (P2): Analytics Config - Requires User Story 1 (auth), User Story 2 (camera service), User Story 4 (events)
- User Story 7 (P2): Multi-Camera - Extends User Story 2 (camera service)
- User Story 8 (P3): NPR Integration - Requires User Story 4 (events), User Story 6 (analytics)
- User Story 9 (P3): Video Export - Requires User Story 5 (recording management)
- User Story 10 (P3): Health Monitoring - Can start after Foundational, but best after all services exist
- **Polish (Phase 13)**: Depends on all desired user stories being complete
### Critical Path (Sequential)
```
Phase 1: Setup
Phase 2: Foundational (BLOCKS all user stories)
Phase 3: User Story 1 - Authentication (BLOCKS all protected endpoints)
Phase 4: User Story 2 - Live Streaming (BLOCKS camera-dependent features)
Phase 5: User Story 3 - PTZ Control
Phase 6: User Story 4 - Event Notifications (BLOCKS analytics)
[Phase 7-12 can proceed in parallel after their dependencies are met]
Phase 13: Polish
```
### User Story Dependencies
- **US1 (Authentication)**: No dependencies - can start after Foundational
- **US2 (Live Streaming)**: Depends on US1 completion
- **US3 (PTZ Control)**: Depends on US1, US2 completion
- **US4 (Event Notifications)**: Depends on US1, US2 completion
- **US5 (Recording Management)**: Depends on US1, US2 completion
- **US6 (Analytics Config)**: Depends on US1, US2, US4 completion
- **US7 (Multi-Camera)**: Depends on US2 completion
- **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
**Within Phases**:
- Phase 1 (Setup): T004-T010 can run in parallel (all marked [P])
- Phase 2 (Foundational): T014-T015, T019-T021, T023-T024, T028-T029 can run in parallel
**Within User Stories**:
- US1 Tests: T030-T034 can run in parallel
- US1 Models: T035-T036 can run in parallel
- US1 Schemas: T038 independent
- US2 Tests: T049-T055 can run in parallel
- US2 Models: T063-T064 can run in parallel
- US2 Schemas: T066-T067 can run in parallel
- [Similar pattern for all user stories]
**Across User Stories** (if team capacity allows):
- 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
- US12 COMPLETED (Configuration Management)
**Polish Phase**: T198-T212, T214-T215 all marked [P] can run in parallel
---
## Parallel Example: User Story 2 (Live Streaming)
```bash
# Step 1: Write all tests in parallel (TDD - ensure they FAIL)
Task T049: Contract test for GET /cameras
Task T050: Contract test for GET /cameras/{id}
Task T051: Contract test for POST /cameras/{id}/stream
Task T052: Contract test for DELETE /cameras/{id}/stream/{stream_id}
Task T053: Integration test for stream lifecycle
Task T054: Unit test for CameraService (Python)
Task T055: Unit test for CameraService (C#)
# Step 2: Create models in parallel
Task T063: Camera model
Task T064: Stream model
# Step 3: Create schemas in parallel
Task T066: Camera schemas
Task T067: Stream schemas
# Step 4: Implement services sequentially (dependency on models)
Task T068: CameraService (depends on T063, T064)
Task T069: StreamService (depends on T068)
# Step 5: Implement SDK Bridge sequentially
Task T056: CameraService.cs (depends on gRPC proto T047)
Task T059: StreamService.cs (depends on gRPC proto T048)
# Step 6: Implement routers sequentially (depends on services)
Task T071: Cameras router
Task T072: Stream endpoints
# Verify: Run tests T049-T055 - they should now PASS
```
---
## Implementation Strategy
### MVP First (User Stories 1-4 Only)
**Rationale**: US1-US4 are all P1 and deliver core surveillance functionality
1. Complete Phase 1: Setup
2. Complete Phase 2: Foundational (CRITICAL - blocks all stories)
3. Complete Phase 3: User Story 1 (Authentication) - STOP and TEST
4. Complete Phase 4: User Story 2 (Live Streaming) - STOP and TEST
5. Complete Phase 5: User Story 3 (PTZ Control) - STOP and TEST
6. Complete Phase 6: User Story 4 (Event Notifications) - STOP and TEST
7. **STOP and VALIDATE**: Test all P1 stories together as integrated MVP
8. Deploy/demo MVP
**MVP Delivers**:
- Secure authentication with RBAC
- Live video streaming from cameras
- PTZ camera control
- Real-time event notifications
**Not in MVP** (can add incrementally):
- Recording management (US5)
- Analytics configuration (US6)
- Multi-camera enhancements (US7)
- NPR integration (US8)
- Video export (US9)
- Health monitoring (US10)
### Incremental Delivery (After MVP)
1. **MVP** (US1-4) Deploy Validate
2. **+Recording** (US5) Deploy Validate
3. **+Analytics** (US6) Deploy Validate
4. **+Multi-Camera** (US7) Deploy Validate
5. **+NPR** (US8) Deploy Validate
6. **+Export** (US9) Deploy Validate
7. **+Health** (US10) Deploy Validate
8. **+Polish** (Phase 13) Final Release
Each increment adds value without breaking previous functionality.
### Parallel Team Strategy
With 3 developers after Foundational phase completes:
**Week 1-2**: All work on US1 together (foundational for everything)
**Week 3-4**:
- Developer A: US2 (Live Streaming)
- Developer B: Start US4 (Events - can partially proceed)
- Developer C: Setup/tooling improvements
**Week 5-6**:
- Developer A: US3 (PTZ - depends on US2)
- Developer B: Complete US4 (Events)
- Developer C: US5 (Recording)
**Week 7+**:
- Developer A: US6 (Analytics)
- Developer B: US7 (Multi-Camera)
- Developer C: US9 (Export)
---
## Task Summary
**Total Tasks**: 215
**By Phase**:
- Phase 1 (Setup): 10 tasks
- Phase 2 (Foundational): 19 tasks
- Phase 3 (US1 - Authentication): 17 tasks
- Phase 4 (US2 - Live Streaming): 29 tasks
- Phase 5 (US3 - PTZ Control): 15 tasks
- Phase 6 (US4 - Event Notifications): 22 tasks
- Phase 7 (US5 - Recording Management): 19 tasks
- Phase 8 (US6 - Analytics Config): 18 tasks
- Phase 9 (US7 - Multi-Camera): 9 tasks
- Phase 10 (US8 - NPR Integration): 12 tasks
- Phase 11 (US9 - Video Export): 14 tasks
- Phase 12 (US10 - Health Monitoring): 14 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)
**Parallel Tasks**: 100+ tasks marked [P]
**Estimated Timeline**:
- MVP (US1-4): 8-10 weeks (1 developer) or 4-6 weeks (3 developers)
- Full Feature Set (US1-10 + Polish): 16-20 weeks (1 developer) or 8-12 weeks (3 developers)
---
## Notes
- **[P] tasks**: Different files, no dependencies - safe to parallelize
- **[Story] labels**: Maps task to specific user story for traceability
- **TDD enforced**: All test tasks MUST be written first and FAIL before implementation
- **Independent stories**: Each user story should be independently completable and testable
- **Commit frequently**: After each task or logical group
- **Stop at checkpoints**: Validate each story independently before proceeding
- **MVP focus**: Complete US1-4 first for deployable surveillance system
- **Avoid**: Vague tasks, same-file conflicts, cross-story dependencies that break independence
---
**Generated**: 2025-12-08
**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)