Completed Tasks (T001-T010): - ✅ Project structure created (src/, tests/, docs/, scripts/) - ✅ Python dependencies defined (requirements.txt) - ✅ C# SDK Bridge project initialized (.csproj) - ✅ Configuration template (.env.example) - ✅ Database migration config (alembic.ini) - ✅ Code quality tools (pyproject.toml with ruff, black, mypy) - ✅ Development setup script (setup_dev_environment.ps1) - ✅ Service startup script (start_services.ps1) - ✅ Architecture documentation (docs/architecture.md) - ✅ Revised MVP tasks (tasks-revised-mvp.md - 84 tasks focused on cross-switching) MVP Scope Refined: - Focus: Cross-switching control for GSCView viewers - NO recordings, NO analytics, NO LPR in MVP - REST API only, no UI needed - Phase 2: GeViSet configuration management Ready for Phase 2: SDK Bridge Foundation 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
16 KiB
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)
- Setup → SDK Bridge → Python API → Authentication
- Then parallel: Camera Discovery + Monitor Discovery + Cross-Switching
- Then: Polish & Documentation
- 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
- Write contract test (should FAIL)
- Write unit tests (should FAIL)
- Implement feature
- Run tests (should PASS)
- Refactor if needed
- 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 Scope: Cross-switching MVP with authentication, expandable to GeViSet configuration Architecture: Python FastAPI + C# gRPC Bridge + GeViScope SDK