Relay Desk — product requirements
Relay Desk is a customer-service platform. Agents work tickets in a console with views, first-reply SLA timers, a ticket workspace (public reply vs internal note, macros, properties), bulk actions, a live chat queue, a knowledge base and reports. Customers use a public help center to file requests, look up their status and search articles.
Problem. Support teams need to answer customers quickly without ever exposing internal discussion, losing a teammate’s reply, or silently breaking an SLA; customers need a simple way to ask for help and follow up.
Users
- Support agent — Work a queue of tickets, reply, add internal notes, use macros and chat, and see which tickets are about to breach.
- Customer — Submit a request, receive a request number and check its status without seeing internal notes.
- Team lead — Trust that reports, SLA counts and merges reflect what actually happened.
Goals
- Internal notes are never visible to customers.
- SLA state always matches the ticket’s priority, age and status.
- A reply is never sent over a teammate’s newer reply without the agent seeing it first, and destructive actions need explicit confirmation.
Out of scope
- Email delivery
- Attachments
- Real push between agents
Contents
Agent sign-in
Email and password sign-in to the console.
- URL becomes /helpdesk/agent/views/mine; the header shows the agent name and role
- Seven views: Your unsolved tickets, Unassigned tickets, All unsolved tickets, SLA breached, Pending tickets, Recently solved, All tickets (60)
- Empty form: "Enter your email and password"
- Wrong password: "Invalid email or password"; the page stays on sign-in
Ticket list
Views with search, filters, sorting and paging.
- "All tickets" shows "60 tickets" and the pager "1–25 of 60"; after Next twice "51–60 of 60" with Next disabled
- Search "refund" lists only tickets whose subject or tags mention refund, including #1001
- A priority filter with no matches shows "No tickets match this view and "refund"."; Clear restores 60 tickets
SLA timers
First-reply SLA per ticket.
- #1001 (High, 6 h old, no reply) is in "SLA breached" with a red negative badge such as "−2h 0m"
- The "SLA breached" view count matches the number of breached tickets
- #1004 (High, New, 90 min old) shows a neutral badge of about "2h 30m"
- Pending and On-hold tickets show "⏸ Paused"
- Solved tickets or tickets with a first reply show "✓ Met", never a running timer
Ticket workspace
Reply, internal notes, solving rules and properties.
- The composer defaults to "Public reply" with hint "Reply to Elena Park — the customer will see this"
- Choosing Pending changes the button to "Submit as Pending"; after sending: toast "Ticket #1001 updated · Pending", reply last in the thread, status pill Pending
- "First reply due" in Properties shows "✓ Met"
- The Internal note tab turns the composer yellow with "Internal note — only agents can see this"
- The note appears in the thread with a yellow "Internal note" tag
- The customer’s status lookup shows only public messages; no note, including seeded ones, appears
- Submitting as Solved on an unassigned ticket shows "Assignee is required to solve a ticket" and the status stays New
- "Take it" assigns the agent; solving then succeeds with toast "Ticket #1002 updated · Solved" and the ticket leaves "Unassigned tickets"
- Type Question: no Root cause field; Type Incident: "Root cause — required to solve" appears
- Solving an Incident without it shows "Root cause is required to solve an Incident" and the status stays New
- Switching the type back to Question, saving, then to Incident again shows an empty Root cause
- Typing "pri" leaves only Priya Nair; "zzz" shows "No agent matches "zzz""
- Enter selects the highlighted option and closes the list
- "Save properties" persists the assignee across reload
- "Requester email is required" then "Subject is required" when missing
- Success: toast "Ticket #NNNN created" and the workspace opens with status New
- "Other tickets" lists the customer’s earlier tickets
Sending and concurrency
Undo window and protection against overwriting teammates.
- Alert "Sam Okoye updated this ticket while you were writing. Review the new reply before you submit."; Submit is disabled; the draft stays in the composer
- "Review changes" shows the teammate’s reply and the new status without altering the draft
- The second submit succeeds; the thread contains exactly one copy of each reply, the teammate’s first
- Presence banners "👀 Sam Okoye is also viewing this ticket" and "✍ Sam Okoye is typing a reply…" appear on the ticket
- Status bar "Sending in 5s…" with "Undo"; Submit is disabled
- Undo shows "Sending cancelled — your draft is kept"; the thread, status and SLA are unchanged after reload
Macros
Canned replies that also set properties.
- Reply starts "Hi Elena, we have issued a full refund."; button reads "Submit as Solved"; hint lists tags: refund
- After submit: toast "Ticket #1001 updated · Solved", status pill Solved, tag refund present and the ticket is in "Recently solved"
Bulk actions
Act on several selected tickets.
- Two selected tickets: "2 tickets assigned to you"; both leave "Unassigned tickets" and the count drops by 2
- Setting Solved on an unassigned ticket: "0 updated · 1 skipped (no assignee): #NNNN" and the row stays
Merge tickets
Destructive merge of a duplicate into another ticket.
- The preview shows the target ticket and requester; "Merge tickets" stays disabled until exactly "MERGE" is typed (lowercase does not count)
- Result: toast "#1005 merged into #1001"; #1001 gains a system note about the merge
- The merged ticket is Closed with banner "This ticket was merged into #1001 and is closed."; its "Merge into another ticket…" is disabled
- Merging a ticket into itself shows "A ticket cannot be merged into itself"
- #1001 Elena Park and #1005 Elena Parks have different emails and different orders (BZ-48213 vs BZ-48231)
Live chat
Queue of waiting visitors and chat-to-ticket conversion.
- The queue shows "Waiting (3)" with Visitor 4821 on /orders/BZ-77120
- Accept opens "Chat with Visitor 4821" with the visitor’s opening message; sending a message shows a typing indicator and then the visitor’s answer
- End chat with "Convert to ticket" ticked and a subject: toast "Chat ended · ticket #NNNN created"; the ticket has channel Chat, the agent as assignee and a transcript note
Help center
Public request form, status lookup and knowledge base.
- Invalid email: "Enter a valid email address" with the field marked invalid
- Description shorter than 10 characters: "Describe the issue in at least 10 characters"
- Success: "Request #NNNN received" and "We emailed a confirmation to <email>."
- Agents see the request in "Unassigned tickets" with status New, the chosen group and tag portal
- Wrong email: "No request matches that number and email"
- Right email for #1003: "#1003 Package arrived damaged" with status "Awaiting your reply"
- Search "password" gives "1 article" — "Reset your password" ("Links expire after 30 minutes.")
- No match: "No articles match "zzz"."
Reports
KPIs and distributions from the live ticket set.
- Solving one unsolved ticket lowers Unsolved by 1 and raises the Solved bar by 1
Non-functional requirements
Glossary and rules
| Internal note | A message only agents can see. |
|---|---|
| Macro | A canned reply that can also set status, tags, priority and group. |
| First reply SLA | Time allowed for the first public reply, by priority. |