22 · Admin · Helpdesk & CRM config
Admin pages that control helpdesk behaviour: SLA policies, support contracts, ticket types, helpdesk rules, saved views, and CRM-side settings like custom fields and import.
SLA policies
/admin/helpdesk/sla
There is one SLA policy per priority — LOW, MEDIUM, HIGH, and URGENT each have a single policy for the tenant. A policy defines a response target (hours to first public reply) and a resolution target (hours to close). When a ticket is created, the platform stamps deadlines onto it from the policy matching the ticket's priority.
+-----------------------------------------------+
| SLA policies |
|-----------------------------------------------|
| URGENT 1h respond / 4h resolve [Edit] |
| HIGH 4h / 8h [Edit] |
| MEDIUM 8h / 24h [Edit] |
| LOW 48h / 120h [Edit] |
+-----------------------------------------------+
📷 Screenshot placeholder: screenshots/admin-sla.png
Editing a policy
- Click Edit on the priority row.
- Set a name, a response target (hours), and a resolution target (hours).
- Save. This upserts the policy for that priority.
There is no working-hours calendar and no pause/resume — SLA deadlines are fixed absolute timestamps computed at ticket-creation time as created-at + N hours. The response target is met on the first public reply; the resolution target is met when the ticket reaches RESOLVED or CLOSED.
Note: SLA policies are keyed on tenant + priority. They are not selected per support contract — a contract carries no SLA policy reference.
Support contracts
/admin/helpdesk/contracts
A support contract is a billing arrangement. Each contract has:
- A name and a type — one of:
- Ad-hoc (
ADHOC) — billed per hour - Hour block (
BLOCK) — a pre-paid pool of hours - Monthly/Annual (
CONTRACT) — recurring, with an optional included-hours allowance
- Ad-hoc (
- A client name and optional client email
- An optional hourly rate (£) and hours included
- A start date and optional end date
- Free-text notes
+-------------------------------------------------------+
| Contracts [+ New] |
|-------------------------------------------------------|
| Client Name Type Rate Hours Active |
| Acme Ltd Acme Gold Hour block £95 12/20 ✓ |
| Beta Co Beta PAYG Ad-hoc £110 — ✓ |
+-------------------------------------------------------+
📷 Screenshot placeholder: screenshots/admin-contracts.png
Hours allowance & billing
Time entries logged against tickets can be attributed to a contract. The contract list shows hours used against hours included, and the contract detail page has a date-range billing summary: total / billable hours, hours remaining, overage, and amount due. How the amount is computed depends on the contract type — BLOCK and CONTRACT bill overage beyond the included hours, ADHOC bills all billable hours. See Billing.
There is no "Renew" action and no SLA-policy reference on contracts.
Ticket types & statuses
/admin/helpdesk/types
Define your own ticket types and the status options each type can move through. Each tenant has independent types — no global enum to fight.
+--------------------------------------------------------+
| Ticket types [+ New type] |
|--------------------------------------------------------|
| 🎫 Incident • DEFAULT 4 statuses [Edit] |
| ├─ Open (default) |
| ├─ Investigating |
| ├─ Resolved (counts as resolved) |
| └─ Closed (terminal) |
|--------------------------------------------------------|
| 🛠 Change request 4 statuses [Edit] |
| ├─ Submitted (default) |
| ├─ Approved |
| ├─ Implemented (counts as resolved) |
| └─ Closed (terminal) |
+--------------------------------------------------------+
📷 Screenshot placeholder: screenshots/admin-ticket-types.png
Type fields
- Name — display label
- Slug — URL-safe key auto-derived from the name
- Icon + colour — chip rendered on the ticket list
- Default — one per tenant; new untyped tickets fall to it
- Archived — hides the type from the create-ticket dropdown while preserving historical reporting
Status fields (per type)
- Name + slug + colour + sort order
- Default (
isDefault) — the type's default status. Exactly one per type; ticking a new one clears the previous default. - Counts as resolved (
isResolved) — metadata flag marking the status as a resolved-equivalent. - Terminal (
isClosed) — metadata flag marking the status as a closed-equivalent.
The
isResolved/isClosedflags are descriptive metadata stored on the status. Open/closed queue membership,resolvedAt, and the SLA clock are still driven by the legacy enumstatusfield (OPEN / IN_PROGRESS / RESOLVED / CLOSED), not by the typed status.
How types and the legacy enum interact
The platform shipped originally with a fixed OPEN | IN_PROGRESS | RESOLVED | CLOSED enum on every ticket. That enum is still the
authoritative status: SLA computation, the open/closed queues,
resolvedAt, and the helpdesk rules engine all read it.
A ticket type and a typed status (statusOption) are an optional
extra layer. The ticket list and detail views display the typed
status name + colour when one is set, falling back to the enum label
otherwise. The two are stored independently — assigning a typed
status does not rewrite the enum, and changing the enum does not
rewrite the typed status. Keep the enum correct for anything that
depends on SLA or queue membership.
Priorities
Priority is a fixed enum (LOW | MEDIUM | HIGH | URGENT) for SLA
compatibility — those four values appear everywhere. Per-tenant
relabeling is on the roadmap; until then use the labels as-is.
⚠️ Caution. Deleting a type or status removes the link on existing
tickets (FK ON DELETE SET NULL). Tickets fall back to the legacy
enum status until you reassign them. The platform refuses to delete
the last type or a type's default status — archive instead.
Helpdesk rules
/admin/helpdesk/rules
The rules engine automates ticket workflows. Configuration lives on its own page — see Helpdesk rules.
Saved views
/admin/helpdesk/views
Admin-managed shared views that appear in every operator's helpdesk sidebar. Use them to surface curated queues — e.g. "Network outages" (ticket type = Incident), "VIP customers" (a specific customer), "My open work" (base view = Assigned to me).
Each saved view bundles:
- Base view — one of the five built-ins (Assigned to me, SLA breached, etc.), or "— none —" for a purely filter-driven view
- Status / Priority / Ticket type
- Assignee / Customer / Project
- Search text (free-text contains)
- Sort order — lower numbers appear first in the sidebar
- Shared flag — when off, the view is private (don't use this page for that; operators manage personal views from their own Account settings instead)
Slug is auto-generated from the name. The sidebar link is
/helpdesk?view=<slug>.
Operators can also manage personal views at
/profile/settings/views — those are only visible to the owner.
CRM settings
/admin/crm/settings
- Pipeline stages — drag to reorder, edit names. Drives the deal kanban.
- Custom fields — typed extra fields on companies and contacts: text, number, date, dropdown.
- Default owner — the user that newly-created CRM records belong to if not specified.
- Tags — the curated tag list (free-form tags also allowed).
Import contacts
/admin/crm/import
Bulk CSV import. See CRM → Importing contacts.
Permissions
The helpdesk service recognises platform roles only — there is no
dedicated helpdesk-admin or billing role. "Admin" below means
SUPER_ADMIN or ADMIN.
| Action | Role required |
|---|---|
| View SLA policies / contracts / types / views / rules | any authenticated user |
| Edit SLA policies | Admin |
| Create / edit support contracts | Admin |
| Create / edit / delete ticket types & statuses | Admin |
| Create / edit / delete helpdesk rules | Admin |
| Create / edit a shared saved view | Admin |
| Create / edit your own personal saved view | any authenticated user |
Common workflows
Tighten an SLA target
- SLA policies → Edit the URGENT (or other priority) row.
- Lower the response / resolution hours.
- Save. New tickets at that priority pick up the tighter deadlines.
Onboard a many-customer batch
- Create their CRM companies via Import.
- For each, create a support contract with the right billing type.
Customise a status
- Ticket types → open a type → + Add status "Awaiting parts".
- Optionally tick Counts as resolved so the ticket maps to the RESOLVED legacy enum and leaves the open queues.