Skip to content

Lessons Learnt

Experience notes from building HVC. These are informal observations — useful context before touching the code.

Multi-tenancy is the source of most complexity

  • Subdomain → realm → tenant resolution touches every service and every query. Changes to tenant resolution ripple widely; keep it in one place (ITenantService / MultiTenantConnectionInterceptor).
  • Deleting a tenant requires cleaning many tables (chat included) — that's why the admin API has a dedicated TenantDeletionService.

Realtime has many moving parts

  • SignalR (hvc-api) and WebSockets (hvc-ws) both push state; make sure clients subscribe to the right one and reconnect cleanly.
  • WebRTC signaling over SignalR works but couples call flow to hub lifecycle — test reconnects and token refreshes carefully.

Recording pipeline is fragile by nature

  • Files flow disk → blob (hvc-filePushApi) → tenant storage (hvc-services) while hvc-sinkapi marks events complete. Filename conventions (env__eventId__tenantId__...) are load-bearing — don't change them without updating all three services.

Environment-awareness in workers

  • hvc-services and hvc-sinkapi spin up one worker per configured environment. Adding an environment means config in multiple places (processors[], environments[], connection strings).

Docs drift

  • Several services (hvc-ws Seq wiring, hvc-filePushApi console logging) lag their config. When touching a service, check its Serilog/Seq setup.

Shared libraries drift

  • hvc-admin-api and hvc-filePushApi each carry their own copy of the blob wrapper instead of referencing hvc-storage. Prefer the shared library for new code.

See also

Released under the MIT License.