Architecture

System Overview

Multi-tenant AI interview platform architecture with event-driven microservices.

The AI Interview System is an event-driven, multi-tenant platform. At its core is a NestJS API gateway that orchestrates three subsystems: the Agno Python agents for AI reasoning, the Vert.x WebSocket edge for real-time interview audio, and the HITL workflow engine for human oversight.

Architecture Layers

LayerTechnologyResponsibility
API GatewayNestJS 10 + TypeScriptREST/A2A endpoints, JWT/API-key auth, multi-tenant routing
Agno AgentsPython + Agno frameworkSkill validation, plan generation, real-time interview, assessment
WebSocket EdgeVert.x (JVM)Real-time audio streaming between candidate and agent
DatabasePostgreSQL 16 + pgvectorInterview data, workflow states, skill embeddings (RLS)
Event BusApache KafkaAsync event streaming between all services
CacheRedis 7Session data, rate limiting, distributed locks

Multi-tenancy

Every database query is filtered by tenantId. Row-Level Security policies at the PostgreSQL level enforce isolation even if application code has a bug.

typescript
// Every controller extracts tenantId from the JWT
@Get()
async findAll(@TenantId() tenantId: string) {
  return this.interviewService.findAll(tenantId);
}

// Every service filters by tenantId
async findAll(tenantId: string) {
  return this.prisma.interview.findMany({
    where: { tenantId },  // Required — never omit!
  });
}
Never query the database without a tenantId filter. All services enforce this via the @TenantId() decorator and RLS policies.

Kafka Event Topics

TopicPublished ByConsumed ByTrigger
interview.info_neededAPI GatewayNotification ServiceData validation fails
skill.validation.requestedAPI GatewayAgno Planner AgentData complete / info completed
plan.generatedAgno AgentWorkflow EnginePlan generation complete
approval.approvedAPI GatewayCandidate AccessRecruiter approves plan
approval.rejectedAPI GatewayAgno AgentRecruiter rejects plan
interview.completedVert.x EdgeAgno Assessor AgentInterview session ends
assessment.completedAgno AgentWorkflow EngineAI assessment ready

Service Ports

ServicePortProtocol
API Gateway (NestJS)3009HTTP/REST + Kafka
Agno Agents (Python)8000HTTP + Kafka
WebSocket Edge (Vert.x)8080WebSocket
PostgreSQL5432TCP
Kafka9092TCP
Redis6379TCP

Interview Data Flow

1. Plan Generation

text
External System
    │
    ▼
POST /api/v1/a2a/interview (API Gateway)
    │
    ├── Validate data completeness
    │
    ├── Save to PostgreSQL (state: RECEIVED → VALIDATING_SKILLS)
    │
    └── Publish: skill.validation.requested (Kafka)
              │
              ▼
        Agno Planner Agent (Python)
              │
              ├── Validate skills via pgvector similarity search
              ├── Generate interview plan using Claude/GPT
              └── Publish: plan.generated (Kafka)
                          │
                          ▼
                  API Gateway consumes → state: PENDING
                          │
                          └── Send webhook: interview.plan_generated

2. Live Interview

text
Candidate Browser
    │
    ├── GET /candidate-access/:token/info
    ├── POST /candidate-access/:token/request-otp
    ├── POST /candidate-access/:token/verify-otp → session token
    └── POST /candidate-access/:token/start → sessionId
              │
              ▼
        WebSocket: ws://localhost:8080 (Vert.x Edge)
              │
              ├── Audio chunks: candidate voice (16kHz PCM)
              ├── Kafka: video.candidate.stream (30s WebM chunks)
              │
              └── Agno Interview Agent:
                      ├── Transcribe candidate speech
                      ├── Generate agent responses
                      └── Synthesize TTS audio → candidate browser

Permissions

PermissionRolesDescription
interview:createADMIN, RECRUITERCreate new interviews via A2A or internal API
interview:readADMIN, RECRUITER, VIEWERRead interview details and status
interview:updateADMIN, RECRUITERUpdate interview data (HITL completion)
interview:approveADMIN, RECRUITERApprove/reject plans and assessments
interview:deleteADMINDelete interview records
Was this page helpful?