[Chore-1118] Surface duplicate client email inline error

Story 1118Epic None7 files · +117/−14

PR #306 · pramaan-io/pramaan-app · merged 2026-06-11

Why this matters

A vague 'something went wrong' is worse than no error at all.

What breaks when the form can't tell the user which field is the problem.

Generic toast can't point to a field. String parsing is not a contract.

The fix — Typed errors light up the field. Generic errors leave the user guessing.

How it flows

sequenceDiagram
  autonumber
  participant ui as Client UI
  participant bff as BFF Route
  participant gw as Gateway
  ui->>bff: Submit form
  bff->>gw: Create / update client
  gw->>bff: Typed GatewayError: email_in_use
  bff->>ui: Re-emit typed error
  ui->>ui: Map to primary email field

Files changed (7)

File±
messages/en.json+1
messages/hi.json+1
src/app/[locale]/(workspace)/clients/clients-client.test.tsx ★+47 −2
src/app/[locale]/(workspace)/clients/clients-client.tsx ★+24 −1
src/app/api/internal/clients/[clientId]/route.ts+11 −7
src/app/api/internal/clients/route.ts ★+24 −4
src/components/clients/AddClientSheet.stories.tsx+9