Appearance
Ticket Model
This document provides a detailed technical overview of the Ticket data model, its associated enumerations, validation rules, and data transfer objects (DTOs). It is intended for developers responsible for maintaining and extending the ticketing functionality.
The Ticket is the central entity in the ticketing system, representing a single request or issue reported by a user.
Ticket Entity
The Ticket entity is a JPA-managed object that maps directly to the tickets table in the MySQL database. It serves as the single source of truth for all ticket-related data within the application.
The entity is defined in the com.slalom.demo.ticketing.model.Ticket class. It leverages Lombok annotations (@Data, @Builder, @NoArgsConstructor, @AllArgsConstructor) to reduce boilerplate code for getters, setters, constructors, and builder methods.
Fields and Database Mapping
The following table details each field in the Ticket entity, its Java type, corresponding database column, and applied constraints.
| Field Name | Java Type | Database Column | Annotations & Constraints | Description |
|---|---|---|---|---|
id | Long | id | @Id, @GeneratedValue(strategy = GenerationType.IDENTITY) | The primary key for the ticket. The value is auto-generated by the database's identity column feature (e.g., AUTO_INCREMENT in MySQL). |
title | String | title | @NotBlank, @Column(nullable = false) | A concise summary of the ticket. Cannot be null or empty. |
description | String | description | @NotBlank, @Column(nullable = false, length = 2000) | A detailed description of the issue or request. Cannot be null or empty. The database column has a max length of 2000 characters. |
status | TicketStatus | status | @NotNull, @Enumerated(EnumType.STRING), @Column(nullable = false) | The current status of the ticket. Stored as a string (e.g., "OPEN", "CLOSED") in the database for readability and robustness. |
priority | TicketPriority | priority | @NotNull, @Enumerated(EnumType.STRING), @Column(nullable = false) | The priority level of the ticket. Stored as a string (e.g., "LOW", "HIGH") in the database. |
requesterEmail | String | requester_email | @NotBlank, @Column(nullable = false) | The email address of the user who created the ticket. |
assignedTo | String | assigned_to | @Column | The user or team member to whom the ticket is assigned. This field is optional and can be null. |
createdAt | LocalDateTime | created_at | @CreationTimestamp, @Column(nullable = false, updatable = false) | The timestamp when the ticket was created. Automatically set by Hibernate upon entity creation and cannot be updated. |
updatedAt | LocalDateTime | updated_at | @UpdateTimestamp, @Column(nullable = false) | The timestamp of the last update to the ticket. Automatically managed by Hibernate on every update. |
resolvedAt | LocalDateTime | resolved_at | @Column | The timestamp when the ticket's status was moved to RESOLVED. This field is nullable and must be set manually by the application's business logic. |
Source Code
java
// src/main/java/com/slalom/demo/ticketing/model/Ticket.java
package com.slalom.demo.ticketing.model;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
@Entity
@Table(name = "tickets")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Ticket {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "Title is required")
@Column(nullable = false)
private String title;
@NotBlank(message = "Description is required")
@Column(nullable = false, length = 2000)
private String description;
@NotNull(message = "Status is required")
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private TicketStatus status;
@NotNull(message = "Priority is required")
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private TicketPriority priority;
@Column(name = "requester_email", nullable = false)
@NotBlank(message = "Requester email is required")
private String requesterEmail;
@Column(name = "assigned_to")
private String assignedTo;
@CreationTimestamp
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
@Column(name = "resolved_at")
private LocalDateTime resolvedAt;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Developer Note: The use of
@CreationTimestampand@UpdateTimestampdelegates timestamp management to the persistence layer (Hibernate). This ensures consistency and removes the need for manual handling in the service layer. However, theresolvedAttimestamp must be explicitly set within the business logic when a ticket's status transitions toRESOLVED.
Ticket Status
The TicketStatus enumeration defines the lifecycle of a ticket. It is crucial for tracking progress and driving workflows.
The enum is defined in com.slalom.demo.ticketing.model.TicketStatus.
| Status | Description |
|---|---|
OPEN | The initial state of a newly created ticket. It is awaiting assignment and review. |
IN_PROGRESS | The ticket has been assigned and is actively being worked on by an agent. |
WAITING_ON_CUSTOMER | Work is paused pending a response or additional information from the requester. |
RESOLVED | The issue has been fixed or the request has been fulfilled. The solution is pending confirmation from the requester. |
CLOSED | The ticket is considered complete. This is the final state in the lifecycle. |
Source Code
java
// src/main/java/com/slalom/demo/ticketing/model/TicketStatus.java
package com.slalom.demo.ticketing.model;
public enum TicketStatus {
OPEN,
IN_PROGRESS,
WAITING_ON_CUSTOMER,
RESOLVED,
CLOSED
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Ticket Priority
The TicketPriority enumeration is used to classify the urgency of a ticket, which can influence response times and service-level agreements (SLAs).
The enum is defined in com.slalom.demo.ticketing.model.TicketPriority.
| Priority | Description |
|---|---|
LOW | Non-urgent issues or requests that can be addressed during normal maintenance cycles. |
MEDIUM | The default priority for most tickets, representing standard operational issues. |
HIGH | Urgent issues that impact business operations but are not system-critical. Requires prompt attention. |
CRITICAL | System-critical issues causing a service outage or significant business disruption. Requires immediate attention. |
Source Code
java
// src/main/java/com/slalom/demo/ticketing/model/TicketPriority.java
package com.slalom.demo.ticketing.model;
public enum TicketPriority {
LOW,
MEDIUM,
HIGH,
CRITICAL
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Data Validation
Data validation is enforced at the API boundary using a Data Transfer Object (TicketRequest) to ensure that incoming data is well-formed before it reaches the service layer. This is handled by the spring-boot-starter-validation module, which uses the Jakarta Bean Validation API.
API Input Validation (TicketRequest)
The TicketRequest DTO defines the contract for creating or updating a ticket. Validation annotations are applied directly to its fields.
| Field | Constraint | Message |
|---|---|---|
title | @NotBlank | "Title is required" |
description | @NotBlank | "Description is required" |
status | @NotNull | "Status is required" |
priority | @NotNull | "Priority is required" |
requesterEmail | @NotBlank | "Requester email is required" |
requesterEmail | @Email | "Invalid email format" |
When a controller endpoint receives a TicketRequest object annotated with @Valid, Spring Boot automatically triggers the validation process. If validation fails, a MethodArgumentNotValidException is thrown, which is typically handled by a global exception handler to return a 400 Bad Request response with detailed error messages.
Source Code
java
// src/main/java/com/slalom/demo/ticketing/dto/TicketRequest.java
package com.slalom.demo.ticketing.dto;
import com.slalom.demo.ticketing.model.TicketPriority;
import com.slalom.demo.ticketing.model.TicketStatus;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TicketRequest {
@NotBlank(message = "Title is required")
private String title;
@NotBlank(message = "Description is required")
private String description;
@NotNull(message = "Status is required")
private TicketStatus status;
@NotNull(message = "Priority is required")
private TicketPriority priority;
@NotBlank(message = "Requester email is required")
@Email(message = "Invalid email format")
private String requesterEmail;
private String assignedTo;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Data Transfer Objects (DTOs)
The application uses the DTO pattern to decouple the API's public contract from the internal database entity. This provides flexibility and prevents exposing internal implementation details.
TicketRequest
Used for incoming create and update operations. It contains only the fields a client is allowed to provide. It notably excludes system-managed fields like id and timestamps.
TicketResponse
Used for all outgoing responses (e.g., GET /tickets/{id}, POST /tickets). It represents a complete view of the ticket, including the generated id and all timestamps (createdAt, updatedAt, resolvedAt). This ensures clients receive a full and consistent representation of the resource.
java
// src/main/java/com/slalom/demo/ticketing/dto/TicketResponse.java
package com.slalom.demo.ticketing.dto;
import com.slalom.demo.ticketing.model.TicketPriority;
import com.slalom.demo.ticketing.model.TicketStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TicketResponse {
private Long id;
private String title;
private String description;
private TicketStatus status;
private TicketPriority priority;
private String requesterEmail;
private String assignedTo;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime resolvedAt;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Related Documentation
- API Reference: Tickets: For details on the RESTful API endpoints used to create, read, update, and delete tickets.
- API Reference: Data Models: For a comprehensive overview of all API request and response models.
- Development: Database Schema: For detailed information on the
ticketstable structure and its relationships within the database.