Commit Graph

18 Commits

Author SHA1 Message Date
141b1b2452 console: the real mark in the masthead, not type set to look like it
The brand was being drawn: a circled "Z" in Source Sans beside "ZURICH kotak"
in letter-spaced caps with "General Insurance" under it. That is a passable
imitation of a logo and not the logo — the real mark's proportions, its weight
contrast and its plate are all in the asset, which the login page has been
using all along.

So the masthead carries the artwork, at half the bar's height, and nothing is
set in type beside it: the asset already says both lines, and the wordmark
next to it was the same sentence twice. Bundled from src/assets rather than
public/, so Vite rewrites the URL relative and it resolves under the
/zurich-kotak/ mount.

On a phone the mark shrinks rather than shedding its second line — that line
is inside the artwork now, so it cannot be dropped on its own the way the type
lockup's could.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 18:55:52 +05:30
73b6ff7eb0 console: ask the support desk without leaving the console
An "Ask the desk" panel over the console, for ops only. The desk is a
platform Support App bound to app 536: it reads the deployed config and the
live book through read-only tools and answers with evidence. It is a
different kind of thing from the five AI employees — they do the work and
write to the workflow; this one only reads, to answer a person's question.

No new auth. The desk is an ordinary interactive agent, a conversation is a
session and a question is a message on it, and the token this console
already holds is accepted on those routes as-is.

Ops only, deliberately: the desk reads the WHOLE book — every partner,
every premium, every commission — so a partner agent must not open it. The
platform enforces it per user; the button just isn't drawn for anyone else.

The panel renders the markdown the desk actually uses — headings, lists,
bold, code and tables. Tables earn their place: asked anything countable it
replies with one, and rendered as raw pipes a correct answer reads like a
broken one.

Verified end to end against the database: its stage counts matched all ten
states exactly, and its account of why ZK-2026-01040 sits with the
underwriter names both PAN numbers correctly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 16:04:32 +05:30
a310b0a8b9 console: close the drawer from the link, not from an effect
Also leaves the Closed fold openable without dismissing the menu.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 13:47:28 +05:30
607693a04a console: make the phone layout work
Opened at 390px the masthead wrapped inside its own 56px bar and clipped —
"ZURICH kotak", "Lead Desk / Lead to policy" and the user's name all on
three lines each — and the nine-item rail stacked above the content, so
every page began with a screenful of menu.

The masthead now keeps one line: the mark, the app name, the person, with
the secondary lines dropped below 900px and the app name below 560px,
where it cannot fit beside the user menu without truncating.

The rail becomes a drawer behind a button, over the page rather than above
it, closing on navigation and on a tap outside. Desktop is untouched: the
button is display:none, the rail is static, and the drawer rules live
entirely inside the media query.

Also: "Ops admin", not "OPS admin" — the acronym rule over-fired on a word.

Verified at 390x844 and 1440x900: no horizontal scroll, nothing clipped in
the masthead, the drawer closes on navigation, and the desktop rail keeps
its transform and its hidden button.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 13:46:27 +05:30
79863e2a5f console: the Lead Desk redesign — one colour rule for who holds the work
Implements the design in zurich-kotak-leaddesk across every screen.

Foundation: Source Sans 3 bundled from src/assets/fonts (no Google Fonts
request), 15px root, navy/blue/amber/teal/red palette where blue is the AI,
amber a person, teal the customer and red is reserved for risk; flat white
10px cards on a grey canvas, no shadows.

Shell: 56px navy masthead (Z wordmark, Lead Desk, user), 232px white nav
grouped Needs you / Scheduled / History with coloured count pills and the
closed stages folded.

Overview: the hero says who holds each open lead (stacked bar + legend)
beside the renewals-at-risk card; five KPIs incl. Closed to date; Waiting
on a person queue with owner dots and "N more with the AI"; Pipeline by
stage with owner-coloured bars; Renewal exposure with tabs, dropdown
filters and a Holding it column.

Lead: back button, id line, holder pill; one attention banner (amber your
turn / blocked, red stalled, blue with the AI, teal with the customer) that
carries its button; four facts with a confidence bar; navy steps rail
whose current step takes its holder's colour; timeline as an avatar
gutter with title, stage pill, by-line + AI tag and text-link actions
(See reasoning · N steps, Hear the call, Open thread); side column flows.

Lists: card with search + hide-closed toggle, columns Customer / Stage /
Renewal due / Holding it / Premium / Last activity, stalled rows get a red
inset, closed rows dim, person-gated queues split into Your turn / With the
AI group rows.

src/api/holder.js is the single rule for holder tone + label so the table
cells, the overview and the lead header cannot disagree.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:56:29 +05:30
90290a8b37 console: declutter the pipeline sidebar
Five fixes to the confusing nav:

- The two per-row numbers had no key. The AI's share now reads "N with AI" in
  quiet grey, so it stops competing with the pink "needs you" badge.
- Removed the outline node circles (and the rail line they hung on) — with one
  queue per group they read as empty checkboxes, not a pipeline. Rows now align
  flush and the active queue is shown by its tint alone.
- Dropped the section-header count that just repeated the single row beneath it.
- Lightened and tightened the group labels so the queues lead, not the headers.
- Closed now matches a queue row — same padding, hover and count badge — while
  staying a foldable disclosure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 16:44:10 +05:30
e4ca2b92c9 Revert "console: redesign the UI — one card language, icons, filters, live trail"
This reverts commit e90e4204ec.
2026-09-09 11:40:49 +05:30
e90e4204ec console: redesign the UI — one card language, icons, filters, live trail
Visual and information-architecture pass across every screen. No API call,
payload, poll, permission rule or workflow mirror changes; forms still render
from the live schema and the timeline's merge/grouping is unchanged (only the
display order is reversible).

Design language
- Ground + white cards with one hairline and one radius; sentence-case
  headings; shared primitives in index.css (.card .pill .btn .avatar .live).
- One inline icon set (components/Icon.jsx); no more filled navy/red tiles.
- Read-side labels in api/display.js: roles and enum tokens humanized,
  customer initials/tones, money and date formatters. Nothing sent changes.

Shell
- 56px header with brand, global lead search (portfolio rows, "/" to focus)
  and identity chip with a human role label.
- Sidebar rows carry icons and a clear active bar; AI roster at the foot,
  each opening its remit card.

Login
- Operator copy instead of retail copy; centred sign-in card with show/hide
  password; demo persona picker that fills the EMAIL only.

Overview
- "Who holds the work" as four quiet cards that warm only when owed.
- Pipeline flow bar with every stage named beneath it; KPI strip in a card.
- Action rows with chevron / view-only eye; expiry bands filter the table.

Queues
- Filter bar (search, product, channel, expiry band, stalled, hide closed)
  and sortable columns, all client-side on the fetched page.
- Avatars, product/channel chips, stage chips for closed leads, tinted
  stalled rows, count inline with the title.

Lead
- Avatar + chips in the header; metrics card with the stage rail inside,
  and a branch node for Referred / Parked / Lost / Declined.
- Timeline newest-first by default (toggle), the worker's face as the node,
  one footer row per entry, AI markdown rendered as bold.
- "AI team on this lead" panel with per-agent step counts; PDF tags on docs.

Forms & dialogs
- Required marked with an asterisk + legend; "Select…" placeholder; dd Mon
  yyyy hint under date inputs; open activity form in a titled panel;
  one-line dialog footnotes.

Fixes: horizontal overflow at 1024px, boxed "in N days" figure, raw tokens
(sme_underwriter, verbal_call, Rsa), findings cut at "1.".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 11:37:42 +05:30
de8b158ca9 console: the nav navigates, and the screens act
"New lead" sat in the sidebar. A sidebar is for moving between places;
filing a lead is an action, and an action in a list of destinations is
the one item that does not behave like its neighbours — everything above
and below it changes what you are looking at, and it did something.

It now sits on the overview and on every queue, beside the lists it adds
to, which is also where somebody is standing when they realise they have
a lead to file. Same role gate as before: shown only to a user who holds
an entry door.

The sidebar's own button CSS went with it rather than being left for
someone to wonder about.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 18:31:07 +05:30
5ff74ea22d console: numbers in the navigation, and reasoning behind one click
THE SIDEBAR NOW CARRIES COUNTS. It deliberately did not, on the argument
that a tally could only come from a second full list call that would then
disagree with the queue's own total. Right about the cost, wrong about
the conclusion: with no numbers the only way to learn whether anything
was waiting on you was to open all nine queues in turn, which is the
question navigation exists to answer.

There is no second call. The overview's existing fetch moved into a
PortfolioProvider that both surfaces read, so this is one call fewer than
before and the two agree by construction. Bounded at 200 rows, as the
overview always was; past that the honest answer is an aggregate
endpoint, not a bigger limit.

What the badge counts is what needs a PERSON — phaseOf again, so a lead
whose documents are in and whose AI chain is running is reported beside
the badge rather than inside it. An amber dot marks a queue holding a
renewal inside a week, which is the only reason to open one queue before
another and was previously invisible. Zero is shown rather than hidden:
"nothing here" is an answer, and a queue that disappears when it empties
makes the sidebar move under the cursor.

Closed is folded into a summary. Three of the twelve queues, opened about
once a week, and at equal weight they made the live ones harder to find.

REASONING OPENS IN A DIALOG, NOT INLINE. The audit rail is 320px wide
with one entry per step, and a 1,500-character rationale expanding in
place pushed a lead's whole history off screen to read one sentence of
it. Nobody reads a paragraph in a sidebar. The finding — the AI's own
first sentence, which is already the conclusion — stays on the line; the
working is one click away and one Escape back, headed by what is being
read ("Call — Log Contact") rather than by nothing. Escape closes, the
page behind does not scroll, and focus returns to the button that opened
it so a keyboard reader keeps their place.

Two headings that described the container rather than the contents:
Record → "Lead file", and the audit trail's subtitle now says what a
reader gets from it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 12:42:40 +05:30
6a6801d2bd console: all-leads view, document form prefill, and two things that should not be offered
Four operator-reported issues, one commit because two of them are about
the same form.

ALL LEADS WAS GONE. The team's rewrite of the queue screen dropped the
/stage/all view, so finding a lead meant guessing which of nine queues
it sat in. Restored: no stage filter, closed leads dropped client-side,
one request for the whole open book. Linked under Overview in the
sidebar so it is one click from anywhere.

THE DOCUMENT FORM ASKED FOR WHAT THE LEAD ALREADY KNEW. Collect
Documents mirrors fourteen record fields — registration, make and model,
previous insurer, expiry, policy number, PAN — so the OCR has somewhere
to write. Rendered blank, they read as fourteen more things to type, on
a form whose whole point is uploading three files. They are now seeded
from the lead by base key: an agent uploading for KA01MF6618 sees
KA01MF6618 already there. Server prefill wins, then anything typed;
files and generated ids are never seeded, and an INIT form has no
record to seed from. SME-only fields were already hidden on a motor
lead by fieldLine — that half was working.

"SEND A REMINDER" IS THE SCHEDULER'S JOB, NOT A BUTTON. It fires at
24h, 72h and 120h on its own. Offering it as a loop action invited a
person to send a reminder the platform was already about to send. It
and Retry Call move to `force` — reachable behind "Lead not moving?"
for the day the schedule itself fails, and otherwise out of sight.

THE UPLOAD STAYED THE "NEXT STEP" AFTER THE UPLOAD. Once
documents_status is complete the lead remains in Document Pending while
Engage captures the risk and the quote is built — and the panel kept
saying "Upload documents", which reads as though nothing was received.
Now, when complete, the upload becomes a loop (a fourth document, a
correction) and the panel says what is actually happening: documents
received, Engage AI is capturing the risk and preparing the quote.

Permissions unchanged; ACTIONS still matches
tbl_wf_state_allowed_activities exactly.
2026-09-07 19:26:13 +05:30
aca5d1a043 console: role-scoped access, portfolio analytics, enterprise register
Four things, and the first is the one that mattered.

ROLE-BASED ACCESS. The console showed every action to everyone on
purpose — "the refusal is the demo" — and the workflow refused
server-side. That is a defensible engineering position and a poor
product: an underwriter saw a row of six buttons, five of which 403.

src/api/permissions.js now mirrors tbl_wf_activity_permissions, and the
session already carries user.roles, so nothing new had to be fetched.
Action buttons, sidebar queues and the entry doors are all filtered.
It remains presentation only — the platform still refuses, and a role
added there but missing here hides a button that would have worked,
which is the failure mode to watch.

Each role's app now looks like their job. Ops sees the whole board and
still cannot clear a referral. An underwriter sees one queue and two
buttons. Agents see the three queues they work in. Reporting is NOT
gated: the overview counts the whole portfolio for everyone, because an
agent tracking leads they filed is reasonable and acting on them is not.

One deliberate divergence from the workflow, commented where it lives:
the two scheduled activities carry no roles at all, because that is the
only configuration under which the scheduler can perform them. Open to
the SYSTEM is not open to everyone signing in, so the UI narrows them —
otherwise an underwriter is offered "Send Document Reminder".

ANALYTICS. The overview was three lists. It is now a measured page:
open leads, pipeline value, written premium, conversion, commission —
then renewal exposure in three buckets, the queues needing a person with
the age of the oldest item in each, and stage distribution as bars.

Checked against the live book rather than assumed, which found a real
bug before it shipped: Policy Issued is written business AND not yet
terminal, so its premium was counted in pipeline and production both.
₹42,912 double counted on 37 leads. Pipeline now excludes anything
already on risk.

The lead page gained the same treatment: renewal countdown, lead age,
time in current stage, premium, commission, AI confidence. Age and
dwell are computed — neither is on the record, and they are the two
figures that answer "is this moving?", which no field could.

TERMINOLOGY. The previous pass over-corrected: fixing builder jargon
("the workflow decides, server-side") produced chat ("What you can do",
"The agents have it", "Nothing here right now"). Neither is how an
operations console reads. Now: Actions · Record · Audit trail · Action
required · Customer response · Automated · Scheduled · Document
collection · Underwriting referral · Premium confirmation.

LAYOUT. Prose subtitles cut to one line or removed. Measures render as
tabular figures in a bordered strip instead of label/value pairs. The
overview splits into work on the left and distribution on the right.
Stage bars replace a wall of equal-weight cards.

Pre-existing lint errors unchanged at 11; none in the new files.
2026-09-07 16:31:04 +05:30
4c210c7e09 console: a page to monitor from, and words an operator would use
Three problems, and the first one is the reason the other two were hard
to see.

THERE WAS NO DASHBOARD. "/" redirected to the underwriting queue — one
stage, usually empty, and belonging to somebody else. Every screen in
the app answered "show me this queue"; none answered "how is the book
doing, and is anything waiting on me?", which is the only question a
person has before they have picked a queue.

So: a Today page. Three blocks, in the order somebody cares about them.
What is waiting on a person, as three cards that colour only when they
have something in them. Renewals running out, worst first, capped at 30
days because a renewal six months away is not a thing to look at today.
Then every stage with its count, zeroes included — a stage quietly
receiving nothing is only visible if its zero is on screen.

It is one list call, counted in the browser. That is honest at this size
and it is the same call the queues already make. If the book outgrows it
the answer is a counts endpoint, not a bigger page.

THE WORDS WERE WRITTEN FOR WHOEVER BUILT THE WORKFLOW. "What happens
next" was followed by "these are the only activities this state allows
— but the workflow decides, server-side, whether you may". A failed list
said "this queue has no record view yet". Panels were called "Flow
details". A closed lead read "nothing runs from here". None of that is
wrong; all of it is addressed to the wrong reader.

Now: "What you can do", "Lead details", "History", "This queue could not
be loaded". Queue names say what they want — "Documents needed",
"Underwriter to review", "Payment to confirm". The sidebar group called
"Not yet" says "Not due yet", and "Running by itself" says "The agents
have it", which is the actual claim being made.

THE QUEUE HAD NINE COLUMNS AND LED WITH THE WRONG ONE. Two were internal
vocabulary: attribution status renders "clear" or "contested" and means
nothing to an operator, and the channel is background rather than
something anyone scans a queue for. Both fold into a subtitle under the
customer. That leaves six columns and puts the renewal countdown — the
number that decides whether to act today — second instead of fifth.

Also: the timeline printed a raw slug when a step came back without a
name. It is the screen this product is demonstrated on, so a
"zk-act-doc-reminder" in the middle of an otherwise readable story is
expensive. It now reads as English.
2026-09-07 16:13:13 +05:30
Likith K R
66ea08e317 Updated to new frontend specifications 2026-09-04 13:26:20 +05:30
Likith K R
ae548a3a10 UI Enhancements in recordsview and detailsview 2026-09-02 15:33:26 +05:30
5ea627b064 Make the console operable: add a lead, work a lead
The pipeline could be looked at but not driven. Adds the three pieces
that make the machine walkable end to end from the UI.

- ActivityForm renders whatever /view/form-screens returns — labels,
  types, select options, mandatory flags — and submits it back. No form
  is defined in this repo, so a field added in Studio appears here with
  no code change.
- AddLead presents the three doors. Each is a separate INIT activity with
  its own permissions; the bank one lands further along because the bank
  already did CKYC.
- Lead shows the file grouped in the order it was worked, ending with
  what the sourcing agent earns, plus the activities this state allows
  and who normally performs each.

The "who normally performs this" label is presentational only. Nothing
here enforces anything — the workflow refuses server-side and the form
reports what it said, including a note when a 403 is the platform
declining rather than the console misbehaving.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 16:11:28 +05:30
49cfdc8c00 Show the signed-in role in the header
RBAC is what this demo argues, so which persona you are signed in as
should never be a guess while presenting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 15:21:00 +05:30
9210681488 Wire the console to the platform and make it deployable
The scaffold had the brand right and nothing behind it: the login was a
600ms setTimeout with a TODO, and three pieces of the frontgen deploy
contract were missing.

- Sign in against POST /usr/login (org_id as a STRING — a number is
  rejected by the gateway) with the session in a provider; surface the
  gateway's own message rather than a generic "invalid credentials",
  because a wrong password and a user without access to this app look
  identical from here and are not.
- Runtime config: the API URL is read from the config.js the server
  writes at placement, never compiled in, and requireConfigValue throws
  so a build with no config.js fails loudly instead of calling whichever
  backend built it.
- base: './' plus a router basename taken from <base href>, so one build
  serves any mount path.
- Move the fonts and logo from public/ into src/assets/ — Vite rewrites
  bundled asset URLs to be relative, while a public/ file referenced as
  "/fonts/..." stays absolute and 404s under the /zurich-kotak/ mount.
- API client for recordview / detailview / form-screens / start /
  activity, and the pipeline shell whose sidebar is the state machine in
  the order a lead moves.

Queue and lead-file data wait on the record and detail views.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 15:20:13 +05:30