Back to blog
Next.jsTypeScriptAIOpenAIFull-StackSaaS
TickMate: Engineering an AI-Powered Support Ticket Platform
A detailed technical breakdown of TickMate's architecture — from its multi-tenant database design and AI analysis pipeline to role-based access control and real-time analytics.
5 min read·Talha Bilal

Introduction
TickMate is a full-featured, AI-powered support ticket management platform designed to eliminate manual triage bottlenecks. This post breaks down the complete architecture — from database schema to AI pipeline to production deployment.

System Architecture Overview
Rendering diagram...
Frontend Architecture
The frontend is built with Next.js 16 App Router with a clear server/client component boundary:

Component Hierarchy
text
1Layout (Server)2├── AuthProvider (Client)3├── DashboardLayout (Server)4│ ├── Sidebar (Client)5│ ├── Header (Client)6│ └── PageContent (Server/Client)7├── TicketList (Server)8│ └── TicketCard (Client)9├── TicketDetail (Server)10│ ├── AIAnalysisPanel (Client)11│ ├── ActivityTimeline (Server)12│ └── CommentForm (Client)13└── AdminPanel (Server)14 └── UserManagement (Client)Authentication & Authorization
TickMate implements a comprehensive role-based access system with three tiers:
Rendering diagram...
Auth Flow
JWT-based authentication with HttpOnly cookies for security:

text
1Login Request → Validate Credentials → Generate JWT →2Set HttpOnly Cookie → Redirect to DashboardAI Analysis Pipeline
The core differentiator is the automated ticket analysis system:

Rendering diagram...
LangChain Integration
The AI pipeline uses LangChain's structured output capabilities:
typescript
1import { ChatOpenAI } from "@langchain/openai";2import { StructuredOutputParser } from "langchain/output_parsers";3
4const parser = StructuredOutputParser.fromNamesAndDescriptions({5 summary: "A concise 1-2 sentence summary of the issue",6 priority: "Suggested priority: low, medium, high, or critical",7 skills: "Comma-separated list of required skills to resolve",8 notes: "Additional helpful context for the assignee",9});10
11const chain = new LLMChain({12 llm: new ChatOpenAI({ modelName: "gpt-4.1-mini", temperature: 0 }),13 prompt: analysisPrompt,14 outputParser: parser,15});Database Schema
The PostgreSQL database uses a multi-tenant design with role-based data isolation:
Rendering diagram...
Role Management

Permission Matrix
| Feature | Customer | Agent | Admin |
|---|---|---|---|
| Create ticket | ✓ | ✓ | ✓ |
| View own tickets | ✓ | ✓ | ✓ |
| View all tickets | - | ✓ | ✓ |
| Assign tickets | - | - | ✓ |
| Delete tickets | - | - | ✓ |
| Manage users | - | - | ✓ |
| View analytics | - | - | ✓ |
| System settings | - | - | ✓ |
Ticket Lifecycle

Rendering diagram...
Logging & Observability
Every action in the system is tracked through comprehensive audit logging:

typescript
1// Audit log entry structure2interface AuditEntry {3 userId: number;4 action: "CREATE" | "UPDATE" | "DELETE" | "ASSIGN" | "RESOLVE";5 entityType: "ticket" | "user" | "comment";6 entityId: number;7 metadata: {8 previousValue?: unknown;9 newValue?: unknown;10 ipAddress: string;11 userAgent: string;12 };13 timestamp: Date;14}Dark Mode Implementation
The entire application supports both light and dark modes with persistent user preference:

text
1User Preference → localStorage → CSS Custom Properties →2Tailwind dark: Variants → Persistent ThemeKey Takeaways
- Separate AI from the request cycle — using Inngest for async processing keeps the API responsive
- Structured AI outputs via LangChain give predictable, type-safe results
- Role-based access needs careful planning — the permission matrix should be defined before feature development
- Audit logging is non-negotiable — every state change in a ticket system needs to be traceable
- Dark mode should be built in from day one — retrofitting it is significantly more expensive
Want to learn more about the TickMate architecture? Reach out through the contact form.
