Clients
(web)
(web)
🧑💻EmployeeSubmits & tracks requests
🎧Help Desk AgentTriages, comments, resolves
📊IT Manager / AdminQueues, SLA, reports, admin
HTTPS · JWT bearer + httpOnly refresh cookie · WSS
▼
Edge
🛡️Caddy — TLS edge / reverse proxy
Terminates TLS (HTTPS only). Routes /v1/* & /api/* → API; everything else → Web. Forces HTTP→HTTPS, sets HSTS, sizes large client-header buffers.
▼
Presentation
▲Next.js 16 — Web (apps/web)
App Router. Marketing landing + app shell (sidebar + header). 13 screens, light/dark.
🔌API client + Realtime
Typed fetch → /v1, Bearer + silent refresh; RFC 9457 errors mapped to fields. socket.io client for live updates.
📦packages/shared
DTOs, enums, ticket state machine, error contract constants — shared by web + API.
REST /v1 (JSON)
▼
API request
pipeline
(apps/api)
pipeline
(apps/api)
⚙️NestJS 11 — every authenticated request flows top → bottom
1Helmet · CORS allowlist · Throttler (rate limit)
↓
2JwtAuthGuard → Principal {userId, tenantId, role}
↓
3RolesGuard — RBAC (@Roles)
↓
4TenantTxInterceptor — opens tx, SET LOCAL app.tenant_id
↓
5ValidationPipe (whitelist) — strips client SLA/audit fields
↓
6assertResourceAccess — object-level authz (404 to non-owner)
↓
7Domain services
Ticketsstate machine · @Version (409)
Commentsinternal vs public
Attachmentsmagic-byte · gated DL
SLAserver-side evaluator
Authargon2 · HIBP · anti-enum
Users / CatalogRBAC admin
Dashboard / Reportsmetrics · PDF/CSV/JSON
Notificationsin-app
Outboxemail + webhook
Auditappend-only
Webhooks (in)verify-before-read
Events Gatewaysocket.io /events
⤴ProblemDetailsFilter — all errors as RFC 9457 application/problem+json
TypeORM (pooled) · tenant tx · RLS enforced as servicehub_app
▼
Data &
state
state
🐘PostgreSQL 18
15 tenant-scoped tables, all with tenant_id. Row-Level Security policies + FORCE RLS; app connects as non-owner servicehub_app. Optimistic @VersionColumn; UNIQUE dedup keys.
⚡Redis 7
Auth rate-limit counters (ip,email), cache for SLA/category lookups, and the BullMQ queue backend. socket.io multi-pod adapter.
▲▼
outbox rows (same tx) · repeatable jobs · pub/subAsync,
realtime &
external
realtime &
external
🔁Worker (BullMQ)
Repeatable maintenance tick (30s): drains the email outbox (capped backoff → DLQ) and runs the SLA evaluator per tenant, emitting breach notifications.
📡EventsGateway
socket.io /events. JWT handshake + Origin check; per-room (tenant/ticket) authz. Pushes ticket/comment/SLA events back to clients.
✉️Resend (external)
Transactional email via the outbox (console stub when unconfigured). Inbound delivery webhooks verified HMAC-before-read & deduped.
↳ Worker ↔ Redis (queue) · Worker → PostgreSQL (drain/evaluate) · Worker → Resend (send) · Gateway ↔ Redis (adapter) ⇄ Clients (WSS)