Skip to content

Operations

1. Deployment

PropertyValue
Imageregistry/helpdesk:<tag>
ProcessesAPI (RUN_MODE=startup) + Worker (RUN_MODE=worker) + one-shot Migration (RUN_MODE=migrate)
Container Port3000 (external 31130)
Snowflake node id12
ProbesGET /healthz (live), GET /readyz (ready) — IGNIS defaults
Migration moderun-once job (bun run migrate)

The API and Worker share one image; the role is selected by RUN_MODE. The Worker process must run for SLA monitoring, assignment, escalation, notifications, context enrichment, and survey triggers to function.

Traefik labels

yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.helpdesk.rule=PathPrefix(`/v1/api/helpdesk`)"
  - "traefik.http.services.helpdesk.loadbalancer.server.port=3000"

2. Observability

SignalSourceWhere to look
Logsstdout, prefixed [ComponentName] (e.g. [QueueComponent], [ProcessEscalation]) via console.log/console.errorkubectl logs <pod> / Loki
MetricsIGNIS defaults if exposedGrafana
TracesNone wired
HealthGET /healthz, GET /readyzGateway portal
Queue depthBullMQ (Redis)Bull board / Redis inspection

Key log markers

MarkerMeaning
[QueueComponent] SLA Monitor cron job scheduledWorker booted SLA cron
[ProcessEscalation] Reassigning ticket …Escalation reassign path (see Known Issues)
[EventHandlerRegistry] Handler failed for <event>In-process listener error (caught)

Logging is unstructured console.* (no key-value logger in workers/listeners). Cross-service request-id propagation applies at the IGNIS HTTP layer only.

3. Security

ConcernMitigation
AuthNJWT (ES256) verified against identity JWKS — VerifierApplication
AuthZPer-merchant scoping via assertMerchantAccess() + useRequestContext(); helpdesk PermissionService for finer checks. No per-route @authenticate decorator — controllers enforce access in handlers
SecretsEnv (APP_ENV_*) incl. SMTP + Redis passwords; never in code. .env.development contains real-looking dev secrets — rotate before any non-dev use
TenancyAll ticket queries scoped by merchantId / organizerId
Soft-deletedeletedAt — no hard-delete by default
Internal/private notesTicketMessage.isInternal hides notes from reporters

4. Runbook

4.1 Alert classes

AlertTriggerCheckFixEscalate
helpdeskWorkerDownNo SLA-monitor cron logsWorker pod statusRestart worker (RUN_MODE=worker)on-call backend
helpdeskQueueLagBullMQ pending highRedis queue depthScale workers / inspect failureson-call SRE
helpdeskNotificationFailnotification jobs hitting max retries (5)SMTP creds / notification-delivery-logFix SMTP, replay DLQon-call backend
helpdeskSlaBreachSpikebreach rate upSlaTracker status countsCheck agent staffing / policiessupport-team

4.2 Common operations

OperationCommand / action
Tail API logskubectl logs -n <ns> -f deploy/helpdesk-api
Tail worker logskubectl logs -n <ns> -f deploy/helpdesk-worker
Trigger SLA checkQueueComponent.triggerSlaCheck({ ticketId? }) (manual job, priority HIGH)
Reset SLA cronWorker restart re-registers sla-monitor-cron (removes stale repeatables)
Run migrationbun run migrate:dev (per-package; never run by the agent)
Replay dead-lettered jobsvia HandleDeadLetterUseCase / dlq.helper.ts

5. Known Issues

The TypeScript build of @nx/helpdesk currently fails. Per the package AGENTS.md, the cause is a dead assignTicketUseCase reference path. The Level-2+ escalation reassignment call (this.assignTicketUseCase.execute(...)) in src/application/use-cases/sla-policy/process-escalation.use-case.ts is commented out — that use-case is not injected into ProcessEscalationUseCase, so SLA escalation does not reassign tickets to a senior agent; it only sends an escalation-assignment notification. Do not fix the source as part of documentation work.

ImpactDetail
Buildbun run rebuild / tsc fails; deployable artifacts cannot be produced until repaired
Escalation reassignmentDisabled — senior-agent reassignment on Level 2/3 is a no-op (notification only)
Identity drift.env.development carries stale SVC-00030 / 31032 / 0; reconcile to app-info.json (SVC-00120 / 31130 / 12) when build is fixed (see Configuration)
Dead dependency@platformatic/kafka declared but unused — candidate for removal

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.