Files
support_backend/docs/07-backend-architecture.md
T
saqib mirandClaude Sonnet 5 f475a55a53 docs: add product and engineering specification
Full system blueprint (docs 01-10): product vision, integration &
security, AI support architecture, ticketing & problem management,
orchestration/SLA/escalation, database schema, backend/frontend
architecture, testing/observability/CI-CD, and the implementation
roadmap. This is the pre-implementation design reference the codebase
is being built against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 16:22:21 +05:30

6.4 KiB

07 — Backend Architecture

1. Technology stack

  • Node.js + TypeScript
  • Fastify
  • PostgreSQL + Prisma
  • Redis + BullMQ
  • Pino (structured logging)
  • OpenAPI
  • Zod (validation)
  • Vitest
  • Docker

Architecture style: modular monolith. Do not start with microservices — the module boundaries below make a future split possible, but premature service decomposition adds operational cost this system doesn't need yet.

2. Top-level source layout

src/
├── config
├── bootstrap
├── plugins
├── common
├── infrastructure
├── modules
├── events
├── jobs
└── api

3. Domain module groups

modules/
├── identity
│   ├── auth
│   ├── customers
│   ├── agents
│   └── teams
│
├── catalog
│   ├── products
│   ├── categories
│   ├── problem-types
│   └── priorities
│
├── ticketing
│   ├── tickets
│   ├── messages
│   └── attachments
│
├── problem-management
│   ├── problems
│   ├── investigation
│   ├── root-causes
│   ├── solutions
│   ├── verification
│   └── resolutions
│
├── ai-support
│   ├── agents
│   ├── sessions
│   ├── diagnosis
│   ├── knowledge
│   ├── troubleshooting
│   ├── tools
│   ├── tool-execution
│   ├── verification
│   └── escalation
│
├── orchestration
│   ├── hierarchy
│   ├── routing
│   ├── orchestration
│   ├── assignments
│   ├── sla
│   └── escalation
│
└── platform
    ├── notifications
    ├── audit
    ├── business-calendars
    ├── integrations
    ├── reports
    └── admin

Note: identity here means SupportHub's own agent/team/support-domain identity — not a re-implementation of SaaS user/tenant identity. See 01 and 02.

4. Module internal structure

Standard module:

module/
├── controller/
├── routes/
├── schema/
├── repository/
├── service/
├── types/
├── mapper/
├── constants/
└── index.ts

Complex modules (real decision logic, not just CRUD) add:

├── engine/
├── rules/
├── strategies/
└── calculators/

Example — orchestration:

orchestration/
├── controller
├── routes
├── schema
├── repository
├── service
├── engine
├── rules
├── types
├── mapper
├── constants
└── index.ts

ai-support and orchestration are the two module groups most likely to need the extended structure across nearly all their submodules — see 03 and 05.

5. Request flow

HTTP → Route → Schema validation → Controller → Service
     → Engine/Rules (if required) → Repository → Prisma → PostgreSQL

Rules:

  • Controller never touches Prisma directly.
  • Repository is the only layer that talks to Prisma.
  • Service coordinates business workflows and calls repositories/engines.
  • Engine implements complex decision logic (assignment strategy selection, SLA calculation, escalation rule evaluation, AI tool-execution policy).

6. Module boundaries

Modules must not reach into another module's internals. Only import through the target module's public index.ts.

// Allowed
import { TicketService } from "@/modules/ticketing/tickets";

// Not allowed — reaches past the module boundary
import { TicketRepository } from "@/modules/ticketing/tickets/repository/ticket.repository";

7. Redis / BullMQ usage

Redis is not a source of truth — it's for queues, caching, and coordination. Use BullMQ jobs for:

  • SLA monitoring (warning, breach detection)
  • Escalation triggering
  • Notifications
  • AI background work where appropriate (long-running tool calls, batch re-diagnosis)
  • Analytics rollups
  • Attachment processing (malware scan, thumbnailing)
  • Cleanup jobs

Jobs must be durable and idempotent. Never use setTimeout or any in-memory timer for production SLA enforcement — a process restart must not lose or double-fire SLA state transitions.

8. Domain events

Emit and consume these as first-class domain events (not just side effects buried in service code), so audit, notifications, analytics, and SLA/escalation subsystems can all react independently:

TicketCreated, ProblemCreated, TicketClassified
AIAnalysisStarted, KnowledgeRetrieved, AIDiagnosisCompleted
AIActionRequested, AIActionCompleted, AITroubleshootingStarted
AIResolutionVerified, TicketEscalatedToHuman
TicketAssigned, TicketReassigned, PriorityChanged
SLANearingBreach, SLABreached
InvestigationStarted, RootCauseIdentified
SolutionProposed, SolutionImplemented, VerificationCompleted
TicketResolved, TicketClosed, TicketReopened

Events must be traceable (correlation ID) and auditable.

9. Notifications

Channels: in-app, email, push (where appropriate). Triggered asynchronously (via job queue, never inline in the request path) on: ticket created, AI solved, human escalation, assignment, agent reply, SLA warning, SLA breach, escalation, resolution, closure, reopen.

10. Audit

Audit every important action: ticket creation, AI escalation, assignment/reassignment, priority changes, hierarchy changes, SLA changes, escalation, investigation, root cause, solution, verification, resolution, closure.

Audit record shape:

interface AuditRecord {
  actor: string;
  actorType: "customer" | "agent" | "admin" | "system" | "ai";
  action: string;
  entity: string;
  entityId: string;
  oldValue?: unknown;
  newValue?: unknown;
  timestamp: Date;
  reason?: string;
  metadata?: Record<string, unknown>;
}

Security-relevant audit records should be append-only from the application's perspective — no service-layer update/delete path against AuditLog.

11. Observability endpoints

GET /health
GET /health/live
GET /health/ready
GET /metrics

Structured logging via Pino, with request ID and correlation ID on every log line; metrics and tracing wired through from day one, not bolted on later. Full metric list is in 09.