PhoenixKit.Modules.Tickets (phoenix_kit v1.7.43)

Copy Markdown View Source

Context for managing support tickets, comments, and attachments.

Provides complete API for the customer support ticketing system including CRUD operations, status workflow, comment threading with internal notes, file attachments, and audit trail.

Features

  • Ticket Management: Create, update, delete tickets
  • Status Workflow: open → in_progress → resolved → closed
  • Assignment: Assign tickets to support staff
  • Comment System: Public comments and internal notes
  • File Attachments: Multiple files per ticket/comment
  • Audit Trail: Complete status change history

Status Flow

  • open - New ticket, awaiting assignment or response
  • in_progress - Being worked on by support staff
  • resolved - Issue resolved, awaiting confirmation
  • closed - Ticket closed (resolved or abandoned)

Examples

# Create a ticket
{:ok, ticket} = Tickets.create_ticket(user_id, %{
  title: "Cannot login",
  description: "I get an error when trying to login..."
})

# Assign to support staff
{:ok, ticket} = Tickets.assign_ticket(ticket, staff_user_id, current_user)

# Start working on it
{:ok, ticket} = Tickets.start_progress(ticket, current_user)

# Add a public comment
{:ok, comment} = Tickets.create_comment(ticket.uuid, staff_user_id, %{
  content: "We're looking into this issue."
})

# Add an internal note (hidden from customer)
{:ok, note} = Tickets.create_internal_note(ticket.uuid, staff_user_id, %{
  content: "Customer seems frustrated. Need to escalate."
})

# Resolve the ticket
{:ok, ticket} = Tickets.resolve_ticket(ticket, current_user, "Fixed in v2.0.1")

Summary

Functions

Assigns a ticket to a support staff member.

Creates a public comment on a ticket.

Creates an internal note on a ticket (visible only to support staff).

Creates a new ticket.

Deletes a comment.

Deletes a ticket and all related data.

Disables the Tickets module.

Enables the Tickets module.

Checks if the Tickets module is enabled.

Gets a comment by ID.

Gets the current Tickets module configuration and stats.

Gets ticket statistics.

Gets the status history for a ticket.

Gets a single ticket by ID. Returns nil if not found.

Gets a single ticket by ID with optional preloads.

Gets a single ticket by slug.

Lists all comments for a ticket (includes internal notes). For staff use only.

Lists attachments for a comment.

Lists only internal notes for a ticket.

Lists public comments for a ticket (excludes internal notes).

Lists attachments for a ticket.

Lists tickets with optional filtering and pagination.

Lists tickets assigned to a specific handler.

Lists unassigned tickets (where assigned_to_id is nil).

Lists tickets created by a specific user.

Removes an attachment.

Reopens a closed or resolved ticket.

Moves ticket to in_progress status.

Updates a comment.

Updates an existing ticket.

Functions

add_attachment_to_comment(comment_id, file_id, opts \\ [])

Attaches a file to a comment.

add_attachment_to_ticket(ticket_id, file_id, opts \\ [])

Attaches a file to a ticket.

Parameters

  • ticket_id - ID of the ticket
  • file_id - ID of the uploaded file
  • opts - Options
    • :position - Display order (default: auto-calculated)
    • :caption - Optional caption

Examples

iex> add_attachment_to_ticket(ticket.uuid, file.uuid, caption: "Error screenshot")
{:ok, %TicketAttachment{}}

assign_ticket(ticket, handler_id, changed_by)

Assigns a ticket to a support staff member.

If the ticket is open, it will be moved to in_progress.

Parameters

  • ticket - Ticket to assign
  • handler_id - User ID of the support staff
  • changed_by - User making the change

Examples

iex> assign_ticket(ticket, 5, current_user)
{:ok, %Ticket{assigned_to_id: 5}}

close_ticket(ticket, changed_by, reason \\ nil)

Closes a ticket.

Parameters

  • ticket - Ticket to close
  • changed_by - User making the change
  • reason - Optional close reason

Examples

iex> close_ticket(ticket, current_user, "No response from customer")
{:ok, %Ticket{status: "closed"}}

create_comment(ticket_id, user_id, attrs)

Creates a public comment on a ticket.

Parameters

  • ticket_id - ID of the ticket
  • user_id - ID of the commenter
  • attrs - Comment attributes (content, optional parent_id)

Examples

iex> create_comment(ticket.uuid, user_id, %{content: "Thanks for looking into this!"})
{:ok, %TicketComment{}}

create_internal_note(ticket_id, user_id, attrs)

Creates an internal note on a ticket (visible only to support staff).

Parameters

  • ticket_id - ID of the ticket
  • user_id - ID of the staff member
  • attrs - Note attributes (content)

Examples

iex> create_internal_note(ticket.uuid, staff_id, %{content: "Customer seems frustrated"})
{:ok, %TicketComment{is_internal: true}}

create_ticket(user_id, attrs)

Creates a new ticket.

Parameters

  • user_id - Customer who created the ticket
  • attrs - Ticket attributes (title, description)

Examples

iex> create_ticket(42, %{title: "Bug report", description: "Something is wrong"})
{:ok, %Ticket{}}

iex> create_ticket(42, %{title: ""})
{:error, %Ecto.Changeset{}}

delete_comment(comment)

Deletes a comment.

delete_ticket(ticket)

Deletes a ticket and all related data.

Parameters

  • ticket - Ticket struct to delete

Examples

iex> delete_ticket(ticket)
{:ok, %Ticket{}}

disable_system()

Disables the Tickets module.

Examples

iex> disable_system()
{:ok, %Setting{}}

enable_system()

Enables the Tickets module.

Examples

iex> enable_system()
{:ok, %Setting{}}

enabled?()

Checks if the Tickets module is enabled.

Examples

iex> enabled?()
false

get_comment!(id, opts \\ [])

Gets a comment by ID.

get_config()

Gets the current Tickets module configuration and stats.

Examples

iex> get_config()
%{enabled: false, total_tickets: 0, open_tickets: 0, ...}

get_stats()

Gets ticket statistics.

get_status_history(ticket_id, opts \\ [])

Gets the status history for a ticket.

get_ticket(id, opts \\ [])

Gets a single ticket by ID. Returns nil if not found.

get_ticket!(id, opts \\ [])

Gets a single ticket by ID with optional preloads.

Raises Ecto.NoResultsError if ticket not found.

Parameters

  • id - Ticket ID (UUIDv7)
  • opts - Options
    • :preload - List of associations to preload

Examples

iex> get_ticket!("018e3c4a-...")
%Ticket{}

iex> get_ticket!("018e3c4a-...", preload: [:user, :assigned_to, :comments])
%Ticket{user: %User{}, assigned_to: %User{}, comments: [...]}

get_ticket_by_slug(slug, opts \\ [])

Gets a single ticket by slug.

Parameters

  • slug - Ticket slug
  • opts - Options
    • :preload - List of associations to preload

Examples

iex> get_ticket_by_slug("cannot-login-123456")
%Ticket{}

list_all_comments(ticket_id, opts \\ [])

Lists all comments for a ticket (includes internal notes). For staff use only.

list_comment_attachments(comment_id, opts \\ [])

Lists attachments for a comment.

list_internal_notes(ticket_id, opts \\ [])

Lists only internal notes for a ticket.

list_public_comments(ticket_id, opts \\ [])

Lists public comments for a ticket (excludes internal notes).

list_ticket_attachments(ticket_id, opts \\ [])

Lists attachments for a ticket.

list_tickets(opts \\ [])

Lists tickets with optional filtering and pagination.

Parameters

  • opts - Options
    • :user_id - Filter by customer (ticket creator)
    • :assigned_to_id - Filter by assigned handler
    • :status - Filter by status (open/in_progress/resolved/closed)
    • :search - Search in title and description
    • :page - Page number (default: 1)
    • :per_page - Items per page (default: 20)
    • :preload - Associations to preload

Examples

iex> list_tickets()
[%Ticket{}, ...]

iex> list_tickets(status: "open", assigned_to_id: nil)
[%Ticket{}, ...]

list_tickets_assigned_to(handler_id, opts \\ [])

Lists tickets assigned to a specific handler.

list_unassigned_tickets(opts \\ [])

Lists unassigned tickets (where assigned_to_id is nil).

list_user_tickets(user_id, opts \\ [])

Lists tickets created by a specific user.

remove_attachment(attachment_id)

Removes an attachment.

reopen_ticket(ticket, changed_by, reason \\ nil)

Reopens a closed or resolved ticket.

Parameters

  • ticket - Ticket to reopen
  • changed_by - User making the change
  • reason - Optional reopen reason

Examples

iex> reopen_ticket(ticket, current_user, "Issue still occurring")
{:ok, %Ticket{status: "open"}}

resolve_ticket(ticket, changed_by, reason \\ nil)

Resolves a ticket.

Parameters

  • ticket - Ticket to resolve
  • changed_by - User making the change
  • reason - Optional resolution reason

Examples

iex> resolve_ticket(ticket, current_user, "Fixed in version 2.0.1")
{:ok, %Ticket{status: "resolved"}}

start_progress(ticket, changed_by)

Moves ticket to in_progress status.

Parameters

  • ticket - Ticket to update
  • changed_by - User making the change

Examples

iex> start_progress(ticket, current_user)
{:ok, %Ticket{status: "in_progress"}}

update_comment(comment, attrs)

Updates a comment.

update_ticket(ticket, attrs)

Updates an existing ticket.

Parameters

  • ticket - Ticket struct to update
  • attrs - Attributes to update

Examples

iex> update_ticket(ticket, %{title: "Updated Title"})
{:ok, %Ticket{}}