Helpdesk queue demo with SLA timers

A support queue where the timers are the product. Deadlines are derived from stored timestamps rather than from an interval nobody is running, so closing the laptop for half an hour produces the right overdue time and the right escalation history when you come back.

Open the demo

Opens helpdesk.taiphamsolutions.com in a new tab. No account, no signup, and nothing you do in it leaves your browser.

What it does

The queue filters by priority, status, assignee and SLA state, and a ticket opens into its conversation beside its SLA panel. Staff replies are public and complete the first response; internal notes are visible only in the admin interface and do not. Canned replies are bilingual templates that can be inserted and then edited before sending.

Resolution is a cycle rather than a state. Send and wait for user pauses it, a requester reply resumes it, and send and resolve finishes it. Reopening a ticket preserves the previous outcomes and starts a new cycle, so a reopened ticket does not quietly erase the SLA it already met.

The database stores cycle start timestamps, budget durations, accumulated pauses, completion times and escalation levels, and the countdown on screen is derived from those and the device clock. One shared signal repaints the visible text each second, and a routine tick reads and writes nothing. Deadlines are reconciled at startup, on focus, on visibility restoration and on any relevant action, and a missed escalation records both when the threshold passed and when it was processed.

In Settings, create a timed ticket. Its first-response deadline is two minutes away. Close the tab, come back after it, and check both the overdue time and the escalation history.

Features

A populated queue in English and Vietnamese, with User and Admin profiles switchable from the sidebar.

Queue and conversation

Filters on priority, status, assignee and SLA state, with the conversation and the SLA panel on one screen rather than two.

Replies and notes

Public staff replies complete first response, internal notes stay in the admin interface, and bilingual canned templates can be inserted and edited before sending.

Pause, resolve, reopen

Waiting on the requester pauses the resolution clock and their reply resumes it. Reopening starts a new cycle and keeps the outcomes of the last one.

Administration

Editable SLA policies and bilingual templates, profile creation, a validated import preview over backups, and a demo reset.

The flow it closes, end to end

Every step below happens inside the demo. There is no point in it where the work leaves the browser and comes back.

  1. A request arrives

    Filed from the User interface, with a priority that decides which SLA policy applies to it.

  2. It lands in the queue

    Filtered by priority, status, assignee or SLA state, with its first-response countdown already running.

  3. First response

    A public staff reply completes it. An internal note does not, which is the distinction most queues get wrong.

  4. Waiting on the requester

    Send and wait pauses the resolution clock. The pause accumulates against the ticket, and the requester's reply resumes it.

  5. The threshold passes

    Escalation is recorded once, with both the time the threshold was crossed and the time the app got round to processing it, even if every tab was shut in between.

  6. Resolved, and reopened if it comes back

    Send and resolve closes the cycle. Reopening starts a fresh one and leaves the previous outcomes standing.

What is real, and what is not

There is no server behind any of this, which decides both columns. The left one is what that constraint made worth building properly. The right one is what it rules out.

Actually handled

  • A 35-minute clock jump with every tab closed, giving one deadline and both escalation levels recorded once
  • A refresh mid-reply that keeps the committed ticket and the draft
  • Two tabs racing, with transactions and unique event IDs preventing a duplicate escalation or reassignment
  • 1,000 stored tickets and 50 visible rows producing 100 text updates and zero database reads over a 2.2-second sample

Deliberately not real

  • Roles are an interface simulation, not authentication
  • No email arrives and none is sent. A ticket is created in the app
  • There are no background notifications. While every tab is closed no code runs, and the catch-up happens when the app runs again
  • The device clock is the time source. A clock moved by hand cannot be corrected without an external time authority

How it is built

The write-up sells harder than the application does, so it is on the page rather than in a repository nobody can open.

Stack
Preact, Signals, TypeScript and Vite, with IndexedDB as the only application database and cycles embedded in the ticket records.
Timing
Pure functions over stored timestamps compute every deadline and escalation. The visible countdown is derived, so nothing depends on an interval having been left running.
Budget
100 KiB gzip for initial JavaScript and 150 KiB gzip for total JavaScript and CSS, checked by a size gate rather than by hope.
Tests
27 domain and state tests over timing, pause and resume, boundaries, priority changes, concurrency, permissions, historical policies, backup validation and rollback, plus 9 browser workflow scenarios and 7 browser regressions.

The services this is evidence for

A demo exists to prove something on the offer list rather than to be impressive on its own. These are the ones this one argues for.

Want the version of this with your rules in it?

This one was built to a constraint nobody would choose. Yours would have a server, real accounts, and the parts of the domain that are actually hard. Tell us what the software has to do and we will tell you what it takes.

Bring the messy version of the problem. That is the conversation we enjoy most.

Email us