PhoenixKitCustomerSupport

Elixir License: MIT

Customer support ticketing module for PhoenixKit.

Provides a full ticketing system: create tickets, track status, add comments and attachments, manage agents. Extracted from PhoenixKit core (>= 1.7.104).

Features

Installation

Add to the host app's mix.exs:

{:phoenix_kit_customer_support, "~> 0.3"}

Then mix deps.get. The module appears in the admin Modules page and sidebar automatically via PhoenixKit.Module auto-discovery.

Requires PhoenixKit core ~> 2.4. Ticket.changeset/2 calls PhoenixKit.Utils.Slug.put_slug/3, which core added in 2.4.0 (along with V168, which makes ticket slugs unique). Core 2.0.0 squashed the migration chain to a V135 floor and refuses to migrate a database below it — check mix phoenix_kit.status before upgrading, and see core’s 2.0.0 / 2.4.0 CHANGELOGs.

This module owns and versions the future shape of its 4 tables (phoenix_kit_tickets, phoenix_kit_ticket_comments, phoenix_kit_ticket_attachments, phoenix_kit_ticket_status_history) through its own migration chain, PhoenixKitCustomerSupport.Migrations. Core's V135/V168 still CREATE these 4 tables on every install — this chain's V1 adopts that shape and stamps a version marker. It makes exactly one real change: phoenix_kit_ticket_status_history.changed_by_uuid is made NULLABLE (ALTER COLUMN … DROP NOT NULL), because core's baseline declares it NOT NULL while its own FK is ON DELETE SET NULL — a contradiction core's V164 documents but never resolves. Hosts installed from the squashed V135 baseline (core ≥ 2.0.0) carry the NOT NULL and are relaxed by V1; older hosts that reached the current chain historically already have it nullable, so V1 is a no-op there. V1 also replaces any legacy descriptive COMMENT on phoenix_kit_tickets with the version marker. The ~> 2.4 floor above exists because V1 must already include V168 (the unique slug index) for the adopted shape to match.

Module integration

The package registers itself with PhoenixKit's module system. No manual router wiring needed — admin routes are auto-discovered at compile time via route_module/0.

Routes

Admin routes (registered by this package via route_module/0)

Path LiveView
/admin/customer-support PhoenixKitCustomerSupport.Web.List
/admin/customer-support/tickets PhoenixKitCustomerSupport.Web.List
/admin/customer-support/tickets/new PhoenixKitCustomerSupport.Web.New
/admin/customer-support/tickets/:uuid PhoenixKitCustomerSupport.Web.Details
/admin/customer-support/tickets/:uuid/edit PhoenixKitCustomerSupport.Web.Edit
/admin/settings/customer-support PhoenixKitCustomerSupport.Web.Settings

User dashboard routes (wired by PhoenixKit core via Code.ensure_loaded? guards)

Path LiveView
/dashboard/customer-support/tickets PhoenixKitCustomerSupport.Web.UserList
/dashboard/customer-support/tickets/new PhoenixKitCustomerSupport.Web.UserNew
/dashboard/customer-support/tickets/:id PhoenixKitCustomerSupport.Web.UserDetails

User-facing routes are registered by PhoenixKitWeb.Integration in the core library when this package is present — no additional router configuration is required in the host app.

Settings

The following settings keys control this module's behaviour. They are managed via the admin Settings UI (/admin/settings/customer-support) or directly via PhoenixKit.Settings.

Key Default Description
customer_support_enabled false Enables or disables the customer support module globally.
customer_support_per_page 20 Number of tickets shown per page in admin and user list views.
customer_support_comments_enabled true Allows users and agents to post comments on tickets.
customer_support_internal_notes_enabled true Enables internal (agent-only) notes on tickets.
customer_support_attachments_enabled true Allows file attachments to be added to tickets and comments.
customer_support_allow_reopen true Permits closed tickets to be reopened by users or agents.

Removing this module

There is deliberately no automated uninstall. PhoenixKitCustomerSupport.Migrations.down/1 never drops any of the 4 phoenix_kit_ticket* tables or a row in them, for any target version — a host that merely removes this dependency from mix.exs has not consented to deleting every customer's tickets, comments (public and internal notes), attachments and status-change audit trail, and a migration whose result depended on which packages happen to be compiled in would be nondeterministic. Removing the data is therefore a deliberate, manual operator step — remove :phoenix_kit_customer_support from mix.exs first, then run, in FK-safe order (children before parents, substituting your PhoenixKit schema prefix for public):

-- Only if you actually want every ticket and everything attached to it
-- gone for good.
DROP TABLE public.phoenix_kit_ticket_attachments;
DROP TABLE public.phoenix_kit_ticket_comments;
DROP TABLE public.phoenix_kit_ticket_status_history;
DROP TABLE public.phoenix_kit_tickets;

Dropping phoenix_kit_tickets last also removes the pkcs_schema:<N> version marker, which is a COMMENT on that table — no separate step is needed.

While core's baseline still creates these tables (it does today), core's ExpectedSchema manifest lists all 4 as required: mix phoenix_kit.doctor then reports them missing, and mix phoenix_kit.repair recreates them — empty. The rows are gone either way; only the empty tables come back.

To keep the rows (e.g. you plan to reinstall the module later), simply leave the tables alone. The marker is inert once the module is gone, and on reinstall it correctly reads as already adopted. Clearing it achieves nothing: while the module is installed, the next mix phoenix_kit.update re-stamps it.

Development

mix deps.get
mix compile
mix test