Service Ticketing Demo¶
Ordered runbook for showcasing Floh service ticketing: catalog submit, My Tickets, agent assignment, comments, status/SLA, queues, and (optionally) email intake.
For a five-card IT support portal walkthrough (self-service + approval + ticketed cards) seeded via pnpm seed:support-portal, see Support Portal Demo.
Read Service Ticketing for architecture and story inventory. This page is the live checklist.
Start the stack¶
pnpm dev:all https starts infra + migrations, then the full HTTPS stack
(API :7070, console BFF :7074, admin SPA :7072, portal BFF :7071, portal SPA
:7073, form-builder :7080). Do not start pnpm dev:portal in a second
terminal — those ports are already bound.
| Port | App | Started by |
|---|---|---|
| 7070 | API (+ /api/docs) |
dev:all https |
| 7071 | Portal BFF | dev:all https |
| 7072 | Admin web | dev:all https |
| 7073 | Portal SPA | dev:all https |
| 7074 | Console BFF | dev:all https |
| 7080 | Form-builder | dev:all https |
pnpm dev:all with no argument prompts from the HTTPS picker (dev:https,
dev:mux, …). Use pnpm dev:all:http for the HTTP picker. pnpm dev:all portal:https is valid but starts only the portal side.
Accounts¶
- Requester — any authenticated portal user (catalog submit + own tickets)
- Agent — user with
ticket:manage(Tickets hub, queues, SLA, assign/status/comments/snooze). Prefer a second user so assignment is visible.
One-time config (before the live demo)¶
- Admin → Tickets → Ticket Queues → create e.g.
IT Support - Admin → Tickets → SLA Policies → create or attach a policy to that queue (response/resolution hours per priority)
- Admin → Workflows → open a catalog-published workflow → Catalog Publishing → Ticket Queue → select
IT Support→ save (needsticket:manageto load queues) - Confirm the workflow is published to the Request Catalog (or use draft preview if you hold
workflow:publish)
Demo script¶
1. Catalog submit → ticket created (LSA-9061)¶
Where: Portal https://localhost:7073/requests/catalog
- Sign in as requester
- Open Request Catalog (topbar)
- Pick a catalog item whose workflow has a Create ticket step (and optionally a Ticket Queue)
- Fill the form (optional:
ticketTitle,ticketDescription,ticketRequestType) → Submit Request - Confirm the banner: Your request was submitted as ticket #N (link when you are the requester). Without Create ticket, expect “Your request was submitted.”
- When ticketed, click the link → lands on
/tickets/N
What to say: Ticket creation is opt-in via the create_ticket step. When present, one DB transaction creates the run and service_ticket. Form variables map title/description/request type. On-behalf-of sets requester_id to the target user. The portal does not expose raw POST /api/tickets.
2. Portal My Tickets (LSA-9063)¶
Where: /tickets and /tickets/:ticketNumber
- Topbar My Tickets
- Walk tabs: Open, Pending Your Response, Resolved, All
- Open
#N— Details, Description, Conversation - Post a Reply (public comment only)
What to say: The list is force-scoped to requester_id. The BFF whitelist blocks agent mutations (assign, status, internal notes) from the portal. Open tab uses statusIn=open,in_progress,on_hold.
3. Agent inbox — assign, status, priority, queue¶
Where: Admin https://localhost:7072/tickets (sidebar Tickets, needs ticket:manage)
- Find ticket
#N(filters: Status / Priority / Queue / Assignee) - Open detail or use list Update for a quick status/priority/queue change
- On detail Assignment card: set Assignee to the agent, change Status (e.g. open → in_progress or pending_customer), adjust Priority / Queue if useful
- Save, then refresh portal as requester to show the same ticket number with updated fields
What to say: Agents work in admin; requesters work in portal. Same display ticket number in both UIs.
4. Comments — public vs internal¶
Where: Admin ticket detail → Comments
- Add a public comment (visible on portal Conversation)
- Check Internal note → add another (tag Internal)
- Switch to portal as requester → only the public reply appears
What to say: Internal notes never leave the agent surface. The email channel also never emails internal notes. A public requester reply on pending_customer returns the ticket to open.
5. SLA visibility + snooze¶
Where: Admin ticket detail; portal list SLA column
- Show SLA due / countdown fields on admin (and portal list if present)
- Snooze SLA → pick a future time → confirm
- Mention breach notifications (LSA-9067) if SMTP is configured; otherwise note they are environment-dependent
6. Queues and SLA policy admin¶
Where: /tickets/queues, /tickets/sla-policies
Brief walkthrough of creating a queue and editing policy hours so the audience sees the config that drives assignment defaults and SLA clocks.
7. Optional — email channel (LSA-9066)¶
Where: Admin → Connectors → email-ticketing; webhook against the API
If a connector is configured:
- Show fields:
inboxAddress,webhookSecret,adminNotifyEmail POST /api/email-ticketing/inbound/:connectorIdwith HMAC signature — see Email Ticketing connector- Ticket appears with
source=email; agent public comments would trigger outbound mail with a full gateway
If no connector is set up, skip and point at the connector doc.
8. Out of scope for this demo¶
Call these out so expectations stay clear:
- Ticket reporting / charts (LSA-9068) — planned, not shipped
- Portal “create ticket” button / BFF
POST /api/tickets— intentionally omitted; catalog is the create path - Phase 1 triage (LSA-9052) — owned elsewhere; not required for this walkthrough
Quick reference checklist¶
- [ ] Terminal A:
pnpm dev:all https(7070, 7072) - [ ] Terminal B:
pnpm dev:portal:https(7071, 7073) - [ ] Queue + SLA policy created
- [ ] Catalog workflow has Ticket Queue bound
- [ ] Requester + agent accounts ready
- [ ] Catalog submit →
#Nbanner → My Tickets - [ ] Agent assign / status / public + internal comment
- [ ] SLA snooze (optional)
- [ ] Email webhook (optional)