Clave Self-initiated Designed & built

Feedback that survives the trip to shipped

A feedback OS for B2B teams. It follows one customer request from the moment Sales files it to the revenue it moved after launch - and back to the person who raised it.

My roleEverything - domain model, IA, UI and the front-end build
Scale21 screens · 7 roles · 16 entities · 195 seeded records
StatusClickable prototype, front-end only
StackReact · TypeScript · Tailwind · Zustand
Clave's Impact screen in dark theme: four portfolio stat cards above per-feature charts where a realised revenue curve rises through a dashed expected-target line, each with an analyst note.

Shipping is not the end state. Every feature carries the revenue and churn number its PM committed to at prioritisation, and the chart keeps drawing after launch. One of the four tracked features deliberately misses its target - a demo that only shows wins isn't a demo.

The problem

Sales, Support and Success all collect feedback and it all goes somewhere different. Requests arrive without context, get grouped by hand, and whoever raised one never hears where it landed - so they stop bothering. Nothing connects a shipped feature back to the number it was supposed to move.

What I decided

  • Start after the filtering. Every input is pre-curated by a department head, so the product never asks "is this worth listening to" - only "what do we do with it, and did it work". That single scoping call removed about half the screens.
  • Model the objects before drawing anything: 16 entities, an 11-state request lifecycle, 6 feature states.
  • Make illegal states unreachable. Transitions are a declared table with roles and preconditions rather than conditions scattered through the UI - you cannot ship a feature that never had an owner, because there is no path that gets you there.
  • Closing the loop can't be something a PM remembers to do. Every transition writes the timeline entry, the plain-language comment and the notification. There is no toggle for it.
  • One navigation table drives both the sidebar and the permissions, so what you can see and what you can reach can never drift apart.

The trade-off

Guarding every transition means a PM cannot shortcut a step even when they are obviously right and the process is obviously wrong. I chose that deliberately: the failure I was designing against - requests quietly dying - is far more common than a PM being blocked for an afternoon.

A Clave request detail: a ten-node status rail running from Submitted through linked, reviewed, accepted, on roadmap, in development, Shipped, to Being tracked, beside the PM's written status update.
Clave's Insights Inbox: eighteen requests needing triage grouped by lifecycle state, with source filter chips and account context on each row.

Left - the loop, closed. Ten lifecycle nodes with who moved it and when, ending in a written update back to Sofia in Support, who filed it three months earlier. That comment is produced by the transition, not typed by a diligent PM. Right - where a PM's day starts. Requests grouped by state rather than date, because the question is never "what's new", it's "what's stuck".

Clave's leadership dashboard: expansion revenue, churn movement and features shipped, above a needs-attention queue and a Now / Next / Later roadmap snapshot.
Clave's submit form: a rich-text editor with a dictate option, type and priority pickers, attachable account context and a live preview of the resulting request card.

Same data, different job. Leadership gets money and momentum. The submitter gets a form that can be dictated mid-call and fills in its own title. Seven roles, one nav table, and no role is ever shown a link it cannot open.