{
    "openapi": "3.1.0",
    "info": {
        "title": "Laravel Helpdesk API Docs",
        "version": "1.0.0",
        "description": "# Laravel Helpdesk API\n\nPortfolio project built with Laravel 12.\n\nThis API includes:\n\n- authentication with Laravel Sanctum\n- ticket management\n- ticket comments\n- notifications\n- role-based access control\n- policy-based authorization\n\nUse the endpoints below to authenticate and work with the Helpdesk system."
    },
    "servers": [
        {
            "url": "https:\/\/helpdesk.rakitin.tech\/api"
        }
    ],
    "security": [
        {
            "http": []
        }
    ],
    "paths": {
        "\/auth\/register": {
            "post": {
                "operationId": "auth.register",
                "description": "Creates a customer account and returns a Sanctum bearer token. Auth responses intentionally keep the Postman-friendly shape { user, token }, with user normalized by UserResource. Validation errors are returned for missing fields, invalid or duplicate email addresses, weak passwords, and password confirmation mismatches.",
                "summary": "Register",
                "tags": [
                    "Auth"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "description": "Customer display name.",
                                        "example": "John Doe",
                                        "maxLength": 255
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "description": "Unique customer email address.",
                                        "example": "john@example.com",
                                        "maxLength": 255
                                    },
                                    "password": {
                                        "type": "string",
                                        "description": "Password with at least 8 characters. Must be confirmed by password_confirmation.",
                                        "example": "password123",
                                        "minLength": 8
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "description": "Must match password.",
                                        "example": "password123",
                                        "minLength": 8
                                    }
                                },
                                "required": [
                                    "name",
                                    "email",
                                    "password",
                                    "password_confirmation"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "user": {
                                            "$ref": "#\/components\/schemas\/UserResource"
                                        },
                                        "token": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "user",
                                        "token"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    }
                },
                "security": []
            }
        },
        "\/auth\/login": {
            "post": {
                "operationId": "auth.login",
                "description": "Authenticates a user, revokes previous API tokens for that user, and returns a new Sanctum bearer token. Auth responses intentionally keep the Postman-friendly shape { user, token }, with user normalized by UserResource. Invalid credentials return a 422 validation response on the email field.",
                "summary": "Login",
                "tags": [
                    "Auth"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "description": "Registered user email address.",
                                        "example": "qa-agent@example.com"
                                    },
                                    "password": {
                                        "type": "string",
                                        "description": "User password.",
                                        "example": "password"
                                    }
                                },
                                "required": [
                                    "email",
                                    "password"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "user": {
                                            "$ref": "#\/components\/schemas\/UserResource"
                                        },
                                        "token": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "user",
                                        "token"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    }
                },
                "security": []
            }
        },
        "\/auth\/me": {
            "get": {
                "operationId": "auth.me",
                "description": "Returns the authenticated user for a valid Sanctum bearer token. This auth response intentionally keeps the shape { user } instead of { data } so the existing Postman demo flow remains stable.",
                "summary": "Current user",
                "tags": [
                    "Auth"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "user": {
                                            "$ref": "#\/components\/schemas\/UserResource"
                                        }
                                    },
                                    "required": [
                                        "user"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    }
                }
            }
        },
        "\/auth\/logout": {
            "post": {
                "operationId": "auth.logout",
                "description": "Deletes the current Sanctum access token. The same bearer token cannot be used on protected endpoints after a successful logout.",
                "summary": "Logout",
                "tags": [
                    "Auth"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "const": "Logged out"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    }
                }
            }
        },
        "\/notifications": {
            "get": {
                "operationId": "notification.index",
                "description": "Returns notifications for the authenticated user only as { data: NotificationResource[] }.",
                "summary": "List notifications",
                "tags": [
                    "Notification"
                ],
                "responses": {
                    "200": {
                        "description": "Array of `NotificationResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#\/components\/schemas\/NotificationResource"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    }
                }
            }
        },
        "\/notifications\/{id}\/read": {
            "post": {
                "operationId": "notification.markAsRead",
                "description": "Marks one notification as read when it belongs to the authenticated user. Unknown notification IDs and notifications owned by another user return 404.",
                "summary": "Mark notification as read",
                "tags": [
                    "Notification"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "const": "Notification marked as read."
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#\/components\/responses\/ModelNotFoundException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    }
                }
            }
        },
        "\/tickets": {
            "get": {
                "operationId": "ticket.index",
                "description": "Returns tickets available to the authenticated user as { data: TicketResource[], meta }. Customers only see tickets they created. Agents and admins can see all tickets and can filter, search, sort, and paginate the result set. For agents and admins, mine=true limits the result to tickets assigned to the current user.",
                "summary": "List tickets",
                "tags": [
                    "Ticket"
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Filter by ticket status. Typical values: open, in_progress, closed.",
                        "schema": {
                            "$ref": "#\/components\/schemas\/TicketStatus"
                        },
                        "example": "open"
                    },
                    {
                        "name": "priority",
                        "in": "query",
                        "description": "Filter by ticket priority. Typical values: low, medium, high.",
                        "schema": {
                            "$ref": "#\/components\/schemas\/TicketPriority"
                        },
                        "example": "high"
                    },
                    {
                        "name": "assigned_to",
                        "in": "query",
                        "description": "Filter by assigned user ID. The ID must exist in users.",
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ]
                        },
                        "example": 2
                    },
                    {
                        "name": "mine",
                        "in": "query",
                        "description": "For agents and admins: when true, return only tickets assigned to the current user.",
                        "schema": {
                            "type": [
                                "boolean",
                                "null"
                            ]
                        },
                        "example": true
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Search by ticket title or description.",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 255
                        },
                        "example": "login issue"
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "description": "Sort field. Supported values in this endpoint: created_at, priority, status.",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "enum": [
                                "created_at",
                                "priority",
                                "status"
                            ]
                        },
                        "example": "priority"
                    },
                    {
                        "name": "direction",
                        "in": "query",
                        "description": "Sort direction. Supported values in this endpoint: asc, desc.",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        },
                        "example": "asc"
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "description": "Number of tickets per page.",
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "minimum": 1,
                            "maximum": 100
                        },
                        "example": 50
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated set of `TicketResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#\/components\/schemas\/TicketCollection"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "meta": {
                                                    "type": "object",
                                                    "properties": {
                                                        "current_page": {
                                                            "type": "integer",
                                                            "minimum": 1
                                                        },
                                                        "per_page": {
                                                            "type": "integer",
                                                            "description": "Number of items shown per page.",
                                                            "minimum": 0
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "description": "Total number of items being paginated.",
                                                            "minimum": 0
                                                        },
                                                        "last_page": {
                                                            "type": "integer",
                                                            "minimum": 1
                                                        }
                                                    },
                                                    "required": [
                                                        "current_page",
                                                        "per_page",
                                                        "total",
                                                        "last_page"
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "meta"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "$ref": "#\/components\/responses\/AuthorizationException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    }
                }
            },
            "post": {
                "operationId": "ticket.store",
                "description": "Creates a ticket for the authenticated user and returns { data: TicketResource }. The ticket starts with status open, and priority defaults to medium when omitted.",
                "summary": "Create ticket",
                "tags": [
                    "Ticket"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "$ref": "#\/components\/schemas\/StoreTicketRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`TicketResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#\/components\/schemas\/TicketResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    }
                }
            }
        },
        "\/tickets\/{ticket}": {
            "get": {
                "operationId": "ticket.show",
                "description": "Returns { data: TicketResource } when the ticket is visible to the authenticated user. Customers can view only their own tickets; agents and admins can view any ticket.",
                "summary": "Show ticket",
                "tags": [
                    "Ticket"
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "description": "The ticket ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`TicketResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#\/components\/schemas\/TicketResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "$ref": "#\/components\/responses\/AuthorizationException"
                    },
                    "404": {
                        "$ref": "#\/components\/responses\/ModelNotFoundException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    }
                }
            }
        },
        "\/tickets\/{ticket}\/assign": {
            "patch": {
                "operationId": "ticket.assign",
                "description": "Assigns a ticket to an agent and returns { data: TicketResource }. Only agents and admins can assign tickets. Customer accounts receive 403. The assignee ID must exist and must belong to an agent, otherwise the endpoint returns 422.",
                "summary": "Assign ticket",
                "tags": [
                    "Ticket"
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "description": "The ticket ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "$ref": "#\/components\/schemas\/AssignTicketRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`TicketResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#\/components\/schemas\/TicketResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    },
                    "404": {
                        "$ref": "#\/components\/responses\/ModelNotFoundException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    },
                    "403": {
                        "$ref": "#\/components\/responses\/AuthorizationException"
                    }
                }
            }
        },
        "\/tickets\/{ticket}\/status": {
            "patch": {
                "operationId": "ticket.changeStatus",
                "description": "Changes ticket status and returns { data: TicketResource }. Only agents and admins can change status. Customer accounts receive 403.",
                "summary": "Change ticket status",
                "tags": [
                    "Ticket"
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "description": "The ticket ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "$ref": "#\/components\/schemas\/ChangeTicketStatusRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`TicketResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#\/components\/schemas\/TicketResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#\/components\/responses\/ModelNotFoundException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    },
                    "403": {
                        "$ref": "#\/components\/responses\/AuthorizationException"
                    }
                }
            }
        },
        "\/tickets\/{ticket}\/comments": {
            "get": {
                "operationId": "ticketComment.index",
                "description": "Returns comments for a ticket visible to the authenticated user as { data: TicketCommentResource[] }. Customers can list comments only for their own tickets; agents and admins can list comments for any ticket.",
                "summary": "List ticket comments",
                "tags": [
                    "TicketComment"
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "description": "The ticket ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Array of `TicketCommentResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#\/components\/schemas\/TicketCommentResource"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "$ref": "#\/components\/responses\/AuthorizationException"
                    },
                    "404": {
                        "$ref": "#\/components\/responses\/ModelNotFoundException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    }
                }
            },
            "post": {
                "operationId": "ticketComment.store",
                "description": "Adds a comment to a visible ticket and returns { data: TicketCommentResource }. Customers can comment only on their own tickets; agents and admins can comment on any ticket. The ticket creator and assignee are notified except for the comment author.",
                "summary": "Create ticket comment",
                "tags": [
                    "TicketComment"
                ],
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "description": "The ticket ID",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "$ref": "#\/components\/schemas\/StoreTicketCommentRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`TicketCommentResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#\/components\/schemas\/TicketCommentResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#\/components\/responses\/ModelNotFoundException"
                    },
                    "401": {
                        "$ref": "#\/components\/responses\/AuthenticationException"
                    },
                    "422": {
                        "$ref": "#\/components\/responses\/ValidationException"
                    },
                    "403": {
                        "$ref": "#\/components\/responses\/AuthorizationException"
                    }
                }
            }
        },
        "\/users": {
            "get": {
                "operationId": "user.index",
                "description": "Returns a paginated list of users as { data: UserResource[], meta }. Only admins can list users. Agent and customer accounts receive 403.",
                "summary": "List users",
                "tags": [
                    "User"
                ],
                "parameters": [
                    {
                        "name": "per_page",
                        "in": "query",
                        "description": "Number of users per page.",
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "minimum": 1,
                            "maximum": 100
                        },
                        "example": 50
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated set of `UserResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#\/components\/schemas\/UserCollection"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "meta": {
                                                    "type": "object",
                                                    "properties": {
                                                        "current_page": {
                                                            "type": "integer",
                                                            "minimum": 1
                                                        },
                                                        "per_page": {
                                                            "type": "integer",
                                                            "description": "Number of items shown per page.",
                                                            "minimum": 0
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "description": "Total number of items being paginated.",
                                                            "minimum": 0
                                                        },
                                                        "last_page": {
                                                            "type": "integer",
                                                            "minimum": 1
                                                        }
                                                    },
                                                    "required": [
                                                        "current_page",
                                                        "per_page",
                                                        "total",
                                                        "last_page"
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "meta"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated. A valid Sanctum bearer token is required.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "Error overview."
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error. The pagination query parameters are invalid.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "Errors overview."
                                        },
                                        "errors": {
                                            "type": "object",
                                            "description": "A detailed description of each field that failed validation.",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden. Only admin users can list users.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "Error overview."
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "\/users\/{user}\/role": {
            "patch": {
                "operationId": "user.changeRole",
                "description": "Changes a user role and returns { data: UserResource }. Only admins can change roles. The role must be admin, agent, or customer. The endpoint refuses changes that would leave the system with zero admin users.",
                "summary": "Change user role",
                "tags": [
                    "User"
                ],
                "parameters": [
                    {
                        "name": "user",
                        "in": "path",
                        "required": true,
                        "description": "User ID.",
                        "schema": {
                            "type": "integer"
                        },
                        "example": 3
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application\/json": {
                            "schema": {
                                "$ref": "#\/components\/schemas\/ChangeUserRoleRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`UserResource`",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#\/components\/schemas\/UserResource"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated. A valid Sanctum bearer token is required.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "Error overview."
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error. The role is invalid or the change would remove the last admin.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "Errors overview."
                                        },
                                        "errors": {
                                            "type": "object",
                                            "description": "A detailed description of each field that failed validation.",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden. Only admin users can change roles.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "Error overview."
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found. The requested user does not exist.",
                        "content": {
                            "application\/json": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "http": {
                "type": "http",
                "scheme": "bearer"
            }
        },
        "schemas": {
            "AssignTicketRequest": {
                "type": "object",
                "properties": {
                    "assigned_to": {
                        "type": "integer",
                        "description": "Existing agent user ID.",
                        "example": 2
                    }
                },
                "required": [
                    "assigned_to"
                ],
                "title": "AssignTicketRequest"
            },
            "ChangeTicketStatusRequest": {
                "type": "object",
                "properties": {
                    "status": {
                        "description": "New ticket status.",
                        "example": "in_progress",
                        "$ref": "#\/components\/schemas\/TicketStatus"
                    }
                },
                "required": [
                    "status"
                ],
                "title": "ChangeTicketStatusRequest"
            },
            "ChangeUserRoleRequest": {
                "type": "object",
                "properties": {
                    "role": {
                        "description": "New role for the user. Supported values: admin, agent, customer.",
                        "example": "agent",
                        "$ref": "#\/components\/schemas\/UserRole"
                    }
                },
                "required": [
                    "role"
                ],
                "title": "ChangeUserRoleRequest"
            },
            "NotificationResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string"
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "ticket_id": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "ticket_title": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "comment_id": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "comment_body": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "comment_author_id": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "ticket_id",
                            "ticket_title",
                            "comment_id",
                            "comment_body",
                            "comment_author_id"
                        ]
                    },
                    "read_at": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "id",
                    "type",
                    "data",
                    "read_at",
                    "created_at"
                ],
                "title": "NotificationResource"
            },
            "StoreTicketCommentRequest": {
                "type": "object",
                "properties": {
                    "body": {
                        "type": "string",
                        "description": "Comment body.",
                        "example": "I can reproduce this issue."
                    }
                },
                "required": [
                    "body"
                ],
                "title": "StoreTicketCommentRequest"
            },
            "StoreTicketRequest": {
                "type": "object",
                "properties": {
                    "title": {
                        "type": "string",
                        "description": "Ticket title.",
                        "example": "Cannot sign in",
                        "maxLength": 255
                    },
                    "description": {
                        "type": "string",
                        "description": "Detailed problem description.",
                        "example": "Login fails after password reset."
                    },
                    "priority": {
                        "description": "Ticket priority. Defaults to medium when omitted.",
                        "example": "high",
                        "$ref": "#\/components\/schemas\/TicketPriority"
                    }
                },
                "required": [
                    "title",
                    "description"
                ],
                "title": "StoreTicketRequest"
            },
            "TicketCollection": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#\/components\/schemas\/TicketResource"
                        }
                    }
                },
                "required": [
                    "data"
                ],
                "title": "TicketCollection"
            },
            "TicketCommentResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "ticket_id": {
                        "type": "integer"
                    },
                    "user_id": {
                        "type": "integer"
                    },
                    "body": {
                        "type": "string"
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "author": {
                        "$ref": "#\/components\/schemas\/UserResource"
                    }
                },
                "required": [
                    "id",
                    "ticket_id",
                    "user_id",
                    "body",
                    "created_at",
                    "updated_at"
                ],
                "title": "TicketCommentResource"
            },
            "TicketPriority": {
                "type": "string",
                "enum": [
                    "low",
                    "medium",
                    "high"
                ],
                "title": "TicketPriority"
            },
            "TicketResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "title": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string"
                    },
                    "status": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "$ref": "#\/components\/schemas\/TicketStatus"
                            }
                        ]
                    },
                    "priority": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "$ref": "#\/components\/schemas\/TicketPriority"
                            }
                        ]
                    },
                    "created_by": {
                        "type": "integer"
                    },
                    "assigned_to": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "title",
                    "description",
                    "status",
                    "priority",
                    "created_by",
                    "assigned_to",
                    "created_at",
                    "updated_at"
                ],
                "title": "TicketResource"
            },
            "TicketStatus": {
                "type": "string",
                "enum": [
                    "open",
                    "in_progress",
                    "closed"
                ],
                "title": "TicketStatus"
            },
            "UserCollection": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#\/components\/schemas\/UserResource"
                        }
                    }
                },
                "required": [
                    "data"
                ],
                "title": "UserCollection"
            },
            "UserResource": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "role": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "$ref": "#\/components\/schemas\/UserRole"
                            }
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "name",
                    "email",
                    "role",
                    "created_at",
                    "updated_at"
                ],
                "title": "UserResource"
            },
            "UserRole": {
                "type": "string",
                "enum": [
                    "admin",
                    "agent",
                    "customer"
                ],
                "title": "UserRole"
            }
        },
        "responses": {
            "ValidationException": {
                "description": "Validation error",
                "content": {
                    "application\/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Errors overview."
                                },
                                "errors": {
                                    "type": "object",
                                    "description": "A detailed description of each field that failed validation.",
                                    "additionalProperties": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                }
                            },
                            "required": [
                                "message",
                                "errors"
                            ]
                        }
                    }
                }
            },
            "AuthenticationException": {
                "description": "Unauthenticated",
                "content": {
                    "application\/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Error overview."
                                }
                            },
                            "required": [
                                "message"
                            ]
                        }
                    }
                }
            },
            "AuthorizationException": {
                "description": "Authorization error",
                "content": {
                    "application\/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Error overview."
                                }
                            },
                            "required": [
                                "message"
                            ]
                        }
                    }
                }
            },
            "ModelNotFoundException": {
                "description": "Not found",
                "content": {
                    "application\/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Error overview."
                                }
                            },
                            "required": [
                                "message"
                            ]
                        }
                    }
                }
            }
        }
    }
}