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>
498 lines
13 KiB
Markdown
498 lines
13 KiB
Markdown
# Geutebruck Cross-Switching API - Architecture
|
|
|
|
**Version**: 1.0.0 (MVP)
|
|
**Last Updated**: 2025-12-08
|
|
**Status**: In Development
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The Geutebruck Cross-Switching API provides a modern REST API for controlling video routing between cameras (video inputs) and monitors/viewers (video outputs) in Geutebruck surveillance systems. The system acts as a bridge between the native GeViScope/GeViSoft SDK and modern web/mobile applications.
|
|
|
|
**Core Functionality**:
|
|
- 🔐 User authentication with JWT tokens
|
|
- 📹 Camera discovery and management
|
|
- 🖥️ Monitor/viewer discovery and status
|
|
- 🔀 Cross-switching operations (route camera to monitor)
|
|
- 📊 Routing state tracking and audit logging
|
|
|
|
---
|
|
|
|
## System Architecture
|
|
|
|
### High-Level Architecture
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ Client Apps │ (Postman, curl, custom apps)
|
|
└────────┬────────┘
|
|
│ HTTP/REST
|
|
▼
|
|
┌─────────────────┐
|
|
│ FastAPI Server │ (Python 3.11)
|
|
│ Port: 8000 │
|
|
└────────┬────────┘
|
|
│
|
|
┌────┴────┬───────────┬──────────┐
|
|
│ │ │ │
|
|
▼ ▼ ▼ ▼
|
|
┌────────┐ ┌────────┐ ┌────────┐ ┌─────────┐
|
|
│ PostgreSQL│ │ Redis │ │SDK Bridge│ │Auth/JWT │
|
|
│ Port:5432│ │Port:6379│ │Port:50051│ │ Service │
|
|
└─────────┘ └────────┘ └────┬───┘ └─────────┘
|
|
│ gRPC
|
|
▼
|
|
┌──────────────┐
|
|
│ GeViScope │
|
|
│ SDK (.NET) │
|
|
└──────┬───────┘
|
|
│ TCP/IP
|
|
▼
|
|
┌──────────────┐
|
|
│ GeViServer │
|
|
│ Port: 7700+ │
|
|
└──────┬───────┘
|
|
│
|
|
┌────────┴────────┐
|
|
▼ ▼
|
|
┌──────────┐ ┌──────────┐
|
|
│ Cameras │ │ GSCView │
|
|
│ (Inputs) │ │ Viewers │
|
|
└──────────┘ └──────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Component Details
|
|
|
|
### 1. FastAPI Server (Python)
|
|
|
|
**Purpose**: REST API layer handling HTTP requests, authentication, and business logic
|
|
|
|
**Technology Stack**:
|
|
- Python 3.11+
|
|
- FastAPI (web framework)
|
|
- SQLAlchemy (ORM)
|
|
- Pydantic (validation)
|
|
- PyJWT (authentication)
|
|
|
|
**Key Responsibilities**:
|
|
- Accept HTTP REST requests from clients
|
|
- Authenticate users and generate JWT tokens
|
|
- Validate request data
|
|
- Communicate with SDK Bridge via gRPC
|
|
- Store routing state in PostgreSQL
|
|
- Cache camera/monitor lists in Redis
|
|
- Audit log all operations
|
|
- Return HTTP responses to clients
|
|
|
|
**Port**: 8000
|
|
|
|
---
|
|
|
|
### 2. SDK Bridge (C# .NET 8.0)
|
|
|
|
**Purpose**: gRPC service that wraps the GeViScope SDK, translating between modern gRPC and legacy SDK
|
|
|
|
**Technology Stack**:
|
|
- C# .NET 8.0
|
|
- Grpc.AspNetCore
|
|
- GeViScope SDK (.NET Framework 4.8 DLL)
|
|
- Serilog (logging)
|
|
|
|
**Key Responsibilities**:
|
|
- Connect to GeViServer using GeViScope SDK
|
|
- Enumerate cameras (GetFirstVideoInput / GetNextVideoInput)
|
|
- Enumerate monitors (GetFirstVideoOutput / GetNextVideoOutput)
|
|
- Execute cross-switching (CrossSwitch action)
|
|
- Clear monitors (ClearVideoOutput action)
|
|
- Translate SDK errors to gRPC status codes
|
|
- Maintain connection health with retry logic
|
|
|
|
**Why Separate Service?**:
|
|
- ✅ Isolates SDK crashes from Python API
|
|
- ✅ Enables independent scaling
|
|
- ✅ Clear separation of concerns (SDK complexity vs API logic)
|
|
- ✅ Type-safe gRPC communication
|
|
- ✅ Can run on different machines if needed
|
|
|
|
**Port**: 50051 (gRPC)
|
|
|
|
---
|
|
|
|
### 3. PostgreSQL Database
|
|
|
|
**Purpose**: Persistent storage for users, routing state, and audit logs
|
|
|
|
**Schema**:
|
|
```sql
|
|
users:
|
|
- id (UUID, primary key)
|
|
- username (unique)
|
|
- password_hash (bcrypt)
|
|
- role (viewer, operator, administrator)
|
|
- created_at, updated_at
|
|
|
|
crossswitch_routes:
|
|
- id (UUID, primary key)
|
|
- camera_id (int)
|
|
- monitor_id (int)
|
|
- switched_at (timestamp)
|
|
- switched_by_user_id (UUID, FK to users)
|
|
|
|
audit_logs:
|
|
- id (UUID, primary key)
|
|
- user_id (UUID, FK to users)
|
|
- action (string)
|
|
- target (string)
|
|
- timestamp (timestamp)
|
|
- details (JSON)
|
|
```
|
|
|
|
**Port**: 5432
|
|
|
|
---
|
|
|
|
### 4. Redis
|
|
|
|
**Purpose**: Session storage, caching, and future pub/sub for events
|
|
|
|
**Usage**:
|
|
- **Session Storage**: JWT tokens and user sessions
|
|
- **Caching**: Camera list (60s TTL), monitor list (60s TTL)
|
|
- **Future**: Pub/sub for real-time routing updates
|
|
|
|
**Port**: 6379
|
|
|
|
---
|
|
|
|
### 5. GeViScope SDK & GeViServer
|
|
|
|
**GeViServer**:
|
|
- Backend service managing surveillance system
|
|
- Handles actual video routing
|
|
- Controls GSCView viewers
|
|
- Manages camera inputs and outputs
|
|
|
|
**GeViScope SDK**:
|
|
- .NET Framework 4.8 DLL (GeViProcAPINET_4_0.dll)
|
|
- Provides C# wrapper for GeViServer communication
|
|
- Uses action-based message passing
|
|
- State query pattern for enumeration
|
|
|
|
**Ports**: 7700, 7701, 7703
|
|
|
|
---
|
|
|
|
## Data Flow
|
|
|
|
### 1. Authentication Flow
|
|
|
|
```
|
|
Client → POST /api/v1/auth/login
|
|
{ username: "admin", password: "secret" }
|
|
↓
|
|
FastAPI validates credentials
|
|
↓
|
|
Hash password with bcrypt
|
|
↓
|
|
Query PostgreSQL for user
|
|
↓
|
|
Generate JWT token (1hr expiry)
|
|
↓
|
|
Store session in Redis
|
|
↓
|
|
Client ← { access_token: "eyJ...", token_type: "bearer" }
|
|
```
|
|
|
|
### 2. Camera Discovery Flow
|
|
|
|
```
|
|
Client → GET /api/v1/cameras
|
|
Header: Authorization: Bearer eyJ...
|
|
↓
|
|
FastAPI validates JWT
|
|
↓
|
|
Check Redis cache for camera list
|
|
↓ (cache miss)
|
|
gRPC call to SDK Bridge: ListCameras()
|
|
↓
|
|
SDK Bridge → GeViScope SDK
|
|
→ CSQGetFirstVideoInput()
|
|
→ CSQGetNextVideoInput() (loop)
|
|
↓
|
|
SDK Bridge ← Camera list
|
|
↓
|
|
FastAPI ← gRPC response
|
|
↓
|
|
Store in Redis (60s TTL)
|
|
↓
|
|
Client ← { cameras: [
|
|
{ id: 1, name: "Camera 1", has_ptz: false },
|
|
{ id: 2, name: "Front Gate", has_ptz: true }
|
|
]}
|
|
```
|
|
|
|
### 3. Cross-Switching Flow
|
|
|
|
```
|
|
Client → POST /api/v1/crossswitch
|
|
{ camera_id: 7, monitor_id: 3, mode: 0 }
|
|
↓
|
|
FastAPI validates JWT (requires operator role)
|
|
↓
|
|
Validate camera_id and monitor_id exist
|
|
↓
|
|
gRPC call to SDK Bridge: ExecuteCrossSwitch(7, 3, 0)
|
|
↓
|
|
SDK Bridge → GeViScope SDK
|
|
→ SendMessage("CrossSwitch(7, 3, 0)")
|
|
↓
|
|
GeViServer executes cross-switch
|
|
↓
|
|
SDK Bridge ← Success confirmation
|
|
↓
|
|
FastAPI stores route in PostgreSQL
|
|
↓
|
|
FastAPI logs to audit_logs table
|
|
↓
|
|
Client ← { success: true, message: "Camera 7 routed to monitor 3" }
|
|
```
|
|
|
|
---
|
|
|
|
## Security Architecture
|
|
|
|
### Authentication & Authorization
|
|
|
|
**Authentication**: JWT (JSON Web Tokens)
|
|
- Access tokens: 1 hour lifetime
|
|
- Refresh tokens: 7 days lifetime (future)
|
|
- Tokens stored in Redis for quick invalidation
|
|
- Bcrypt password hashing (cost factor: 12)
|
|
|
|
**Authorization**: Role-Based Access Control (RBAC)
|
|
|
|
| Role | Permissions |
|
|
|------|------------|
|
|
| **Viewer** | Read cameras, Read monitors, Read routing state |
|
|
| **Operator** | Viewer + Execute cross-switch, Clear monitors |
|
|
| **Administrator** | Operator + User management, Configuration |
|
|
|
|
### API Security
|
|
|
|
- ✅ HTTPS enforced in production (TLS 1.2+)
|
|
- ✅ CORS configured for allowed origins
|
|
- ✅ Rate limiting (60 requests/minute per IP)
|
|
- ✅ JWT secret key from environment (not hardcoded)
|
|
- ✅ Database credentials in environment variables
|
|
- ✅ No stack traces exposed to clients
|
|
- ✅ Audit logging for all operations
|
|
|
|
---
|
|
|
|
## Scalability Considerations
|
|
|
|
### Current Architecture (MVP)
|
|
- Single FastAPI instance
|
|
- Single SDK Bridge instance
|
|
- Single GeViServer connection
|
|
|
|
### Future Horizontal Scaling
|
|
|
|
**FastAPI Layer**:
|
|
- ✅ Stateless design enables multiple instances
|
|
- ✅ Load balancer in front (nginx/HAProxy)
|
|
- ✅ Shared PostgreSQL and Redis
|
|
|
|
**SDK Bridge Layer**:
|
|
- ⚠️ Limited by GeViServer connection capacity
|
|
- Consider: Connection pooling pattern
|
|
- Consider: Multiple SDK Bridge instances if needed
|
|
|
|
**Database Layer**:
|
|
- PostgreSQL read replicas for camera/monitor queries
|
|
- Redis Cluster for high availability
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
### SDK Bridge Error Translation
|
|
|
|
| SDK Error | gRPC Status | HTTP Status |
|
|
|-----------|-------------|-------------|
|
|
| Connection Failed | UNAVAILABLE | 503 Service Unavailable |
|
|
| Invalid Channel | INVALID_ARGUMENT | 400 Bad Request |
|
|
| Permission Denied | PERMISSION_DENIED | 403 Forbidden |
|
|
| Timeout | DEADLINE_EXCEEDED | 504 Gateway Timeout |
|
|
| Unknown | INTERNAL | 500 Internal Server Error |
|
|
|
|
### Retry Logic
|
|
- SDK Bridge connection: 3 attempts with exponential backoff
|
|
- gRPC calls from FastAPI: 2 attempts with 1s delay
|
|
- Transient errors logged but not exposed to client
|
|
|
|
---
|
|
|
|
## Monitoring & Observability
|
|
|
|
### Logging
|
|
|
|
**FastAPI**:
|
|
- Structured JSON logs (Structlog)
|
|
- Log levels: DEBUG, INFO, WARNING, ERROR
|
|
- Correlation IDs for request tracing
|
|
|
|
**SDK Bridge**:
|
|
- Serilog with file and console sinks
|
|
- Separate logs for SDK communication
|
|
|
|
### Metrics (Future)
|
|
|
|
**Prometheus Endpoint**: `/metrics`
|
|
- Request count by endpoint
|
|
- Request latency (p50, p95, p99)
|
|
- Active cross-switch operations
|
|
- gRPC call success/failure rates
|
|
- Cache hit/miss rates
|
|
|
|
### Health Checks
|
|
|
|
**Endpoint**: `GET /api/v1/health`
|
|
|
|
Returns:
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"components": {
|
|
"database": "up",
|
|
"redis": "up",
|
|
"sdk_bridge": "up"
|
|
},
|
|
"timestamp": "2025-12-08T15:30:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Deployment Architecture
|
|
|
|
### Development Environment
|
|
```
|
|
Localhost:
|
|
- PostgreSQL (Docker or native)
|
|
- Redis (Docker or native)
|
|
- SDK Bridge (.NET)
|
|
- FastAPI (uvicorn --reload)
|
|
- GeViServer (C:\GEVISOFT\GeViServer.exe)
|
|
```
|
|
|
|
### Production Environment (Windows Server)
|
|
```
|
|
Windows Server 2016+:
|
|
- GeViServer (native Windows service)
|
|
- SDK Bridge (Windows service via NSSM)
|
|
- PostgreSQL (Docker or native)
|
|
- Redis (Docker or native)
|
|
- FastAPI (Docker or uvicorn behind nginx)
|
|
- Nginx (reverse proxy with SSL termination)
|
|
```
|
|
|
|
### Network Requirements
|
|
- Port 8000: FastAPI (HTTPS in production)
|
|
- Port 50051: SDK Bridge gRPC (internal only)
|
|
- Port 5432: PostgreSQL (internal only)
|
|
- Port 6379: Redis (internal only)
|
|
- Port 7700-7703: GeViServer (internal only)
|
|
|
|
---
|
|
|
|
## Technology Choices Rationale
|
|
|
|
### Why Python FastAPI?
|
|
- ✅ Modern async Python framework
|
|
- ✅ Automatic OpenAPI documentation
|
|
- ✅ Fast development cycle
|
|
- ✅ Rich ecosystem (SQLAlchemy, Pydantic)
|
|
- ✅ Easy to expand with new features
|
|
|
|
### Why C# SDK Bridge?
|
|
- ✅ GeViScope SDK is .NET Framework 4.8
|
|
- ✅ gRPC provides type-safe communication
|
|
- ✅ Isolates SDK complexity
|
|
- ✅ Can run on separate machine if needed
|
|
|
|
### Why PostgreSQL?
|
|
- ✅ Mature, reliable, ACID compliant
|
|
- ✅ JSON support for flexible audit logs
|
|
- ✅ Good performance for relational data
|
|
|
|
### Why Redis?
|
|
- ✅ Fast in-memory caching
|
|
- ✅ Session storage
|
|
- ✅ Future: pub/sub for events
|
|
|
|
### Why gRPC (not REST for SDK Bridge)?
|
|
- ✅ Type-safe protocol buffers
|
|
- ✅ Efficient binary protocol
|
|
- ✅ Streaming support (future)
|
|
- ✅ Language-agnostic
|
|
|
|
---
|
|
|
|
## Future Enhancements (Phase 2)
|
|
|
|
1. **GeViSet Configuration Management**
|
|
- Retrieve action mappings from GeViServer
|
|
- Modify configurations via API
|
|
- Export/import to CSV
|
|
- Push configurations back to server
|
|
|
|
2. **Real-Time Event Stream**
|
|
- WebSocket endpoint for routing changes
|
|
- Redis pub/sub for event distribution
|
|
- Monitor status change notifications
|
|
|
|
3. **PTZ Camera Control**
|
|
- Pan/tilt/zoom commands
|
|
- Preset positions
|
|
- Tour sequences
|
|
|
|
4. **Multi-Tenancy**
|
|
- Organization/tenant isolation
|
|
- Per-tenant GeViServer connections
|
|
|
|
5. **Advanced Analytics**
|
|
- Routing history reports
|
|
- Usage patterns
|
|
- Performance metrics
|
|
|
|
---
|
|
|
|
## Development Workflow
|
|
|
|
1. **Setup**: `.\scripts\setup_dev_environment.ps1`
|
|
2. **Start Services**: `.\scripts\start_services.ps1`
|
|
3. **Database Migrations**: `alembic upgrade head`
|
|
4. **Run Tests**: `pytest tests/ -v`
|
|
5. **Code Quality**: `ruff check src/api` + `black src/api`
|
|
6. **API Docs**: http://localhost:8000/docs
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- **FastAPI Documentation**: https://fastapi.tiangolo.com
|
|
- **gRPC .NET**: https://grpc.io/docs/languages/csharp/
|
|
- **GeViScope SDK**: See `docs/SDK_INTEGRATION_LESSONS.md`
|
|
- **SQLAlchemy**: https://docs.sqlalchemy.org
|
|
- **Pydantic**: https://docs.pydantic.dev
|
|
|
|
---
|
|
|
|
**Document Version**: 1.0
|
|
**Architecture Status**: ✅ Defined, 🔄 In Development
|
|
**Last Review**: 2025-12-08
|