Developer Guide
CrowdVision is designed as a distributed, event-driven microservices architecture By completely separating the frontend client from the backend services—and further isolating those backend services from one another—the platform achieves high fault tolerance, independent scalability, and strict data boundary enforcement.
All incoming external traffic (both standard HTTP and WebSockets) enters the system through a single Caddy reverse-proxy gateway exposed on port 80.
Caddy acts as the traffic cop: it strips the service prefixes from the URLs and securely proxies the requests to the appropriate target containers running on the internal Docker bridge network.
graph TD
Browser["Browser / Vue Client"] -->|HTTP + WS| Caddy["Caddy Gateway :80"]
IoT["IoT Sensors (Physical/Simulated)"] -->|HTTP POST| Caddy
subgraph gateway-net [Shared Gateway Network]
Caddy -->|/auth/*| Auth["auth-service :3000"]
Caddy -->|/twin/*| Twin["twin-service :3000"]
Caddy -->|/notification/*| Notif["notification-service :3000"]
Caddy -->|/socket.io/*| Socket["socket-server :3000"]
Notif -->|PUBLISH| Redis[("Redis Broker")]
Socket -->|SUBSCRIBE| Redis
end
subgraph auth-net [Auth Private Network]
Auth --- AuthDB[("auth-db MongoDB")]
end
subgraph twin-net [Twin Private Network]
Twin --- TwinDB[("twin-db MongoDB")]
end
subgraph notification-net [Notification Private Network]
Notif --- NotifDB[("notification-db MongoDB")]
endNotice the strict network segregation in the diagram above. Each microservice is attached to two networks:
Caddy maps external URL paths to internal services according to this strict routing table:
| External Auth Prefix | Internal Target Backend Service | Purpose |
|---|---|---|
| /auth/ | auth-service | Account creation, login, SSO, JWT verification. |
| /twin/ | twin-service | Building models, room CRUD operations, spatial data. |
| /notification/ | notification-service | Processing sensor events, triggering Web Push alerts. |
| /socket.io/ | socket-service | Maintaining persistent WebSocket connections to the frontend. |
🛠️ Developer Mode Only: When running npm run dev, Caddy also exposes auth-db-gui:8081 and twin-db-gui:8081 on paths /auth-db-gui/* and /twin-db-gui/* to allow direct database inspection.
The most critical flow in CrowdVision is how a physical event (like 50 people walking into a room) triggers a UI update and an emergency notification in a facility manager’s browser. This is achieved using Redis Pub/Sub to decouple the data ingestion from the data broadcast.
sequenceDiagram
participant Sensor as IoT Sensor
participant NotifSvc as Notification Service
participant Redis as Redis Broker
participant SocketSvc as Socket Service
participant VueClient as Vue Frontend
Sensor->>NotifSvc: POST /notification/trigger (Data Payload)
activate NotifSvc
Note over NotifSvc: Evaluate limits (overcrowding / maxTemp)
NotifSvc->>Redis: redisClient.publish('notifications', payload)
deactivate NotifSvc
activate Redis
Redis-->>SocketSvc: Message received via SUBSCRIBE
deactivate Redis
activate SocketSvc
SocketSvc->>VueClient: io.emit('notification', data)
deactivate SocketSvc
activate VueClient
Note over VueClient: Client socket.ts updates reactive<br/>`socketState.notifications` array
VueClient-->>VueClient: NotificationBell badge increments
VueClient-->>VueClient: PushNotificationToast displays alert
deactivate VueClient