HDFC-Loan-Desk/index.html
Yashas 2e8cc580ac feat: HDFC Loan Desk operator console
Custom frontend for the HDFC loan-origination demo (dev, org 83 / app 524,
workflow hdfc_wf_loan). MSME and personal loan files: agents assemble the
evidence, rules compute capacity, credit decides.

Stack and platform contract follow the Flight-Disruption-Management console,
which runs against this same cluster:

  * API client carries its predecessor's hard-won notes — instance_id goes
    over the wire as a NUMBER (a quoted id fails the int64 decode), org_id as
    a STRING, record views answer under `data` OR `records`, and audit rows
    need the TRIGGER_ prefix filtered or every activity appears three times.
  * VITE_ZINO_API_URL is read at RUNTIME from the config.js the server writes
    at placement, never compiled in, so one artifact is promoted between
    environments unchanged. Missing config fails loudly.
  * base: './' plus a router basename from <base href>, so one build serves
    any mount path.
  * Forms are read from the LIVE activity schema — no field definitions in
    this repo. Add a field in Studio, redeploy, it appears.

Written for this app:

  * EvidencePanel, the centrepiece. Three independent income sources side by
    side with the widest pair marked; every computed ratio shown against the
    threshold it was tested on; and a visible line between what a rule
    computed and what a model wrote (rules are never violet).
  * Queues are the one record view filtered server-side on
    current_state_name — the sidebar is the pipeline. Income variance is
    surfaced in the list, not only on the file.
  * Application 360 with the evidence panel above the offer and the sanction,
    so the screen reads in the order the decision was made.
  * HDFC palette where red is never decoration: the logo block and declines
    only. The referred queue's amber is the only amber in the pipeline.

Known gaps, documented in README rather than hidden: OCR uploads render as a
visible pending row instead of a control that pretends to work, and Credit
Assessment is still performed by a human pending the agent wiring.

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

52 lines
2.2 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--BASE_HREF-->
<title>HDFC Bank | Loan Desk</title>
<!-- The logo block as a data-URI favicon: an inline SVG needs no asset,
which matters because the build is promoted between environments
unchanged and a /favicon.ico would resolve against whatever mount path
the server chose. -->
<link
rel="icon"
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23004C8F'/%3E%3Crect x='6' y='6' width='20' height='20' fill='%23fff'/%3E%3Crect x='9' y='9' width='14' height='14' fill='%23ED232A'/%3E%3C/svg%3E"
/>
<!-- Navy chrome on mobile browsers, matching the app header. Kept in step
with the active theme by applyTheme() in src/theme.ts. -->
<meta name="theme-color" content="#004c8f" />
<!-- Theme, resolved BEFORE first paint.
This duplicates a few lines of src/theme.ts on purpose. The bundle is a
module and therefore deferred, so resolving the theme in React means
the browser paints the light default first and a dark-mode user gets a
white flash on every navigation. Blocking and inline is the only place
this can run early enough. Keep the localStorage key in step with
THEME_KEY. -->
<script>
(function () {
try {
var t = localStorage.getItem('hdfc-loan-desk-theme');
if (t !== 'light' && t !== 'dark') {
t = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
}
document.documentElement.setAttribute('data-theme', t);
if (t === 'dark') {
var m = document.querySelector('meta[name="theme-color"]');
if (m) m.setAttribute('content', '#00152b');
}
} catch (e) {
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script>
<script src="./config.js"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>