All projects
Client service platform · Case studyDemo coming soon

WM Help Desk

A multi-queue help desk built for a registered investment adviser, with books-and-records controls designed in from the start: role-based access, PII redaction before anything is stored, SLA tracking and a hash-chained audit ledger.

Role
Design, engineering, rollout
Users
Client service, operations, compliance
Stack
Next.js · Prisma · Postgres
Links
Live demo soon
Live demo in progress

Overview

A multi-queue help desk built for a registered investment adviser, with books-and-records controls designed in from the start: role-based access, PII redaction before anything is stored, SLA tracking and a hash-chained audit ledger.

The problem

Client service ran on a general-purpose ticketing tool. Internal notes and client replies sat side by side, account numbers and Social Security numbers landed in free text, and there was no way to show a reviewer that a record had not been changed after the fact.

What I built

  • Queues for client service, money movement, operations and compliance, with access set by group membership.
  • Internal notes in a separate visibility channel that client-facing views cannot query.
  • PII redaction before the write, so the database never holds a full SSN or account number.
  • SLA clocks with On track, Warning and Breached states, and alerts before a breach.
  • An append-only audit ledger in which every entry carries the hash of the one before it.
  • A phone-first interface with a single layout breakpoint, since most triage happens away from a desk.

Key decisions

Redact on the way in

Masking at display time still leaves raw values in backups and exports. Redacting before the write means there is nothing to leak.

Enforce visibility where data is read

Internal notes are filtered in the query layer, so a new client-facing screen cannot expose one by accident.

Hash-chain the audit log

Each row stores the previous row’s hash. Re-verifying the chain proves no entry was edited or removed.

Write the contract first

The architecture document defines 15 invariants, each backed by a test. A change that breaks one fails CI.

Architecture

Production
Browserphone · desktop
Next.js appRBAC · redaction · SLA
Postgrestickets · audit ledger
SchedulerSLA alerts
Public demo
Cloudflare Workerhelpdesk.jeremyhamann.dev
Containersame app · demo build
Neon Postgressynthetic seed · nightly reset

Next.js · TypeScript · Prisma · Postgres · Auth.js · Vitest

The demo

The demo runs the same application with sign-in replaced by a user picker. Email intake, chat alerts and outbound webhooks are captured inside the demo instead of being sent.

Live demo in progress

This demo is being rebuilt on synthetic data. This page will link to it when it ships.

Coming soon