Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Ticket System

Ticket System provides structured two-way communication between users and administrators for customer support. Each ticket is a conversation thread with lifecycle management, priority levels, and automatic status transitions based on message activity.

Core Concept

A Ticket represents:

  • Conversation thread: Series of messages between a user and admin team
  • Priority: Low, Medium, or High (set by user at creation, helps admins triage)
  • Status: Open, Pending, Resolved, or Closed (automatically transitions based on activity)
  • Ownership: Tied to a specific user; only that user and admins can access it
  • Title: Brief description for quick identification in ticket lists

Ticket Lifecycle

Status States

  1. Open: User has sent a message, awaiting admin response
  2. Pending: Admin has replied, awaiting user feedback
  3. Resolved: Admin has marked the issue as resolved
  4. Closed: Ticket is archived, no further messages allowed

Automatic Transitions

Status changes automatically based on who sends messages:

  • User sends message → Open (even if previously Pending or Resolved)
  • Admin replies to Open ticket → Pending
  • Admin manually resolves → Resolved
  • Admin manually closes → Closed

This state machine ensures tickets naturally reflect their support workflow without manual status management for most interactions.

Message Restrictions

  • Resolved/Closed tickets: Cannot receive new messages
  • Open/Pending tickets: Both users and admins can send messages
  • Users can only edit their own messages; admins can only edit their own messages
  • Admins can only delete their own messages (not for general moderation)

Architecture

Dual Service Design

The module exposes two separate gRPC services:

SupportService (User-facing):

  • Create tickets
  • List own tickets
  • View ticket details (ownership validated)
  • Send and edit own messages
  • Close own tickets

SupportAdminService (Admin-facing):

  • List all tickets (with pagination and optional unreplied filter)
  • View any ticket detail
  • Send admin responses
  • Edit own messages
  • Delete own messages
  • Manually close or resolve tickets

This separation ensures clear permission boundaries and prevents accidental exposure of admin capabilities.

RBAC and Audit Logging

Admin operations integrate with the manage module’s RBAC system:

  • Allowed Roles: SuperAdmin, Moderator, CustomerSupport, and SupportBot
  • Audit Trail: All admin operations are logged with operation name, target, and input parameters
  • Authorization: Role verification happens before operation execution via AdminOperation trait

Message Threading

Messages within a ticket follow these rules:

  • Dual-author model: Each message has either user_author_id OR admin_author_id (never both)
  • Edit tracking: edited_at timestamp records when a message was last modified
  • Author metadata:
    • User-facing API returns FrontendTicketMessage with enriched author data (name, avatar, email) joined from auth tables
    • Admin-facing API returns plain TicketMessage objects without enriched metadata
  • Sequential IDs: Messages use auto-incrementing integers for efficient database operations

Message Retrieval

Messages are returned with a simple limit-based approach:

  • Default Limit: 100 messages per request
  • Ordering: Messages are ordered by sent_at timestamp in descending order (newest first)
  • No Pagination: Currently, there is no pagination support; all messages up to the limit are returned at once

Access Control

User Permissions

  • Users can only view tickets they created (validated by user_id match)
  • Users can only edit messages they authored
  • Ticket ownership is checked on every operation (list, view, send message)
  • Failed ownership checks return empty results or permission denied errors

Admin Permissions

  • Admins can access all tickets through SupportAdminService
  • Admin permissions are verified through the manage module’s RBAC system
  • Admins can perform operations like viewing all tickets, sending responses, and manually changing ticket status
  • Admins can only edit or delete their own messages (ownership is checked)

Validation Layer

Input validation includes:

  • Title validation: Non-empty, length limits (enforced at gRPC layer)
  • Content validation: Non-empty, length limits for messages (enforced at gRPC layer)
  • Ownership checks: Service-level validation verifies user owns the ticket/message before operations

Integration Points

Auth Module

  • Ticket user_id references users from auth module
  • User authentication context flows through auth::rpc::middleware::UserId for user operations
  • Admin authentication flows through manage::rpc::middleware::AdminId for admin operations

Database Schema

Lives in support PostgreSQL schema:

  • ticket table: Core ticket data with custom enums for priority and status
  • ticket_message table: Messages with dual-author columns
  • Foreign keys to auth module’s user tables for referential integrity

Development Notes

  • Ticket IDs are UUIDs for global uniqueness
  • Message IDs are integers for simpler database management
  • All service operations use the Processor pattern
  • Status transition logic is implemented in TicketStatus enum methods (on_user_message(), on_admin_reply())
  • Status transitions happen automatically within the CreateTicketMessage database transaction
  • User-facing API gets enriched message data (FrontendTicketMessage) with author metadata joined from user/admin tables
  • Admin operations use the impl_recorded_admin_processor! macro for automatic audit logging
  • Admin message edit/delete operations enforce ownership validation at the service layer