Skip to main content

Design a Customer Issue Resolution System

Problem Statement

Design a customer issue resolution system where customers can raise issues related to products or services, and support agents can resolve them within a defined lifecycle. The system should ensure proper assignment, tracking, and status updates until the issue is fully resolved.


Functional Requirements

  • Customers should be able to raise issues
  • Each issue should have a lifecycle (OPEN → IN_PROGRESS → RESOLVED → CLOSED)
  • Issues should be assigned to support agents
  • Agents should update issue status
  • System should support priority levels
  • Issues should maintain full history of resolution flow

Objects Required

  • Customer
  • SupportAgent
  • Issue
  • IssueService
  • IssueStatus Enum
  • Priority Enum

IssueStatus Enum


public enum IssueStatus {
    OPEN,
    IN_PROGRESS,
    RESOLVED,
    CLOSED
}

This enum defines the lifecycle of an issue and ensures consistent state transitions instead of free-form strings.


Priority Enum


public enum Priority {
    LOW,
    MEDIUM,
    HIGH,
    CRITICAL
}

Priority helps the system decide urgency and SLA handling for each issue.


Customer Class


public class Customer {

    private String customerId;
    private String name;

    public Customer(String customerId, String name) {
        this.customerId = customerId;
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Customer represents a user who can raise issues in the system.


SupportAgent Class


public class SupportAgent {

    private String agentId;
    private String name;

    public SupportAgent(String agentId, String name) {
        this.agentId = agentId;
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

SupportAgent represents a service executive responsible for resolving customer issues.


Issue Class


import java.util.*;

public class Issue {

    private String issueId;
    private String description;
    private Customer customer;
    private SupportAgent assignedAgent;
    private IssueStatus status;
    private Priority priority;
    private List history;

    public Issue(String issueId, String description, Customer customer, Priority priority) {
        this.issueId = issueId;
        this.description = description;
        this.customer = customer;
        this.priority = priority;
        this.status = IssueStatus.OPEN;
        this.history = new ArrayList<>();
        this.history.add("Issue created");
    }

    public void assignAgent(SupportAgent agent) {
        this.assignedAgent = agent;
        this.status = IssueStatus.IN_PROGRESS;
        history.add("Assigned to agent: " + agent.getName());
    }

    public void resolveIssue() {
        this.status = IssueStatus.RESOLVED;
        history.add("Issue resolved");
    }

    public void closeIssue() {
        this.status = IssueStatus.CLOSED;
        history.add("Issue closed");
    }

    public List getHistory() {
        return history;
    }
}

The Issue class is the core entity that tracks problem details, customer info, agent assignment, status, and full lifecycle history.

The constructor initializes a new issue in OPEN state and records its creation in history.

The assignAgent() method assigns a support agent and moves the issue into IN_PROGRESS state.

The resolveIssue() method marks the issue as RESOLVED and records the action.

The closeIssue() method finalizes the issue lifecycle.


IssueService Class


import java.util.*;

public class IssueService {

    private Map issueStore = new HashMap<>();

    public void createIssue(Issue issue) {
        issueStore.put(issue.toString(), issue);
    }

    public void assignIssue(String issueId, SupportAgent agent) {
        for (Issue issue : issueStore.values()) {
            if (issue.toString().equals(issueId)) {
                issue.assignAgent(agent);
            }
        }
    }

    public void resolveIssue(String issueId) {
        for (Issue issue : issueStore.values()) {
            if (issue.toString().equals(issueId)) {
                issue.resolveIssue();
            }
        }
    }

    public void closeIssue(String issueId) {
        for (Issue issue : issueStore.values()) {
            if (issue.toString().equals(issueId)) {
                issue.closeIssue();
            }
        }
    }
}

IssueService acts as the orchestration layer that manages issue lifecycle operations like creation, assignment, resolution, and closure.

It maintains an in-memory store of issues for quick retrieval and updates.


Main Class


public class Main {

    public static void main(String[] args) {

        Customer customer = new Customer("C1", "Alice");

        SupportAgent agent = new SupportAgent("A1", "John");

        Issue issue = new Issue(
            "I1",
            "Payment not processed",
            customer,
            Priority.HIGH
        );

        IssueService service = new IssueService();

        service.createIssue(issue);

        service.assignIssue("I1", agent);
        service.resolveIssue("I1");
        service.closeIssue("I1");

        System.out.println(issue.getHistory());
    }
}

Class Diagram

CustomercustomerId: Stringname: StringgetName(): StringSupportAgentagentId: Stringname: StringgetName(): StringIssueissueId: Stringdescription: Stringcustomer: CustomerassignedAgent: SupportAgentstatus: IssueStatuspriority: Priorityhistory: List<String>assignAgent(agent: SupportAgent): voidresolveIssue(): voidcloseIssue(): voidgetHistory(): List<String>IssueServiceissueStore: Map<String, Issue>createIssue(issue: Issue): voidassignIssue(issueId: String, agent: SupportAgent): voidresolveIssue(issueId: String): voidcloseIssue(issueId: String): voidIssueStatusOPENIN_PROGRESSRESOLVEDCLOSEDPriorityLOWMEDIUMHIGHCRITICAL1many1many

Also See

Comments

Popular posts from this blog

Designing a Parking Lot - Low Level Design

Problem Statement Design a parking lot that can handle vehicles entering and leaving while managing parking across multiple floors. Each vehicle should be assigned a suitable parking spot based on its type, and the spot should be freed once the vehicle exits. The design should also support generating a ticket at entry and optionally calculating the parking fee based on the duration of stay. Asked In Companies Amazon Google Microsoft Uber Walmart Flipkart Meta PayPal Oracle Salesforce Adobe Apple Intuit LinkedIn Atlassian Functional Requirements The design should support multiple vehicle types such as bikes, cars, and trucks A vehicle must be assigned a parking spot compatible with its type A parking spot cannot be assigned to more than one vehicle at a time The parking lot should support multiple levels (floors) The design should search and allocate an availa...

Most Frequently Asked Low Level Design(LLD) Interview Questions

Below are the curated list of most commonly asked Low Level Design (LLD) interview problems. Each problem includes a short description and a link to the complete solution with code and class diagrams. Design Parking Lot System The system should handle parking for different vehicle types such as bikes, cars, and trucks. It should manage slot allocation, availability tracking, and entry/exit flow. The design also ensures efficient usage of parking space under varying load conditions. View Solution Design Elevator / Lift System The system should support multiple elevators operating across floors with request handling logic. It focuses on scheduling algorithms to minimize wait time and optimize movement. It also manages direction control and concurrent floor requests. View Solution Design Movie Ticket Booking System The system should allow users to browse movies, select shows, and book seats. It handles seat ...

Software Design Patterns for LLD Interviews: A Complete Guide

Software Design Patterns for LLD Interviews: A Complete Guide In Software Development Engineer (SDE) interviews—especially for mid-level and senior roles—low-level design (LLD) rounds assess your ability to write clean, reusable, maintainable, and extensible code. The foundation of resolving these architectural challenges lies in the standard Gang of Four (GoF) Design Patterns. Rather than memorizing theoretical definitions, interviewers expect you to apply these patterns to real-world scenarios, identifying the trade-offs of each. Below is a comprehensive guide to the 12 most frequently asked design patterns in LLD interviews, categorized by their classification (Creational, Structural, and Behavioral). Each pattern contains a concrete, real-world Java implementation and a detailed breakdown of design decisions. Creational Design Patterns Creational design patterns deal with object creation mechanisms. They abstract the instantiation process, making a system independent of how...