Search documentation of phoenix_kit

# PhoenixKit.Modules.CustomerService (phoenix_kit v1.7.87)

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_uuid, %{
      title: "Cannot login",
      description: "I get an error when trying to login..."
    })

    # Assign to support staff
    {:ok, ticket} = Tickets.assign_ticket(ticket, staff_user_uuid, 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_uuid, %{
      content: "We're looking into this issue."
    })

    # Add an internal note (hidden from customer)
    {:ok, note} = Tickets.create_internal_note(ticket.uuid, staff_user_uuid, %{
      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

add_attachment_to_comment(comment_uuid, file_uuid, opts \\ [])

Attaches a file to a comment.

add_attachment_to_ticket(ticket_uuid, file_uuid, opts \\ [])

Attaches a file to a ticket.

assign_ticket(ticket, handler_uuid, changed_by)

Assigns a ticket to a support staff member.

close_ticket(ticket, changed_by, reason \\ nil)

Closes a ticket.

create_comment(ticket_uuid, user_uuid, attrs)

Creates a public comment on a ticket.

create_internal_note(ticket_uuid, user_uuid, attrs)

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

create_ticket(user_uuid, attrs)

Creates a new ticket.

delete_comment(comment)

Deletes a comment.

delete_ticket(ticket)

Deletes a ticket and all related data.

disable_system()

Disables the Tickets module.

enable_system()

Enables the Tickets module.

enabled?()

Checks if the Tickets module is enabled.

get_comment!(id, opts \\ [])

Gets a comment by ID.

get_config()

Gets the current Tickets module configuration and stats.

get_stats()

Gets ticket statistics.

get_status_history(ticket_uuid, 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.

get_ticket_by_slug(slug, opts \\ [])

Gets a single ticket by slug.

list_all_comments(ticket_uuid, opts \\ [])

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

list_comment_attachments(comment_uuid, opts \\ [])

Lists attachments for a comment.

list_internal_notes(ticket_uuid, opts \\ [])

Lists only internal notes for a ticket.

list_public_comments(ticket_uuid, opts \\ [])

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

list_ticket_attachments(ticket_uuid, opts \\ [])

Lists attachments for a ticket.

list_tickets(opts \\ [])

Lists tickets with optional filtering and pagination.

list_tickets_assigned_to(handler_uuid, opts \\ [])

Lists tickets assigned to a specific handler.

list_unassigned_tickets(opts \\ [])

Lists unassigned tickets (where assigned_to_uuid is nil).

list_user_tickets(user_uuid, opts \\ [])

Lists tickets created by a specific user.

remove_attachment(attachment_uuid)

Removes an attachment.

reopen_ticket(ticket, changed_by, reason \\ nil)

Reopens a closed or resolved ticket.

resolve_ticket(ticket, changed_by, reason \\ nil)

Resolves a ticket.

start_progress(ticket, changed_by)

Moves ticket to in_progress status.

update_comment(comment, attrs)

Updates a comment.

update_ticket(ticket, attrs)

Updates an existing ticket.

## Functions

# add_attachment_to_comment(comment_uuid, file_uuid, opts \\ [])

Attaches a file to a comment.

# add_attachment_to_ticket(ticket_uuid, file_uuid, opts \\ [])

Attaches a file to a ticket.

## Parameters

- `ticket_uuid` - ID of the ticket
- `file_uuid` - UUID 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_uuid, 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_uuid` - UUID of the support staff
- `changed_by` - User making the change

## Examples

    iex> assign_ticket(ticket, handler_uuid, current_user)
    {:ok, %Ticket{assigned_to_uuid: handler_uuid}}

# 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_uuid, user_uuid, attrs)

Creates a public comment on a ticket.

## Parameters

- `ticket_uuid` - ID of the ticket
- `user_uuid` - ID of the commenter
- `attrs` - Comment attributes (content, optional parent_id)

## Examples

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

# create_internal_note(ticket_uuid, user_uuid, attrs)

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

## Parameters

- `ticket_uuid` - ID of the ticket
- `user_uuid` - ID of the staff member
- `attrs` - Note attributes (content)

## Examples

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

# create_ticket(user_uuid, attrs)

Creates a new ticket.

## Parameters

- `user_uuid` - 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_uuid, 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_uuid, opts \\ [])

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

# list_comment_attachments(comment_uuid, opts \\ [])

Lists attachments for a comment.

# list_internal_notes(ticket_uuid, opts \\ [])

Lists only internal notes for a ticket.

# list_public_comments(ticket_uuid, opts \\ [])

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

# list_ticket_attachments(ticket_uuid, opts \\ [])

Lists attachments for a ticket.

# list_tickets(opts \\ [])

Lists tickets with optional filtering and pagination.

## Parameters

- `opts` - Options
  - `:user_uuid` - Filter by customer (ticket creator)
  - `:assigned_to_uuid` - 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_uuid: nil)
    [%Ticket{}, ...]

# list_tickets_assigned_to(handler_uuid, opts \\ [])

Lists tickets assigned to a specific handler.

# list_unassigned_tickets(opts \\ [])

Lists unassigned tickets (where assigned_to_uuid is nil).

# list_user_tickets(user_uuid, opts \\ [])

Lists tickets created by a specific user.

# remove_attachment(attachment_uuid)

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{}}