Skip to main content

Smart Corridor & eGate Hub

The Smart Corridor & eGate Hub is the central system for the biometric corridor and eGate platform. It aggregates events from all internal source systems, normalizes them into a unified event model, and exposes them to external consumers through dedicated service endpoints.

The Hub is the only system end users, integrators, and partners interact with. VPP, CIGS, CBS, and MCT are internal concerns invisible to the outside world.

Repository structure

The Hub is a multi-service repository. Each service is independently deployable but shares a common module for domain models, ORM entities, DTOs, and event notification types.

ServiceRoleStatus
GraphQL APILive subscriptions and data queries for external consumersActive
DbWorker ServiceEvent persistence and data retentionActive
REST APIAlternative HTTP interface for integrationsPlanned

Shared module — ORM models (IdentificationEvents, Identities, IdentityFaces, ZoneEvents), DTOs, notification types, and RabbitMQ configuration are shared across all services within the repository.

Responsibilities

  • Consuming all normalized events from the internal biometric_events message broker
  • Exposing live event subscriptions and historical queries to external consumers
  • Persisting finalized outgoing events for short-term audit and retrieval
  • Proxying VPP management data (cameras, watchlists, members) for the GUI
  • Enforcing configurable data retention and GDPR compliance modes

The VPP Adapter and CIGS Adapter are also Hub components — they live in the Hub repository and are responsible only for translation and routing, containing no business logic.

Data model

The Hub owns the following entities in PostgreSQL:

TableDescription
identification_eventsIdentification outcomes with face crops, full frames, member context
identitiesAnonymous face tracks from CIGS with optional linked identification
identity_facesIndividual face detections associated with an identity
zone_eventsAll zone-level events (entry, exit, count changes, violations, movement)

VPP entities (cameras, watchlists, members) are not stored locally — they are proxied from VPP on demand by the GraphQL API.

GraphQL API

The GraphQL API is the primary external-facing service of the Hub. It exposes a single /graphql endpoint that serves live event subscriptions over WebSocket or SSE, and historical data queries over HTTP POST. All external consumers — the officer and traveler GUI, partners, and integrators — communicate exclusively through this service; no other Hub service exposes an external interface.

Subscriptions

Live notifications are delivered as GraphQL subscriptions, one per notification topic:

  • IdentificationidentificationMatch, identificationNoMatch, identificationClearanceGreen, identificationClearanceRed, identificationConditionViolation
  • Identity LifecycleidentityCreated, identityUpdated
  • ZonezonePersonEntered, zonePersonLeft, zonePersonAvoidingIdentification, zoneOccupancyViolation, zonePersonsCountChanged, zonePersonMoved

A combined events(filter: EventFilter) subscription is also available for consumers who prefer a single stream with optional type filtering.

Queries

Historical event queries — events persisted by the DbWorker Service are queryable by event type, time range, unit ID, correlation ID, and source system. Results are paginated and returned in chronological order.

VPP proxy queries — the GraphQL API proxies VPP's management data transparently, presenting it as part of the unified Hub API: cameras, watchlists, and members. These are resolved on demand by delegating to VPP's own GraphQL API; no local copy is stored.

Built with Spring for GraphQL, Kotlin, and Spring Boot 3.x. Internally, a Kotlin Flow bridge routes events consumed from RabbitMQ to the appropriate GraphQL subscription publishers in real time.

DbWorker Service

The DbWorker Service is the persistence and data lifecycle service within the Hub. It writes finalized outgoing events to the database and enforces configurable data retention policies. It has no external interface — it operates entirely as a background service, consuming from RabbitMQ in parallel with and independently of the GraphQL API.

Only finalized outgoing events — the same events exposed externally — are stored, into the tables listed under Data model. Raw or intermediate internal events from VPP, CIGS, CBS, or MCT are never stored. Face crops and full frames are stored directly in PostgreSQL as BYTEA columns; a dedicated object storage service is not required given the short retention window.

Retention

A scheduled job removes expired records from all tables; retention periods are independently configurable per data type. Event records default to 48 hours, image data to 24 hours. Setting STORAGE_ENABLED=false disables persistence entirely — the recommended configuration for GDPR-sensitive deployments where event data must not be stored at rest.

Built with Spring Boot 3.x, Kotlin, Spring Data JPA, and PostgreSQL.

Deployment configuration

Unit configuration is environment-based. A single Hub instance can serve multiple units (corridors and eGates).

STORAGE_ENABLED=true
RETENTION_TTL_EVENTS_HOURS=48
RETENTION_TTL_IMAGES_HOURS=24
RETENTION_JOB_INTERVAL_MINUTES=30

UNITS_0_ID=corridor-a
UNITS_0_NAME=Corridor A
UNITS_0_TYPE=CORRIDOR
UNITS_0_CAMERAS=cam-001,cam-002

UNITS_1_ID=egate-1
UNITS_1_NAME=eGate 1
UNITS_1_TYPE=EGATE
UNITS_1_CAMERAS=cam-010

Future extensions

When eGate-specific notifications diverge from corridor notifications, topic prefixes (corridor.*, egate.*) will be introduced without breaking existing subscribers. The REST API service will expose the same event model over HTTP when available.