Phase 1 Complete: Project Setup & Configuration
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>
This commit is contained in:
497
docs/architecture.md
Normal file
497
docs/architecture.md
Normal file
@@ -0,0 +1,497 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user