Add an AI-driven support ticketing system to your codebase
This prompt instructs an AI coding assistant to build a complete, portable support ticketing system inside your web application. It enables your existing AI chat assistant to catch user complaints mid-conversation, deduplicate similar reports, auto-score severity, and present actionable issues in an admin queue. Reach for this prompt when you want structured issue tracking built directly into your product without paying for third-party helpdesk software.
By MCAFax · Last updated August 2, 2026 · Free to copy and use
The prompt
# BUILD PROMPT — AI Chat Support Ticketing System (Portable)
Paste this whole thing into Claude Code (or any AI coding assistant) inside the
repo of the business you want to add it to.
---
## STEP 0 — INTERVIEW ME FIRST (do not write any code yet)
Before building anything, read my codebase and then ask me these questions one
batch at a time. Do not assume answers. Do not start coding until I've answered.
1. **Business identity** — What is this business called, what does it do, and
who are its users (customers, staff, both)?
2. **Stack** — Confirm what you found: frontend framework, backend/runtime,
database, hosting, auth. Tell me what you detected and let me correct you.
3. **Existing chat** — Is there already an AI chat assistant in this app? If
yes, show me the file(s) and the system prompt so you extend it rather than
build a second one. If no, you'll scaffold one.
4. **Product areas** — What are the 5–12 functional areas of this product that
a complaint could be about? (e.g. login, billing, sending, search, uploads,
notifications.) I'll give you the list; you'll use it as the ticket
`area` enum.
5. **Who works tickets** — Is there an existing admin/internal app? Where
should the ticket queue live? Do admins already have an auth gate / custom
claim I should reuse?
6. **Notification** — Where do I want to be told about a Critical ticket:
email, SMS, Slack, or just the admin queue?
7. **AI provider** — Which model/API key is already wired up in this project,
and is there a secret manager already in use?
Then summarize what you're about to build in one screen and wait for my go.
---
## STEP 1 — WHAT TO BUILD
A support ticketing system that is **driven by the AI chat assistant**, not by a
"Submit a bug" form. When a user complains in chat that something isn't
working, the assistant handles it conversationally and quietly turns it into
structured data.
Three pieces:
**A. Chat-side complaint detection + ticket tool**
**B. Ticket store with dedup and severity**
**C. Admin ticket queue UI**
Build them in that order, and make each one work end-to-end before moving on.
---
## STEP 2 — PORTABILITY REQUIREMENT (important)
This is being installed across several different businesses of mine. So:
- Put every business-specific value in **one config file** —
`ticketing.config.js` (or the equivalent for the detected stack) — at the
root of the ticketing module. That file holds: business name, product-area
enum, severity thresholds, notification target, admin auth check, collection
or table names, and the chat assistant's tone.
- Everything else must be **generic**. No business logic hardcoded in the tool
handler, the dedup logic, or the UI.
- Keep the whole thing inside a single folder (e.g. `/ticketing` on the backend
and `/ticketing` on the frontend) so I can copy that folder into the next
project and only edit the config file.
- Write a short `INSTALL.md` in that folder: what to change in the config, what
env vars/secrets are needed, what to deploy, and how to grant admin access.
Assume the person reading it is me and I'm not a deep tooling expert — give
exact file paths and exact terminal commands.
---
## STEP 3 — COMPLAINT DETECTION IN CHAT
Add to the assistant's system prompt:
- Users often report problems mid-conversation without labeling them as bug
reports. Watch for: "this isn't working", "it won't let me", "I keep getting
an error", "nothing happens when I click", "it's been stuck since
yesterday", "did you guys change something", plus frustration with no
explicit ask.
- When that happens: **first try to actually help.** If it's a known
behavior or user error, resolve it and do not open a ticket.
- If it looks like a real defect, ask at most **two** clarifying questions —
what they were trying to do, and what happened instead. Never interrogate.
- Then call the ticket tool.
- **Confirm before writing.** Show the user a one-line summary of what you're
about to file and get a yes. This matches the existing confirm-before-action
pattern in my chat assistant — follow it exactly.
- After filing, tell them the ticket ID in plain language and what happens
next. If it was merged into an existing ticket, say so — "a few other people
have hit this too, it's already flagged" — never make it sound like their
report was discarded.
- Never promise a fix date.
---
## STEP 4 — THE TOOL
Add one tool to the assistant, following the same tool-calling pattern already
in this codebase.
```
name: report_issue
description: File a user-reported problem, or attach this report to an
existing open ticket describing the same problem.
input:
area: enum from config (product areas)
title: short imperative summary, max 80 chars, no user PII
description: what the user was doing, what they expected, what happened
severity_signals: {
blocking: bool // user cannot complete the task at all
workaround_exists: bool
affects_money: bool // billing, payments, anything financial
affects_data: bool // loss, corruption, wrong data shown
affects_security: bool // exposure, auth bypass, wrong-user data
reported_frustration: 0-3
}
user_context: { userId, plan/role, page/route, browser, timestamp }
```
The tool handler — not the model — computes severity and does dedup. The model
supplies observations; the server decides.
---
## STEP 5 — SEVERITY RATING (the importance system)
Four levels. Server-side scoring, deterministic, defined in config so I can
retune per business.
| Level | Name | Definition |
|---|---|---|
| **P1** | Critical | Security or data exposure, money moving incorrectly, or the product's core action is broken for everyone. |
| **P2** | High | Blocking with no workaround for the user, or affects money/data for one user. |
| **P3** | Medium | Blocking but a workaround exists, or degraded/confusing behavior. |
| **P4** | Low | Cosmetic, copy, minor annoyance, feature request in disguise. |
Scoring rules:
- `affects_security` → P1, always.
- `affects_money` or `affects_data` → P2 floor.
- `blocking && !workaround_exists` → P2 floor.
- `blocking && workaround_exists` → P3 floor.
- else → P4.
- **Auto-escalation:** every time a duplicate is merged into an open ticket,
increment `occurrenceCount`. At 3 distinct users, bump one level. At 8
distinct users, bump one more. Cap at P1. Log every auto-bump with reason and
timestamp so I can see why a ticket moved.
- Admins can manually override severity; a manual override sets
`severityLocked: true` and freezes auto-escalation for that ticket.
---
## STEP 6 — DEDUP (create new vs. add to existing)
Before creating anything, the handler must check open tickets in the same
`area` with status `open` or `in_progress`, from the last 30 days (window in
config).
Two-stage match:
1. **Fingerprint** — normalize `area` + route/page + a stripped-down symptom
string (lowercase, drop numbers, IDs, names, quotes). Exact fingerprint
match → merge.
2. **Semantic** — if no fingerprint match, send the new title/description plus
the candidate open tickets' titles to the model in a single cheap call and
ask for the ID of a genuine duplicate or `null`. Require a confident match;
default to creating a new ticket when unsure. A wrong merge hides a real
bug — a duplicate ticket is cheap, a swallowed report isn't.
On merge, do **not** overwrite the original ticket. Append an occurrence
record:
```
occurrences: [{ userId, description, userContext, at }]
occurrenceCount: n
distinctUserCount: n
lastReportedAt: timestamp
```
Then re-run the severity escalation check.
---
## STEP 7 — DATA MODEL
One collection/table, `tickets`:
```
id, businessKey, area, title, description,
severity, severityLocked, severityHistory[],
status: open | in_progress | waiting_on_user | resolved | wont_fix | duplicate,
fingerprint,
occurrences[], occurrenceCount, distinctUserCount,
createdAt, lastReportedAt, resolvedAt,
assignedTo, internalNotes[],
sourceConversationId,
mergedInto (nullable)
```
Rules:
- Write only through the server-side handler. Clients never write tickets
directly — lock this down in the security rules and show me the rules diff.
- Index on `(status, severity, lastReportedAt)` and on `(area, status,
createdAt)`. Tell me the exact command or console steps to create them.
- Store no more PII than needed: user ID, not email dumps; strip anything that
looks like a card number, SSN, or password out of `description` before write.
---
## STEP 8 — ADMIN QUEUE
In the admin app (or a new admin-gated route if none exists):
- Table of tickets, default sort: severity desc, then `lastReportedAt` desc.
- Severity shown as a colored pill (P1 red, P2 orange, P3 yellow, P4 gray).
- Filters: severity, status, area, date range. Search on title.
- A visible count badge on any ticket with `occurrenceCount > 1` — this is the
signal I actually care about.
- Ticket detail: full description, every occurrence with its user context in
chronological order, severity history with auto-bump reasons, internal notes,
and controls to change status, override severity, assign, and merge into
another ticket manually.
- Full edit and delete from this UI — I never want to open the database console
to fix a ticket.
- If config has a notification target, fire it on any new P1 and on any
auto-escalation into P1.
---
## STEP 9 — HOW TO WORK
- Build A, then B, then C. After each, stop, tell me exactly what to run to
test it locally, and wait for me to confirm it works before continuing.
- Any backend/function changes: remind me they need an explicit deploy command
and give me the exact command. Frontend changes deploy on push — keep the two
paths clearly separate in your instructions to me.
- Back up any file before you rewrite it, and run a syntax check after.
- Don't touch unrelated files.
- At the end, give me a checklist of everything that must be true for this to
work in a fresh project, and one seeded test ticket at each severity level so
I can see the queue populated.
Works with ChatGPT, Claude, Gemini or any AI assistant. Replace anything in [brackets] with your own details before you send it.
How to use it
Paste this entire prompt into an AI coding assistant like Claude Code, Cursor, or Aider from within your project's code repository. The assistant will interview you about your tech stack, database, and admin setup before writing any code. Make sure to review the generated ticketing.config.js file to customize severity thresholds and product areas for your business.
Questions readers actually ask
What does this prompt produce for my app?
It generates a self-contained ticketing module inside your codebase. This includes chat complaint detection routines, server-side deduplication and severity scoring logic, database rules, an admin management dashboard, and setup documentation.
Who is this prompt designed for?
This prompt is designed for software founders, developers, and technical business owners who maintain web applications and want an automated way to convert customer chat feedback into developer-ready bug reports.
Which AI assistant should I run this prompt in?
Run this prompt in repository-aware coding assistants like Claude Code, Cursor, Aider, or GitHub Copilot Workspace. These tools can read your existing codebase files and create new files in place.
Do I need a specific database or framework to use this?
No specific framework is required. The prompt starts with an interview step where the AI assistant analyzes your codebase to detect your current framework, database, and auth setup before adapting the output to your environment.
MCAFax is being built to do the thing you can't do from inside the room: make the phone stop. Members will check any broker against a shared, member-built database and send cease & desist letters from their own Gmail, with delivery proof on every one. Some laws, like the TCPA, put statutory damages on illegal calls — whether they apply to yours depends on your situation, and business lines get less protection than home ones. We're not a law firm. Sign-ups aren't open yet; the newsroom is, and it's free to read.