From 6455579cc2153688865be5c9869413aa78e4395e Mon Sep 17 00:00:00 2001 From: Yashas Date: Thu, 10 Sep 2026 16:50:48 +0530 Subject: [PATCH] The Lead Desk, written for a phone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A separate app from the desktop console, talking to the same platform with the same client. Not a breakpoint on the old one: the two answer different questions. The console answers "what is the state of the book?" across a wide grid; a phone answers "what needs me, and what happened to this one?" in a column you scroll with a thumb. The old console at 390px showed why. Tables scrolled sideways, nine queues stacked above the content ate the first screenful, and the action you came to perform sat below the fold. So every row of every table is a CARD — customer, stage, when it is due, who is holding it, and one line about what is happening. Everything else is one tap away. The queues live in a drawer. The action a lead is waiting on is pinned to the bottom of the screen, where a thumb already is. Shared with the console, because a divergence would be two apps disagreeing about the same lead: the whole api/ layer, ActivityForm, and Timeline — whose audit-row merging (one submission writes three rows) is hard-won and must not be reimplemented twice. Written fresh: the shell, the three screens, and the stylesheet. The colour rule is unchanged and is the product in four colours: blue the AI holds it, amber a person, teal the customer, red risk and nothing else. A PWA, so Add to Home Screen gives a full-screen app; the layout pads for the notch and the home indicator. Verified at 402x874: login, overview, drawer, a queue, and a lead, with no horizontal overflow on any of them. Co-Authored-By: Claude Opus 5 (1M context) --- .env.example | 1 + .gitignore | 4 + README.md | 63 + eslint.config.js | 21 + index.html | 21 + package-lock.json | 2505 +++++++++++++++++ package.json | 28 + public/brand/zurich_logo.webp | Bin 0 -> 12418 bytes public/config.js | 3 + public/manifest.webmanifest | 14 + src/App.jsx | 39 + src/api/agents.js | 108 + src/api/client.js | 267 ++ src/api/config.js | 576 ++++ src/api/errors.js | 130 + src/api/holder.js | 36 + src/api/lead.js | 163 ++ src/api/permissions.js | 159 ++ src/api/portfolio.jsx | 109 + src/api/provider.jsx | 51 + src/api/thread.js | 216 ++ src/assets/brand/zurich_logo.webp | Bin 0 -> 12418 bytes .../source-sans-3-latin-400-normal.woff2 | Bin 0 -> 15696 bytes .../source-sans-3-latin-500-normal.woff2 | Bin 0 -> 15652 bytes .../source-sans-3-latin-600-normal.woff2 | Bin 0 -> 15668 bytes .../source-sans-3-latin-700-normal.woff2 | Bin 0 -> 15596 bytes .../source-sans-3-latin-ext-400-normal.woff2 | Bin 0 -> 33024 bytes .../source-sans-3-latin-ext-500-normal.woff2 | Bin 0 -> 32940 bytes .../source-sans-3-latin-ext-600-normal.woff2 | Bin 0 -> 32704 bytes .../source-sans-3-latin-ext-700-normal.woff2 | Bin 0 -> 32956 bytes src/components/ActivityForm.css | 398 +++ src/components/ActivityForm.jsx | 402 +++ src/components/AgentChip.css | 44 + src/components/AgentChip.jsx | 84 + src/components/ChainOfThought.css | 32 + src/components/ChainOfThought.jsx | 87 + src/components/ClampText.css | 168 ++ src/components/ClampText.jsx | 128 + src/components/FileField.jsx | 113 + src/components/LeadCard.jsx | 105 + src/components/Timeline.css | 134 + src/components/Timeline.jsx | 675 +++++ src/layout/Shell.jsx | 160 ++ src/main.jsx | 25 + src/pages/Login.css | 324 +++ src/pages/Login.jsx | 209 ++ src/runtimeConfig.js | 53 + src/screens/Lead.jsx | 347 +++ src/screens/Leads.jsx | 147 + src/screens/Overview.jsx | 264 ++ src/styles/app.css | 459 +++ src/styles/tokens.css | 181 ++ vite.config.js | 14 + 53 files changed, 9067 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 README.md create mode 100644 eslint.config.js create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/brand/zurich_logo.webp create mode 100644 public/config.js create mode 100644 public/manifest.webmanifest create mode 100644 src/App.jsx create mode 100644 src/api/agents.js create mode 100644 src/api/client.js create mode 100644 src/api/config.js create mode 100644 src/api/errors.js create mode 100644 src/api/holder.js create mode 100644 src/api/lead.js create mode 100644 src/api/permissions.js create mode 100644 src/api/portfolio.jsx create mode 100644 src/api/provider.jsx create mode 100644 src/api/thread.js create mode 100644 src/assets/brand/zurich_logo.webp create mode 100644 src/assets/fonts/source-sans-3-latin-400-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-500-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-600-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-700-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-ext-400-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-ext-500-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-ext-600-normal.woff2 create mode 100644 src/assets/fonts/source-sans-3-latin-ext-700-normal.woff2 create mode 100644 src/components/ActivityForm.css create mode 100644 src/components/ActivityForm.jsx create mode 100644 src/components/AgentChip.css create mode 100644 src/components/AgentChip.jsx create mode 100644 src/components/ChainOfThought.css create mode 100644 src/components/ChainOfThought.jsx create mode 100644 src/components/ClampText.css create mode 100644 src/components/ClampText.jsx create mode 100644 src/components/FileField.jsx create mode 100644 src/components/LeadCard.jsx create mode 100644 src/components/Timeline.css create mode 100644 src/components/Timeline.jsx create mode 100644 src/layout/Shell.jsx create mode 100644 src/main.jsx create mode 100644 src/pages/Login.css create mode 100644 src/pages/Login.jsx create mode 100644 src/runtimeConfig.js create mode 100644 src/screens/Lead.jsx create mode 100644 src/screens/Leads.jsx create mode 100644 src/screens/Overview.jsx create mode 100644 src/styles/app.css create mode 100644 src/styles/tokens.css create mode 100644 vite.config.js diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4f321e6 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +VITE_ZINO_API_URL=https://dev.getzino.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01473fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +.env +*.local diff --git a/README.md b/README.md new file mode 100644 index 0000000..48b325d --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# Zurich Kotak — Lead Desk (phone) + +The renewal desk on a phone. A separate app from the desktop console +(`zurich_kotak`), talking to the same platform with the same API client. + +## Why a second app rather than a breakpoint + +The two answer different questions. The desktop console answers *"what is the +state of the book?"* across a wide grid — six-column tables, a lead beside its +record, a rail of queues always visible. A phone answers *"what needs me, and +what happened to this one?"* in a column you scroll with a thumb. + +Squeezing the first into 390px produced what it always produces: tables that +scroll sideways, a menu that eats the first screenful, and a primary action +somewhere below the fold. So the screens are written for the phone, and only +the parts that must not diverge are shared. + +## What is shared, and what is not + +**Copied verbatim, because it is the contract with the platform** — a +divergence here would be two apps disagreeing about the same lead: + + src/api/client.js every call + src/api/config.js stages, actions, doc slots, the workflow mirror + src/api/permissions.js who may perform what + src/api/portfolio.jsx the one record-view call the queues share + src/api/holder.js who is holding a lead + src/api/lead.js how to read a date, name a field, group the record + src/components/ActivityForm.jsx, FileField.jsx, Timeline.jsx + +`Timeline.jsx` in particular is shared on purpose: its audit-row merging (one +submission writes three rows) is hard-won, and reimplementing it here would +mean two different accounts of the same history. + +**Written fresh for the phone:** every screen, the shell, and the stylesheet. + +## The colour rule + +Unchanged from the console, and it is the whole product in four colours: + + blue the AI is holding it + amber a person is holding it + teal the customer is holding it + red risk — and nothing else + +A lead that is amber on a laptop must be amber on a phone. + +## Run it + + npm install + npm run dev # http://localhost:5176 + +`VITE_ZINO_API_URL` in `.env` for local dev only. In a deployed build the API +host is read at RUNTIME from the `config.js` the server writes when it places +the build — never compiled in, so one artifact is promoted between +environments unchanged. + +## Installing it + +It is a PWA: `manifest.webmanifest`, a standalone display mode, and the navy +theme colour, so Add to Home Screen gives a full-screen app with no browser +chrome. The layout pads for the notch and the home indicator through +`env(safe-area-inset-*)`. diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..ea36dd3 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,21 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + globals: globals.browser, + parserOptions: { ecmaFeatures: { jsx: true } }, + }, + }, +]) diff --git a/index.html b/index.html new file mode 100644 index 0000000..685a075 --- /dev/null +++ b/index.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + + Zurich Kotak — Lead Desk + + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..19b4ca5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2505 @@ +{ + "name": "zurich_kotak_pwa", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "zurich_kotak_pwa", + "version": "0.0.0", + "dependencies": { + "react": "^19.2.8", + "react-dom": "^19.2.8", + "react-router-dom": "^7.18.2" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", + "@vitejs/plugin-react": "^6.1.0", + "eslint": "^10.9.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.4", + "globals": "^17.11.0", + "vite": "^8.2.2" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.5.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.5.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz", + "integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@oxc-project/types": { + "version": "0.149.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.149.0.tgz", + "integrity": "sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.8.tgz", + "integrity": "sha512-tN5aztYkKCte4i5SIrrz5yK/HMjEuCqCSCJa418jOV8tZ1cBY3YF2otxB1ktPxzsLA1BeTqwapK0bfjxNvHJVw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.8.tgz", + "integrity": "sha512-dIYTWl9XprMUiQFoc55KUyk/oS8SKYH3zFl0LTR7RT0Xj4hgSVyuJcroH8JUu8RcpF8fTB6E0aOwCkZoYPcDSQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.8.tgz", + "integrity": "sha512-PCSDQGXD2IyTEFrcgPyBM8jJuGmrbCMuoIOXdbEGVemruKACXoLQJrb+A45Z0L5t1RQkdfJprAYPkikbh7dzdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.8.tgz", + "integrity": "sha512-Uk7lRsGhPFHVX/sAUC6D5H9Ol30dFHd6iquokll2th3LpdJ3F5CzQB+7DHn0Ri2mG+U7k2zXiPHDrwZenXhwSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.8.tgz", + "integrity": "sha512-DjszaTEVogPqA5bYzsEeqDCQxbcp2fexQwKcRspYji2yzR68fCf+e4fx6kBSRDwX5/brZaHw/hWS9+A/+/w9sQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.8.tgz", + "integrity": "sha512-zmwa7FTmdzB6aaEEuuls18H6Ap5JmJPSoPTuXixeJZV6tG40SyLkApQtz1g8ptZtiEKqj9OM0oNLPh1AgvE31Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.8.tgz", + "integrity": "sha512-KdYQDPHwJVnbFwdTGMgxsI9SqblBlz6STGM+w1We/d5B8OWWidYH0MwkU/uA1wM5fIpO2MkOVxXrNzzuZhw9ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.8.tgz", + "integrity": "sha512-jFJTifHnNPY+yzOoNZQfSIysrVyXzEQPhPnOUjmD1bcQGHH6s7c8cViKWar8YplQImE5N9JRqMCLrM2CdxOrZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.8.tgz", + "integrity": "sha512-FhiOziBDWPBjbcmRzfLyIJnaP7AVMFXT7YCXPjXxj7wKU3vx24RjrCNN/zjvVa+N2vVoHJwCoUBvsrN/DG3zIA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.8.tgz", + "integrity": "sha512-WnHfADMzOV2Y55wlx1hzzQnar/wDt/VdvWSD99r18Mz9ylNieIGOkRx3UV21h7m/eJvjySYJkO26VvGNFkwsIQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.8.tgz", + "integrity": "sha512-H9tRr5ibfXFVLxbPOseVewewFpl28zcEdjRDt2FTUZU7odxP0gEv1ki4/kGmcGOh78oRwZuuQllGLZ9zTJp84g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.8.tgz", + "integrity": "sha512-UefiqfM3D6IVNlZ8tSGs9+Ejjud2T+oxO0IHADU45Y+lyEjD2dVFyZHbkfX0LUb5Zugo/oIv1eCO/KVYhgYJYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.8.tgz", + "integrity": "sha512-637Ke4kWSy6rp9cxQ9gMOXlxPgIw/c1beASV4M//3+9I4uwBVOOl74G+e3zyU3u19U7RkRl/HuewixZ/Z6+Rjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.8.tgz", + "integrity": "sha512-xWBkPOF1Q9k/Gv1nQXnVdLxKu74jXppuOM4Z3mnypVUJJJwLsMl7hNJGRAUJoG8A5MgOI1ACKM+wBFxSJzKy4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.8.tgz", + "integrity": "sha512-uz2ZvfgXbxqNwijjjbxrnvALwpyODDcgc1T1N8N3rf/DXKQmaFwmB4LX4yyjggpwN2obdQLb2rgirX5ffCWYng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.1.tgz", + "integrity": "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.145.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.21.tgz", + "integrity": "sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz", + "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.20", + "caniuse-lite": "^1.0.30001810", + "electron-to-chromium": "^1.5.420", + "node-releases": "^2.0.54", + "update-browserslist-db": "^1.3.2" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/cacheable": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.426", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.426.tgz", + "integrity": "sha512-2Gcq6inCQs/AqfHP3f5ftCzk+pqeW2VlA1LgmPqEj2hfBO8HiZRspNYkD4HzFBe4u6lGqca4BspFr6Ix4Q400g==", + "dev": true, + "license": "ISC" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.10.0.tgz", + "integrity": "sha512-NPXn6r5zl4uET1DAVPaOwzX3rut4c0wcmw3dWJAfOsTM5+TogXo0DDjz8pwm/hL8cyVNpHqeK4JpN0NjnyFFNw==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.7.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "11.1.5 || >11.1.6 <12", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.6.tgz", + "integrity": "sha512-uZnh24On2bk478AkaDAKcpRiYhS3qFSaSNvpXxV6/Ek/BBDICkWGG7MnBSfjnIlCVBei5vsLlIeQYxbF22+Udg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^6.1.23" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cacheable": "^2.5.0", + "flatted": "^3.4.2", + "hookified": "^1.15.0" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz", + "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.15.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.55", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.55.tgz", + "integrity": "sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qified": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^2.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/qified/node_modules/hookified": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", + "dev": true, + "license": "MIT" + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/react-router": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.3.tgz", + "integrity": "sha512-gyXgtdr5uACJ5b1Q4udzjVV+tb/rlHIMJKuJ0e89R4Kzgz47z/rgP0dIKxktqIEUhDHluGTPJJH/wRha7CyqsA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.3.tgz", + "integrity": "sha512-ytVbyBBM7vMfRCam25r0WMhSVSom909A8p+8m0/f1w853dz/xfFu6etAT2SEbVoSnI+ZoPRDqIsQXVT89gp7kg==", + "license": "MIT", + "dependencies": { + "react-router": "7.18.3" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/rolldown": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.8.tgz", + "integrity": "sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.149.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.8", + "@rolldown/binding-android-arm64": "1.2.8", + "@rolldown/binding-darwin-arm64": "1.2.8", + "@rolldown/binding-darwin-x64": "1.2.8", + "@rolldown/binding-freebsd-x64": "1.2.8", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.8", + "@rolldown/binding-linux-arm64-gnu": "1.2.8", + "@rolldown/binding-linux-arm64-musl": "1.2.8", + "@rolldown/binding-linux-ppc64-gnu": "1.2.8", + "@rolldown/binding-linux-s390x-gnu": "1.2.8", + "@rolldown/binding-linux-x64-gnu": "1.2.8", + "@rolldown/binding-linux-x64-musl": "1.2.8", + "@rolldown/binding-openharmony-arm64": "1.2.8", + "@rolldown/binding-win32-arm64-msvc": "1.2.8", + "@rolldown/binding-win32-x64-msvc": "1.2.8" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz", + "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.1.tgz", + "integrity": "sha512-341aRWQsve0rvronKNTqZpjmzdbUDlFuzHaI/XLg/Ej82qffDJRRfBTCuv7+9q/rMjB6LSLyEBnW4InJeMtt/Q==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c3ff658 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "zurich_kotak_pwa", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.2.8", + "react-dom": "^19.2.8", + "react-router-dom": "^7.18.2" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", + "@vitejs/plugin-react": "^6.1.0", + "eslint": "^10.9.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.4", + "globals": "^17.11.0", + "vite": "^8.2.2" + } +} diff --git a/public/brand/zurich_logo.webp b/public/brand/zurich_logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..6f5c27ee2a8861a6e17d4b5b4bebd74348d57965 GIT binary patch literal 12418 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 + } /> + } /> + + ) + } + + return ( + + } /> + }> + } /> + } /> + } /> + } /> + + + ) +} diff --git a/src/api/agents.js b/src/api/agents.js new file mode 100644 index 0000000..9972cb0 --- /dev/null +++ b/src/api/agents.js @@ -0,0 +1,108 @@ +/** + * The AI employees, as people the operator can recognise. + * + * Five agents carry this workflow and the console referred to them by their + * role slug or their full title, differently in each place — "ai_engage" in one + * view, "Engage" in another, "Engage AI" in a third. Someone watching a lead + * move could not tell that the thing which called the customer and the thing + * which wrote the quote were the same worker. + * + * So: one roster, one short name, one colour, one initial. Used wherever an + * agent is named. `does` is written in the present tense and in the operator's + * words, not the charter's — it appears on hover and in the roster strip, and + * it is what makes an unfamiliar name mean something the first time. + * + * `tools` and `knowledge` are a MIRROR of the employee config in + * aiemployee.tbl_ai_employees. The app frontend cannot read the agents schema, + * so this is hand-maintained the way STAGES and ACTIONS are, and carries the + * same hazard: a tool added or removed there and not here is described wrongly + * in the UI, silently. + * + * Worth the trade, because "what can this thing actually do?" is the first + * question anyone watching an agent asks — and the honest answer is short and + * reassuring: four of the five hold no tools at all and work from the policy + * wordings. The one tool that exists only reads a partner registry. Nothing + * here can move money, and since 89 nothing here can telephone anybody. + * + * Keyed by the ROLE, because that is what an audit row carries. + */ +export const AGENTS = { + ai_intake: { + icon: 'inspect', + short: 'Intake', + full: 'Intake & Attribution', + initials: 'IA', + tone: 'violet', + does: 'checks the lead is real, scores it, and works out whose it is', + wakes: 'Once, the moment a lead is filed.', + tools: [ + { + name: 'lookup_partner', + does: 'Reads the partner registry by partner code and reports whether that POSP, broker or corporate agent is active and empanelled for this product.', + }, + ], + knowledge: ['Products, UINs & Commission', 'SME Package (BSUS / BLUS)', 'Motor (Car Secure)'], + }, + + ai_engage: { + icon: 'chat', + short: 'Engage', + full: 'Engage', + initials: 'EN', + tone: 'blue', + does: 'talks to the customer, writes up the call, and asks for what is missing', + wakes: 'Most often of the five: after the call ends, after documents land, after the Advisor reports, when the premium falls due, and on every WhatsApp reply.', + tools: [], + knowledge: ['SME Package (BSUS / BLUS)', 'Motor (Car Secure)', 'Motor Renewal Sales Desk'], + }, + + ai_advisor: { + icon: 'shield', + short: 'Advisor', + full: 'Advisor', + initials: 'AD', + tone: 'teal', + does: 'reads the captured risk and recommends the cover and add-ons', + wakes: 'Once, as soon as the risk has been captured.', + tools: [], + knowledge: ['Products, UINs & Commission', 'SME Package (BSUS / BLUS)', 'Motor (Car Secure)', 'Motor Renewal Sales Desk'], + }, + + ai_kyc: { + icon: 'id', + short: 'KYC', + full: 'KYC & Evidence', + initials: 'KY', + tone: 'amber', + does: 'verifies identity and screens the risk for underwriting', + wakes: 'Twice: when the customer accepts, and again to run the underwriting screen.', + tools: [], + knowledge: ['Products, UINs & Commission', 'SME Package (BSUS / BLUS)', 'Motor (Car Secure)'], + }, + + ai_uw_referral: { + icon: 'scales', + short: 'Referral', + full: 'Underwriting Referral', + initials: 'UW', + tone: 'plum', + does: 'prepares a referred file so a human underwriter can decide', + wakes: 'Once, and only when the screen refers the risk.', + tools: [], + knowledge: ['Products, UINs & Commission', 'SME Package (BSUS / BLUS)', 'Motor (Car Secure)'], + }, +} + +/** The agent behind a set of roles, or null when a person did it. */ +export function agentFor(roles) { + if (!Array.isArray(roles)) return null + const key = roles.find((r) => AGENTS[r]) + return key ? { key, ...AGENTS[key] } : null +} + +/** Initials for a person, so a human entry reads as a name too. */ +export function initialsOf(name) { + const parts = String(name || '').trim().split(/\s+/).filter(Boolean) + if (!parts.length) return '—' + return (parts[0][0] + (parts.length > 1 ? parts[parts.length - 1][0] : '')).toUpperCase() +} diff --git a/src/api/client.js b/src/api/client.js new file mode 100644 index 0000000..8d456a0 --- /dev/null +++ b/src/api/client.js @@ -0,0 +1,267 @@ +import { APP_ID, WORKFLOW } from './config' + +const TOKEN_KEY = 'zk_lead_desk_token' +const USER_KEY = 'zk_lead_desk_user' + +/** + * HTTP client for the Zino gateway. + * + * Most routes are app-scoped (`/app/536/...`); login is not. The JWT persists + * in localStorage so a refresh does not bounce the operator back to the login + * screen mid-review. + */ +export class ZinoClient { + constructor(baseUrl, onAuthError) { + this.baseUrl = String(baseUrl).replace(/\/+$/, '') + this.token = null + this.onAuthError = onAuthError + if (typeof window !== 'undefined') this.token = localStorage.getItem(TOKEN_KEY) + } + + setAuthErrorHandler(fn) { this.onAuthError = fn } + + setToken(token) { + this.token = token + if (typeof window === 'undefined') return + if (token) localStorage.setItem(TOKEN_KEY, token) + else localStorage.removeItem(TOKEN_KEY) + } + + getToken() { return this.token } + + setStoredUser(user) { + if (typeof window === 'undefined') return + if (user) localStorage.setItem(USER_KEY, JSON.stringify(user)) + else localStorage.removeItem(USER_KEY) + } + + getStoredUser() { + if (typeof window === 'undefined') return null + try { return JSON.parse(localStorage.getItem(USER_KEY) || 'null') } catch { return null } + } + + async request(method, path, body) { + const headers = { 'Content-Type': 'application/json' } + if (this.token) headers['Authorization'] = `Bearer ${this.token}` + + const res = await fetch(`${this.baseUrl}${path}`, { + method, + headers, + body: body !== undefined ? JSON.stringify(body) : undefined, + }) + + if (res.status === 401) { + this.setToken(null) + this.setStoredUser(null) + this.onAuthError?.() + throw { status: 401, message: 'Session expired — sign in again' } + } + if (!res.ok) { + let message = res.statusText + try { + const j = await res.json() + message = j.error || j.message || message + } catch { /* non-JSON body */ } + throw { status: res.status, message } + } + if (res.status === 204) return undefined + return res.json() + } + + /* ── The support desk ──────────────────────────────────────────────────── + Not app-scoped: these are the platform's own agent routes, and the token + this console already holds is accepted on them as-is. A conversation is a + session; a question is a message on it. */ + + /** This operator's conversations with the desk, newest first. */ + deskSessions(agentId) { + return this.request('GET', `/api/agent-sessions?agent_id=${agentId}`) + } + + /** Open a new conversation. */ + deskStartSession(agentId) { + return this.request('POST', '/api/agent-sessions', { agent_id: agentId }) + } + + /** The transcript of one conversation. */ + deskMessages(sessionId) { + return this.request('GET', `/api/agent-sessions/${sessionId}/messages`) + } + + /** + * Ask. Answers with the rows the backend persisted for the turn — + * { user_message, call_api_message, agent_message } — not a bare string. + * + * These take twenty to forty seconds: the desk runs real queries against the + * book before it answers. The caller has to say so, or the panel looks hung. + */ + deskAsk(sessionId, content) { + return this.request('POST', `/api/agent-sessions/${sessionId}/messages`, { content }) + } + + /** + * org_id must be a STRING. The gateway rejects a number with + * "cannot unmarshal number into Go struct field LoginRequest.org_id". + */ + async login(email, password, orgId) { + const res = await this.request('POST', '/usr/login', { + email, + password, + org_id: String(orgId), + }) + if (res?.token) { + this.setToken(res.token) + this.setStoredUser(res.user || null) + } + return res + } + + logout() { + this.setToken(null) + this.setStoredUser(null) + } + + /** + * Paginated records for a record view, filtered server-side. + * + * The POST body is NOT the same shape as the GET query params: the view is + * named by `rv_template_uid` (not `rv_id`, which is the GET spelling), and + * paging/sort/filters all live INSIDE `search_query`. Sending them at the top + * level returns `400 Missing param: rv_template_uid (body)`. + */ + recordView(rvUid, params = {}) { + return this.request('POST', `/app/${APP_ID}/view/recordview`, { + rv_template_uid: rvUid, + search_query: { + page: params.page ?? 1, + limit: params.limit ?? 50, + sort_by: params.sort_by ?? '', + sort_dir: params.sort_dir ?? 'desc', + search: params.search ?? '', + filters: (params.filters ?? []).map((f) => ({ + field_key: f.field_key, + value: f.value, + value2: '', + data_type: f.data_type ?? 'string', + })), + }, + }) + } + + /** + * Rows only. The response key differs by source type — workflow views return + * `data`, rdbms views have been seen returning `records`. + */ + async rows(rvUid, params = {}) { + const r = await this.recordView(rvUid, params) + return r?.data ?? r?.records ?? r?.rows ?? [] + } + + detailView(dvUid, instanceId) { + return this.request( + 'GET', + `/app/${APP_ID}/view/detailview/${dvUid}?instance_id=${encodeURIComponent(String(instanceId))}`, + ) + } + + /** + * The LIVE definition of an activity's form: fields, types, select options, + * which are mandatory. Read rather than hardcoded so that adding a field in + * Studio and redeploying surfaces it here with no frontend change — the + * workflow stays the source of truth. + */ + formSchema(activityUid, instanceId) { + return this.request('POST', `/app/${APP_ID}/view/form-screens`, { + activity_id: activityUid, + device_type: 'desktop', + ...(instanceId ? { instance_id: instanceId } : {}), + }) + } + + /** Start a new instance via one of the three INIT activities. */ + start(activityUid, data) { + return this.request('POST', `/app/${APP_ID}/start`, { + workflow_uuid: WORKFLOW, + activity_id: activityUid, + data, + }) + } + + /** + * Perform an activity on an existing instance. The workflow refuses what the + * signed-in user may not do — a permission denial arrives as 403 here and as + * 400 on /start, both carrying "permission denied". + */ + activity(instanceId, activityUid, data) { + return this.request('POST', `/app/${APP_ID}/activity`, { + workflow_uuid: WORKFLOW, + instance_id: instanceId, + activity_id: activityUid, + data, + }) + } + + /** + * Upload a file and get back a reference — {uuid, blob_path, original_name, + * mime_type}. The field context matters: the backend resolves the field's + * own config (allowed types, size limit, ocr_config) server-side from it and + * ignores anything the client claims. + */ + async uploadFile(file, ctx) { + const form = new FormData() + form.append('file', file) + // workflow_uuid is REQUIRED and is fixed for this app, so it is taken from + // config rather than from ctx. Passing it optionally is how the first + // version shipped: the upload sent activity_id, field_id and instance_id + // and got back `Missing required params: workflow_uuid`. + form.append('workflow_uuid', WORKFLOW) + if (ctx.activityId) form.append('activity_id', ctx.activityId) + if (ctx.fieldId) form.append('field_id', ctx.fieldId) + if (ctx.instanceId) form.append('instance_id', String(ctx.instanceId)) + const headers = {} + if (this.token) headers['Authorization'] = `Bearer ${this.token}` + const res = await fetch(`${this.baseUrl}/app/${APP_ID}/upload`, { method: 'POST', headers, body: form }) + if (!res.ok) { + let message = res.statusText + try { const j = await res.json(); message = j.error || j.message || message } catch { /* non-JSON */ } + throw { status: res.status, message } + } + return res.json() + } + + /** + * Extract from an ALREADY-UPLOADED file. Sends a reference, not the bytes — + * the document crosses the wire once, survives a reload, and re-extracting + * costs no re-upload. The ocr_config (which fields to pull, where they map) + * is resolved server-side from the deployed workflow; anything the client + * sends is ignored. + */ + ocrExtract(fileRef, ctx) { + return this.request('POST', `/app/${APP_ID}/ocr-extract`, { + workflow_uuid: WORKFLOW, + activity_id: ctx.activityId, + field_id: ctx.fieldId, + instance_id: ctx.instanceId || undefined, + files: [fileRef], + }) + } + + instance(instanceId) { + return this.request('POST', `/app/${APP_ID}/instance`, { + workflow_uuid: WORKFLOW, + instance_id: instanceId, + }) + } + + /** + * The instance's audit trail: one entry per activity performed, with WHO + * performed it and the data they wrote. + * + * Must be the APP-SCOPED path. The bare `/view/audit` is not an API route at + * all — it falls through to the SPA and returns HTML with a 200, which + * parses as a JSON error rather than an HTTP one. + */ + audit(instanceId) { + return this.request('GET', `/app/${APP_ID}/view/audit?instance_id=${encodeURIComponent(String(instanceId))}`) + } +} diff --git a/src/api/config.js b/src/api/config.js new file mode 100644 index 0000000..65c75fa --- /dev/null +++ b/src/api/config.js @@ -0,0 +1,576 @@ +/** + * Environment-scoped identifiers for the Zurich Kotak "Lead to Policy" demo. + * + * Workflow config is seeded from sm2/custom-apps/zurich-kotak/ — org 84, + * app 536, workflow zk_wf_lead (110001 v1). + */ +export const ORG_ID = '84' +export const APP_ID = '536' +export const WORKFLOW = 'zk_wf_lead' + +/** + * The pipeline, in the order a lead actually moves. + * + * Mirrors workflow.tbl_wf_states by hand. It is duplicated rather than fetched + * because the sidebar has to render its ORDER, and the API returns states as a + * set with no canonical sequence. Keep in step with 53_v2_state_model.sql. + * + * `kind` answers "who is holding this lead", which is the question an operator + * actually has — not "where is it in the process": + * + * needs a person has to act, and nothing moves until they do + * customer waiting on someone outside the business + * auto an AI employee is carrying it; `doing` is what to say meanwhile + * waiting real, but not yet — the renewal is too far off to work + * end terminal + * + * `need` names the queue by what it wants done. A queue called "Upload + * documents" answers "is anything waiting on me?"; one called "Document + * Pending" describes where the lead sits and leaves the operator to work it out. + * + * `name` MUST match workflow.tbl_wf_states.name exactly — the queue filter, the + * sidebar tally and the action lookup all resolve a lead through this string + * against current_state_name. A workflow rename not mirrored here does NOT + * error: the queue returns nothing, correctly, for a name no lead is in. That + * is the failure mode this table has, and it is silent. + */ +/** + * The support desk this console can ask questions of. + * + * A Support App on the platform: an AI desk bound to app 536 that reads the + * deployed config and the live book through read-only tools and answers with + * evidence. It is org-scoped and lives outside this app, so its id is config + * here rather than something the console can derive. + * + * Access is granted per user on the platform (usersystem.tbl_org_user_agents) + * and the console additionally gates the panel to ops — see ASK_DESK_ROLES. + * Both have to agree; the platform's grant is the one that actually enforces. + */ +export const SUPPORT_AGENT_ID = 29648 +export const ASK_DESK_ROLES = ['ops_admin'] + +export const STAGES = [ + { uid: 'zk-state-new', name: 'New Lead', kind: 'auto', doing: 'Checking the lead', by: 'Intake AI' }, + { uid: 'zk-state-qualified', name: 'Awaiting Contact', kind: 'auto', doing: 'Calling the customer', by: 'the voice agent' }, + { uid: 'zk-state-contacted', name: 'Contacted', kind: 'auto', doing: 'Asking for the documents', by: 'Engage AI' }, + // The principal stall in the workflow, and the one that had no stage until + // 7 September: a lead waited for its three documents inside "Contacted", so + // the queue that most needed watching was the one that did not exist. + { uid: 'zk-state-docs', name: 'Document Pending', kind: 'needs', need: 'Document collection', by: 'the partner agent' }, + { uid: 'zk-state-quoted', name: 'Quote Presented', kind: 'customer', need: 'Customer decision', by: 'the customer', doing: 'Waiting for the customer to reply on WhatsApp' }, + // The one queue where the machine stops and a person decides. + { uid: 'zk-state-referred', name: 'Referred to Underwriting', kind: 'needs', need: 'Underwriting referral', by: 'an underwriter' }, + // `approval` marks the one queue that is a person's SIGN-OFF rather than a + // piece of work: confirming money has arrived. It is locked to ops_admin in + // the workflow — no agent and no other role can perform it — because an + // employee that can mark a premium received can put a customer on risk for a + // policy nobody paid for. It gets its own band on the overview so the role + // that owns it does not have to find it in a list of things mostly handled + // by somebody else. + // WHERE THE AI PUTS DOWN WHAT IT CANNOT HONESTLY FINISH. An AI employee has + // no way to raise a ticket and no way to send a message; the only move it + // has for "a person should take this" is Flag for Review, and it lands here + // with the reason it wrote. Nothing is running on these leads. + { uid: 'zk-state-review', name: 'Needs a Person', kind: 'needs', need: 'Flagged by the AI', by: 'operations' }, + { uid: 'zk-state-payment', name: 'Payment Pending', kind: 'needs', need: 'Premium confirmation', by: 'operations', approval: 'ops_admin', approvalLabel: 'Premium awaiting your confirmation', approvalNote: 'Cover cannot start until the premium is received — section 64VB. Only operations can confirm it.' }, + { uid: 'zk-state-issued', name: 'Policy Issued', kind: 'auto', doing: 'Closing the file', by: 'Engage AI' }, + // Nurture. There is no scheduler yet, so Resume Outreach is a button and it + // is the only thing that wakes a parked lead — do not present this as a + // stage with nothing to do. + { uid: 'zk-state-parked', name: 'Parked / Nurture', kind: 'waiting', need: 'Nurture', by: 'the renewal calendar' }, + { uid: 'zk-state-onboarded', name: 'Onboarded', kind: 'end' }, + { uid: 'zk-state-lost', name: 'Lost / Dropped', kind: 'end' }, + { uid: 'zk-state-declined', name: 'Declined', kind: 'end' }, +] + +/** + * How the sidebar groups those. Fourteen flat stages answer "what is the + * process?" — the question nobody signing in has. These answer "is anything + * waiting on me?". + */ +export const NAV_GROUPS = [ + // The sidebar answers "is anything waiting on me?", so a group is WHO holds + // the work, not where it sits in the process. A person's queues and the + // customer's queues both need a human to look, so they share one heading. + { label: 'Needs you', kinds: ['needs', 'customer'] }, + { label: 'Scheduled', kinds: ['waiting'] }, + { label: 'History', kinds: ['end'] }, +] + +/** Channel presentation. source_channel is data on the instance, never a branch. */ +export const CHANNELS = { + direct: { label: 'Direct', short: 'D' }, + bancassurance: { label: 'Bancassurance', short: 'B' }, + agency: { label: 'Agency', short: 'A' }, +} + +/** View source-uids. Seeded by sm2/custom-apps/zurich-kotak/04_views.sql. */ +export const RV_LEADS = 'zk-rv-leads' +export const DV_LEAD = 'zk-dv-lead' + +/** + * Which activities are runnable from which state, and who is expected to do it. + * + * Mirrors workflow.tbl_wf_state_allowed_activities by hand — the same reason + * STAGES is duplicated: the console needs the ORDER and the labels, and the API + * returns neither. + * + * `by` is presentational ONLY. Nothing here enforces anything: the workflow + * refuses server-side and the console reports what it said. Showing an action + * the signed-in user cannot perform is deliberate — the refusal is the demo. + * + * This map is hand-maintained against workflow.tbl_wf_state_allowed_activities. + * An activity added to the workflow but not added here is simply invisible: + * the platform allows it, the console never offers it, and nothing errors. + * Collect Documents shipped in that state for one round. + */ +/** + * What each activity IS at a stage, not merely who may press it. + * + * `do` the expected next step here. Usually one; Referred has two, + * because clear and decline are a decision pair rather than a + * step and an alternative to it. + * `again` a bounded loop — a retry, a reminder, a re-quote. Legitimate, + * never the thing to do next. + * `force` an AI employee's own job, offered to a person ONLY so a + * stalled lead can be pushed by hand. Presenting these as + * actions is what made the app read as a control panel: six + * equal buttons where five are recovery levers. + * `exit` Mark Lost. Always reachable, never a step. Four stages used + * to offer a partner agent this and nothing else, which told + * them their only option was to give up on a lead the system + * was actively working. + */ +const STATE_ACTIVITIES = { + 'zk-state-new': [ + { uid: 'zk-act-qualify', label: 'Qualify Lead', by: 'Intake AI', role: 'force' }, + ], + 'zk-state-qualified': [ + { uid: 'zk-act-contact', label: 'Log Contact', by: 'Engage AI', role: 'force' }, + { uid: 'zk-act-retry-call', label: 'Retry Call', by: 'Scheduled', role: 'force' }, + ], + 'zk-state-contacted': [ + { uid: 'zk-act-request-docs', label: 'Request Documents', by: 'Engage AI', role: 'force' }, + ], + // The one stage whose next step is a person's: three documents have to + // be found and uploaded. Everything else here is the AI's own chain. + 'zk-state-docs': [ + { uid: 'zk-act-collect-docs', label: 'Upload documents', by: 'you', role: 'do' }, + { uid: 'zk-act-doc-reminder', label: 'Send a reminder', by: 'Scheduled', role: 'force' }, + { uid: 'zk-act-capture-motor', label: 'Capture Motor Risk', by: 'Engage AI', role: 'force' }, + { uid: 'zk-act-capture-sme', label: 'Capture SME Risk', by: 'Engage AI', role: 'force' }, + { uid: 'zk-act-advise', label: 'AI Cover Recommendation', by: 'Advisor AI', role: 'force' }, + { uid: 'zk-act-quote', label: 'Generate Quote', by: 'Rating engine', role: 'force' }, + ], + 'zk-state-quoted': [ + // The customer accepts from their own phone: their WhatsApp reply is + // routed to Customer Reply, Engage reads it, and Engage performs this. + // Kept reachable — role 'force', folded away — because a customer who + // says yes on a CALL still needs somebody to record it, and because a + // reply Engage judged ambiguous has to be actionable by a person. + { uid: 'zk-act-accept', label: 'Record the acceptance by hand', by: 'you, on consent', role: 'force' }, + { uid: 'zk-act-quote', label: 'Re-quote', by: 'Engage AI', role: 'again' }, + { uid: 'zk-act-collect-docs', label: 'Add a document', by: 'you', role: 'again' }, + { uid: 'zk-act-answer-customer', label: 'Reply to the customer', by: 'you, on WhatsApp', role: 'again' }, + { uid: 'zk-act-kyc', label: 'Verify KYC', by: 'KYC AI', role: 'force' }, + { uid: 'zk-act-uw-screen', label: 'Underwriting Screen', by: 'KYC AI', role: 'force' }, + ], + 'zk-state-referred': [ + { uid: 'zk-act-uw-clear', label: 'Clear the referral', by: 'you', role: 'do' }, + { uid: 'zk-act-uw-decline', label: 'Decline the risk', by: 'you', role: 'do' }, + { uid: 'zk-act-uw-prepare', label: 'Prepare Referral', by: 'Referral AI', role: 'force' }, + ], + 'zk-state-review': [ + { uid: 'zk-act-review-resume', label: 'Send back to the workflow', by: 'you', role: 'do' }, + { uid: 'zk-act-review-refer', label: 'Send to underwriting', by: 'you', role: 'do' }, + ], + 'zk-state-payment': [ + { uid: 'zk-act-realise', label: 'Confirm premium received', by: 'you', role: 'do' }, + // Not offered: the chase is a SCHEDULED activity now (86), booked 24h + // out by Request Premium and re-booked at 48h to a cap of three. It + // carries zero roles so the scheduler can perform it at all, which means + // a button here would 403 for everyone. To actually reach the customer, + // use Reply to the customer — that sends something. + { uid: 'zk-act-payment', label: 'Request Premium', by: 'Engage AI', role: 'force' }, + ], + 'zk-state-issued': [ + { uid: 'zk-act-onboard', label: 'Complete Onboarding', by: 'Engage AI', role: 'force' }, + ], + 'zk-state-parked': [ + { uid: 'zk-act-resume', label: 'Resume outreach now', by: 'you', role: 'do' }, + ], +} + +/** + * Mark Lost is not tied to one state: a lead can be dropped from anywhere before + * the policy issues, and every role that files a lead may do it. Appended rather + * than written into every entry so there is one place to change it, and so a + * stage added above cannot silently lose it. + * + * It carries role 'exit' precisely so it is never rendered as a step. It is the + * way out, not the way on. + */ +const DROP = { uid: 'zk-act-drop', label: 'Mark Lost', by: 'whoever holds the lead', role: 'exit' } + +const DROPPABLE = [ + 'zk-state-new', 'zk-state-qualified', 'zk-state-contacted', 'zk-state-docs', + 'zk-state-quoted', 'zk-state-referred', 'zk-state-payment', 'zk-state-parked', +] + +export const ACTIONS = Object.fromEntries( + [...new Set([...Object.keys(STATE_ACTIVITIES), ...DROPPABLE])].map((uid) => [ + uid, + [...(STATE_ACTIVITIES[uid] ?? []), ...(DROPPABLE.includes(uid) ? [DROP] : [])], + ]), +) + +/** + * Entry points surfaced in the console. + * + * The workflow has THREE INIT activities — direct, bancassurance and agency — + * and all three still work over the API with their own permissions. Only the + * agency door is shown here, because this demo is about the individual agent + * who sources a lead and gets paid when it onboards. + * + * The other two are hidden, not removed: the bancassurance door is what makes + * the cross-channel duplicate story possible, and deleting it would take the + * skip-ahead behaviour with it. + */ +export const ENTRY = [ + { uid: 'zk-act-init-agent', label: 'Partner Agent Lead', channel: 'agency', + note: 'POSP or broker sourcing a lead. Everything after this happens without them.' }, +] + +/** Product lines, as stored on the instance and as they should be read. */ +export const PRODUCTS = { + motor: 'Motor', + sme_package: 'SME Package', +} + +/** + * Which upload slot belongs to which product line — and, for the two slots that + * are conditional, when the condition holds. + * + * The Collect Documents activity serves BOTH lines from one form: it returns all + * eleven slots to every lead, so a motor renewal was being asked for a Udyam + * certificate and a stock statement. Nothing on the platform decides otherwise — + * `field_rules` comes back as `[]` for this activity, so there is no server-side + * visibility to honour. + * + * This is therefore a MIRROR, in the same sense as STAGES and ACTIONS above, and + * carries the same hazard: a slot added to the activity but not added here is + * shown to every product, and one renamed here stops matching and reverts to the + * same. The durable home for this is `field_rules` on the activity; when those + * are seeded, ActivityForm should read them and this table should go. + * + * Every slot is optional in the workflow (`mandatory: false` on all eleven), so + * hiding one cannot make a submission fail validation. + */ +export const DOC_SLOTS = { + // Motor. + doc_rc: { line: 'motor' }, + doc_prev_policy: { line: 'motor' }, + // "Break-in only" per the policy. The flag DOES exist now — 49 derives + // break_in at filing on all three doors — so the slot can honour its own + // caveat instead of being shown to every motor renewal. + doc_vehicle_photos: { line: 'motor', when: (lead) => lead.break_in === 'yes' }, + + // SME. + doc_gst_cert: { line: 'sme' }, + doc_udyam_cert: { line: 'sme' }, + doc_premises_proof: { line: 'sme' }, + doc_stock_statement: { line: 'sme' }, + doc_premises_photos: { line: 'sme' }, + // Audited accounts are only read when business interruption is on the risk. + doc_financials: { line: 'sme', + when: (lead) => (lead.sme_sections || []).includes('business_interruption') }, + + // Both lines. + doc_pan: { line: 'both' }, + // Identity is only re-evidenced when KYC actually referred; asking up front + // collects an Aadhaar the file does not need. + doc_address_proof: { line: 'both', when: (lead) => lead.kyc_outcome === 'refer' }, +} + +/** + * The fields that belong to one product line but do not say so in their name. + * Everything else is classified by prefix: `motor_*` is motor, `sme_*` is SME. + * A prefix rule rather than a list, so a field added to the workflow tomorrow is + * classified without anyone remembering to come back here. + */ +export const LINE_FIELDS = { + gstin: 'sme', + udyam_no: 'sme', + // entity_name is labelled "Business Name" on the form. A company-owned + // vehicle does have an owner with a name, so this is not strictly an SME + // field — but asking a motor renewal for a business name puts an empty box + // on the shortest form in the app, and the answer is already carried by + // customer_name in every motor lead we have. It is optional, so hiding it + // cannot block a submission, and an SME lead still gets it. + entity_name: 'sme', +} + +/** + * Fields the form STAMPS rather than asks. + * + * Each is resolved by the prefill pipeline from the signed-in identity — + * Arjun IS Crestline Insurance Advisors, submitting through the agency door — + * so all three arrived filled and read-only-in-spirit, and the New lead form + * opened with three of its eleven boxes already answered by the system. That + * is three boxes of noise in front of the four that actually need a person. + * + * HIDDEN FROM THE FORM, STILL SENT. These are not decorative: source_channel + * is mandatory, and partner_code and rm_or_agent_id are what Intake attributes + * the lead on. So they are filtered at RENDER only — `fields`, which drives + * both validation and the payload, still holds them, and their prefilled + * values submit exactly as before. Filtering them out of `fields` instead + * would drop the attribution and 400 on the mandatory channel. + */ +export const STAMPED_FIELDS = new Set([ + 'source_channel', + 'partner_code', + 'rm_or_agent_id', +]) + +/** Whether a field is stamped by prefill and so should not be drawn. */ +export function fieldIsStamped(fieldId) { + return STAMPED_FIELDS.has(baseFieldId(fieldId)) +} + +/** + * Fields the workflow computes for itself, which a form must therefore not ask + * for. Matched on the base id, so every per-activity suffix is covered. + * + * `documents_status` is the one that matters. It gates the AND-join that wakes + * Engage after an upload (55), and it was rendered as a dropdown — asking the + * person who had just attached three files to tell the system what it could + * see. Left unset, the lead sits in Document Pending with everything attached + * and nothing happening, and it reads as the AI having stalled. It is derived + * in the trigger now (75), from the files themselves. + * + * `documents_notes` goes with it: the same script writes what is still missing, + * and a person overwriting that would be arguing with the file list. + */ +export const DERIVED_FIELDS = new Set([ + 'documents_status', + 'documents_notes', +]) + +/** + * Form field ids carry a per-form suffix — `doc_rc` arrives as `doc_rc_2`, `pan` + * as `pan_3` — so a field is matched on the id with that suffix removed. No + * underlying field id ends in a number, which is what makes this safe. + */ +export function baseFieldId(id) { + return String(id).replace(/_\d+$/, '') +} + +/** Which product line a field belongs to: 'motor', 'sme', or 'both'. */ +export function fieldLine(fieldId) { + const id = baseFieldId(fieldId) + if (DOC_SLOTS[id]) return DOC_SLOTS[id].line + if (LINE_FIELDS[id]) return LINE_FIELDS[id] + if (id.startsWith('motor_')) return 'motor' + if (id.startsWith('sme_')) return 'sme' + return 'both' +} + +/** + * The line a lead is on, in the vocabulary fieldLine answers in, or null when it + * cannot be told. + * + * Null matters: treating an unknown line as SME would quietly drop the RC and + * the expiring policy from Collect Documents on a lead whose product has not + * been stamped yet, with nothing on screen to say a slot was hidden. Not knowing + * means filtering nothing. + */ +export function leadLine(lead) { + if (lead?.product_line === 'motor') return 'motor' + if (lead?.product_line === 'sme_package') return 'sme' + return null +} + +/** + * Whether an activity field should be offered for this lead — its line has to + * match, and a conditional upload slot has to have its condition hold. + * + * Everything is shown when there is no instance yet: an INIT form has no product + * line to filter on. + */ +export function fieldApplies(fieldId, lead) { + // Computed by the workflow — never asked for, on any form, whether or not + // there is a lead behind it. + if (DERIVED_FIELDS.has(baseFieldId(fieldId))) return false + if (!lead) return true + const on = leadLine(lead) + if (!on) return true + const line = fieldLine(fieldId) + if (line !== 'both' && line !== on) return false + const slot = DOC_SLOTS[baseFieldId(fieldId)] + return slot?.when ? slot.when(lead) : true +} + +/** + * A STAGE IS NOT ALWAYS ONE SITUATION. + * + * Document Pending covers two that could not look more different to whoever is + * watching. Before the upload a person has to act and nothing moves until they + * do; after it the lead stays in the same state while Engage captures the risk, + * the Advisor recommends cover and the rating engine prices it — three AI steps, + * two to five minutes, no one to chase. + * + * Rendered from `current_state_name` alone both read as "waiting on the partner + * agent", so a lead that had just been served showed an Upload documents button + * and sat in the Action-required queue, and the AI work behind it was invisible. + * The state machine is right to hold one state here — nothing has been decided + * yet — so the distinction belongs in the read model, once, rather than in each + * screen's own guess. + * + * `documents_status` is what separates them. The workflow derives it from the + * files themselves (75), so it says what is actually attached rather than what + * anyone claimed. + */ +export function phaseOf(stage, lead) { + if (!stage || !lead) return stage + + // Quote Presented has the same shape as Document Pending: the state holds + // still while the situation underneath it changes completely. + // + // Before the customer answers, the lead is genuinely with them and nothing + // is running. After they accept, KYC and the underwriting screen run inside + // the SAME state — the lead does not move until underwriting clears — so a + // page saying "waiting for the customer to reply" sat directly above a panel + // saying "accepted by the customer, KYC and underwriting are running". Both + // were rendered from the same instant; only one was true. + if (stage.uid === 'zk-state-quoted' && lead.acceptance_ref && !lead.uw_outcome) { + return { + ...stage, + kind: 'auto', + doing: lead.kyc_outcome ? 'Screening the risk for underwriting' : 'Verifying KYC', + by: 'KYC & Evidence', + after: 'customer accepted', + } + } + + if (stage.uid === 'zk-state-docs' && lead.documents_status === 'complete') { + return { + ...stage, + kind: 'auto', + doing: 'Reading the documents and pricing the cover', + by: 'Engage AI, then the Advisor', + // Kept so a screen can say WHY this is not the queue it looks like. + after: 'documents received', + } + } + return stage +} + +/** + * Why an automated stage has stopped, when it has. + * + * The AI chain behind Document Pending is honest about refusing: the rating + * engine writes `quoted_breakup` = "Not priced: no insured value (IDV) + * captured…" rather than inventing a premium, and Engage then declines to + * raise a quote it would have to fabricate. Both are the right call. + * + * What was missing is that NOBODY WAS TOLD. The refusal lives in a field on a + * tab, the AI's task dies in a queue no operator can see, and the lead sits in + * Document Pending looking exactly like one whose documents never arrived — + * indefinitely, because nothing wakes the chain again. A workflow that stops + * for a good reason and a workflow that is broken must not look the same. + * + * Recovery is always the same shape: put the missing value in and let the + * chain re-run. Collect Documents carries the IDV field and re-performing it + * wakes Engage again, so the action is one the partner agent already holds. + */ +export function blockedOn(lead) { + if (!lead) return null + const breakup = String(lead.quoted_breakup || '') + if (breakup.startsWith('Not priced')) { + return { + what: breakup.replace(/^Not priced:\s*/, ''), + // Named rather than described: the operator has to find this field, and + // it is not where they would look for it. + fix: 'Re-open Collect Documents and enter the IDV, or attach the expiring policy again so it can be read off.', + via: 'zk-act-collect-docs', + } + } + return null +} + +/** + * WHEN AN AGENT STOPS, WHAT DOES A PERSON PRESS? + * + * Agents stall. Not often, but they do, and for reasons nothing in this app + * controls: the model provider slows to ninety seconds a call or returns a 502, + * a thinking budget runs out mid-sentence, a late webhook wakes the wrong + * employee. Watched from the console every one of those looks identical — + * a lead that simply stops — and the screen kept promising it would "complete + * within two minutes" indefinitely. + * + * There is no retry button in the platform, and none of these agents can be + * woken directly. But every one of them is woken BY AN ACTIVITY, so performing + * that activity again wakes it again. That is what this table holds: for a + * lead sitting in an automated step, the activity a person can perform to make + * the stalled agent run once more. + * + * `by` is who to expect to move afterwards, so the button says what will + * happen rather than just what it does. + * + * The choice within Document Pending depends on HOW FAR the chain got, because + * three agents work that state in sequence and the one to restart is the one + * that did not finish. + */ +export function nudgeFor(stage, lead) { + if (!stage || !lead) return null + + switch (stage.uid) { + case 'zk-state-new': + return { uid: 'zk-act-qualify', label: 'Run the check again', by: 'Intake' } + + case 'zk-state-qualified': + return { uid: 'zk-act-contact', label: 'Record the call outcome', by: 'Engage' } + + case 'zk-state-contacted': + return { uid: 'zk-act-request-docs', label: 'Ask for the documents again', by: 'Engage' } + + case 'zk-state-docs': { + // Engage captures, the Advisor recommends, the rating engine prices — + // in that order, each woken by the one before. + const line = lead.product_line === 'sme_package' ? 'zk-act-capture-sme' : 'zk-act-capture-motor' + if (!lead.motor_idv && !lead.sme_value_at_risk) { + return { uid: line, label: 'Capture the risk again', by: 'Engage' } + } + if (!lead.ai_recommended_cover) { + // The Advisor is the ONE step nobody may perform by hand — it is + // permitted to ai_advisor alone. Re-performing the activity that wakes + // it is the only way back, and it is the reason this table exists. + return { uid: line, label: 'Wake the Advisor', by: 'the Advisor' } + } + if (!lead.quoted_premium) { + return { uid: 'zk-act-quote', label: 'Build the quote again', by: 'the rating engine' } + } + return null + } + + case 'zk-state-quoted': { + // Only after an acceptance — before that nothing is running and there is + // nothing to wake; the lead is with the customer. + if (!lead.acceptance_ref) return null + if (!lead.kyc_outcome) return { uid: 'zk-act-kyc', label: 'Run KYC again', by: 'KYC & Evidence' } + if (!lead.uw_outcome) return { uid: 'zk-act-uw-screen', label: 'Run the underwriting screen', by: 'KYC & Evidence' } + return null + } + + case 'zk-state-issued': + return { uid: 'zk-act-onboard', label: 'Close the file', by: 'Engage' } + + default: + return null + } +} + +/** How long an automated step may sit before the console stops reassuring and + * starts offering the way out. Generous: an employee wake plus a slow model + * can legitimately take three or four minutes. */ +export const STALL_AFTER_MS = 5 * 60 * 1000 diff --git a/src/api/errors.js b/src/api/errors.js new file mode 100644 index 0000000..066c591 --- /dev/null +++ b/src/api/errors.js @@ -0,0 +1,130 @@ +/** + * The gateway's error shapes, turned into something an operator can act on. + * + * Five shapes matter, and they are told apart by status plus a phrase in the + * message — there is no error code to switch on. `kind` is for the caller to + * branch on ('stale' and 'gone' need the screen to do something); `title` and + * `detail` are what gets shown. + * + * Anything unrecognised keeps its own message: a wrong guess reads worse than + * the server's own words. + */ +export function describeError(err) { + const status = err?.status + const raw = String(err?.message ?? '') + const has = (...words) => words.every((w) => raw.toLowerCase().includes(w)) + + if (status === 404 && has('no record found')) { + return { + kind: 'gone', + title: 'This lead is no longer there.', + detail: 'It may have been removed since the queue was loaded. Taking you back to the list.', + } + } + + if (status === 403 && has('not allowed in state')) { + return { + kind: 'stale', + // Deliberately not "the lead moved": the gateway returns this both when a + // lead advanced under the screen AND when the console offered an activity + // the state never allowed. Only one of those is a move, and claiming the + // wrong one sends the operator looking for something that did not happen. + title: 'That activity is not available at this stage.', + detail: 'Either the lead moved on while this was open, or it never allowed this. Refreshed to show what it does allow.', + } + } + + if (status === 403) { + return { + kind: 'forbidden', + title: 'The workflow refused this.', + detail: 'This is the platform deciding, not the console: the signed-in role does not hold this activity.', + } + } + + // Field validation runs BEFORE the permission check, so a disallowed + // submission carrying bad data arrives here as a 400 and not a 403. + if (status === 400 && has('validation failed')) { + // "field(unknown), field_2(required)" is the unsuffixed-key mistake, and it + // is a bug in this console rather than anything the operator did. + if (has('unknown') && has('required')) { + return { + kind: 'bug', + title: 'The console sent a field name the workflow does not know.', + detail: raw, + } + } + if (has('enum')) { + return { + kind: 'invalid', + title: 'One of the choices is not one the workflow accepts.', + detail: raw, + } + } + return { kind: 'invalid', title: 'The workflow rejected this submission.', detail: raw } + } + + if (status === 401) { + return { kind: 'auth', title: 'The session has expired.', detail: 'Sign in again to continue.' } + } + + return { kind: 'unknown', title: raw || 'Something went wrong.', detail: null } +} + +/** + * Turns the workflow's field-validation reply into something a person can act + * on, using the form's own labels. + * + * The server answers with the machine keys and a bare reason: + * + * validation failed for activity zk-act-init-agent: product_line_4(required) + * + * Shown raw, that asks an operator to know what a field_s_id is, that `_4` is a + * disambiguating suffix rather than part of a name, and that "required" is a + * rule and not a value. All three are ours to know, not theirs. + * + * `fields` is the schema array, so the reply is rendered in the same words the + * form used a line above it — "Product Line", not product_line_4. A key the + * schema does not carry keeps its raw name: a wrong label is worse than an + * ugly one, because the operator goes looking for a field that is not there. + * + * Returns null when the message is not a field-validation reply, so callers + * can fall through to describeError. + */ +export function describeValidation(rawMessage, fields = []) { + const raw = String(rawMessage ?? '') + if (!/validation failed/i.test(raw)) return null + + const label = (key) => + fields.find((f) => f.id === key)?.name ?? + // Same suffix rule the prefill seeding uses: the activity key may carry a + // numeric tail the global name does not. + fields.find((f) => String(f.id).replace(/_\d+$/, '') === key)?.name ?? + key + + const reasons = { + required: (n) => `${n} is required`, + unknown: (n) => `${n} is not a field this form accepts`, + enum: (n) => `${n} is not one of the available choices`, + invalid: (n) => `${n} is not valid`, + type: (n) => `${n} is the wrong kind of value`, + } + + const items = [] + const re = /([A-Za-z0-9_.]+)\s*\(([^)]+)\)/g + let m + while ((m = re.exec(raw)) !== null) { + const name = label(m[1]) + const why = String(m[2]).toLowerCase().trim() + const key = Object.keys(reasons).find((k) => why.includes(k)) + items.push(key ? reasons[key](name) : `${name}: ${why}`) + } + + if (!items.length) return null + return { + kind: 'validation', + // One problem reads as a sentence; several read as a list. + title: items.length === 1 ? items[0] : 'Some details are missing or not accepted.', + items, + } +} diff --git a/src/api/holder.js b/src/api/holder.js new file mode 100644 index 0000000..3d1ed7f --- /dev/null +++ b/src/api/holder.js @@ -0,0 +1,36 @@ +import { phaseOf } from './config.js' + +/** + * Who is holding a lead right now, said the way the colour rule says it: + * blue = the AI, amber = a person, teal = the customer, grey = nobody (closed). + * + * Derived from phaseOf, so it agrees with the sidebar tallies and the lead + * header. `label` is the short form for a table cell: "AI · Intake", + * "Underwriter", "Customer", "Closed". + */ +const AI_NAMES = [ + ['intake', 'Intake'], ['engage', 'Engage'], ['advisor', 'Advisor'], + ['kyc', 'KYC'], ['voice', 'Meera'], ['rating', 'Rating'], +] + +function tidy(by) { + const s = String(by || '').replace(/^(the|an|a)\s+/i, '').trim() + return s ? s.charAt(0).toUpperCase() + s.slice(1) : '—' +} + +export function holderOf(stageDef, row) { + if (!stageDef) return { tone: 'grey', label: '—' } + const ph = phaseOf(stageDef, row) || stageDef + switch (ph.kind) { + case 'auto': { + const by = String(ph.by || '').toLowerCase() + const hit = AI_NAMES.find(([k]) => by.includes(k)) + return { tone: 'blue', label: 'AI · ' + (hit ? hit[1] : 'Engage') } + } + case 'customer': return { tone: 'teal', label: 'Customer' } + case 'needs': return { tone: 'amber', label: tidy(ph.by) } + case 'waiting': return { tone: 'grey', label: 'Calendar' } + case 'end': return { tone: 'grey', label: 'Closed' } + default: return { tone: 'grey', label: tidy(ph.by) } + } +} diff --git a/src/api/lead.js b/src/api/lead.js new file mode 100644 index 0000000..c3ee3a1 --- /dev/null +++ b/src/api/lead.js @@ -0,0 +1,163 @@ +import { PRODUCTS } from './config.js' + +/** + * The vocabulary of a lead: how to read a renewal date, how to name a field, + * which fields belong together, and what a blocker means in words. + * + * Lifted out of the desktop console's lead screen unchanged, so the phone and + * the desktop describe the same lead the same way. A divergence here would be + * two products wearing one brand. + */ +/** The countdown, not just the date. On a renewal book this is the number + * that decides whether anyone should act today. */ +export function expiryOf(dateStr) { + if (!dateStr) return null + const d = new Date(String(dateStr).substring(0, 10) + 'T00:00:00Z') + if (isNaN(d)) return null + const days = Math.round((d.getTime() - Date.parse(new Date().toISOString().substring(0, 10) + 'T00:00:00Z')) / 86400000) + return { + days, + tone: days < 0 ? 'lapsed' : days <= 7 ? 'urgent' : days <= 30 ? 'soon' : 'later', + label: days < 0 ? Math.abs(days) + ' days overdue' : days === 0 ? 'expires today' : 'in ' + days + ' days', + on: d.toLocaleDateString('en-IN', { day: 'numeric', month: 'short', year: 'numeric' }), + } +} + +export function inrShort(v) { + const n = Number(v) + if (!Number.isFinite(n) || !n) return null + if (n >= 1e7) return '₹' + (n / 1e7).toFixed(2) + ' Cr' + if (n >= 1e5) return '₹' + (n / 1e5).toFixed(2) + ' L' + return '₹' + Math.round(n).toLocaleString('en-IN') +} + +export const MONEY = new Set(['quoted_premium','quoted_od_premium','quoted_tp_premium','quoted_addon_premium', + 'quoted_gst','commission_base','commission_amount','sme_building_si','sme_plant_si','sme_furniture_si', + 'sme_rawmaterial_si','sme_wip_si','sme_finished_si','sme_other_si','sme_value_at_risk','motor_idv', + 'sme_burglary_si','sme_ee_si','sme_bi_gross_profit','sme_claims_36m_amount','sme_stock_si']) + +/** Field groups, in the order the lead was actually worked. */ +/* What the AI said stopped it, turned into a sentence an operator can act on. + Keyed by the stored value so an unknown one degrades to the generic line. */ +export const BLOCKER = { + missing_evidence: 'It says the evidence it needed was not there.', + contradictory_data: 'It says the evidence it had contradicts itself.', + tool_failed: 'It says a lookup or a tool it depends on failed.', + outside_my_remit: 'It says the judgement is a person\u2019s to make, not its own.', + other: 'It could not complete its step.', +} + +export const GROUPS = [ + ['Source', ['lead_ref','product_line','source_channel','partner_code','partner_branch','rm_or_agent_id','consent_artefact']], + // First, because when a lead is flagged this is the only thing anyone opens + // it to read. Empty on every lead that was never flagged, and an empty group + // does not render. + ['Flagged for review', ['review_blocker','review_reason','review_return','review_note']], + ['Customer', ['customer_name','entity_name','mobile','email','pan','gstin','udyam_no']], + ['Intake', ['lead_score','attribution_status','attribution_reason','dedupe_match_ref','eligibility_outcome','eligibility_reason']], + ['Contact', ['contact_outcome','outreach_window','contact_notes','call_transcript']], + // The five OCR slots led this list and were absent from it, which is how a + // lead with an RC, an expiring policy and a PAN attached showed "Documents 2" + // — the status and the notes. They were also absent from the view itself + // until 76; adding them here without that would have changed nothing. + ['Documents', ['doc_rc','doc_prev_policy','doc_pan','doc_gst_cert','doc_udyam_cert', + 'doc_address_proof','doc_premises_proof','doc_stock_statement','doc_premises_photos', + 'doc_vehicle_photos','doc_financials','documents_status','documents_notes']], + ['SME risk', ['sme_product_variant','sme_occupancy','sme_location_address','sme_building_si','sme_plant_si','sme_furniture_si','sme_rawmaterial_si','sme_wip_si','sme_finished_si','sme_stock_si','sme_other_si','sme_value_at_risk','sme_floor','sme_num_floors','sme_floor_material','sme_walls','sme_roof','sme_building_age_band','sme_unit_age_years','sme_fire_protection','sme_fire_amc','sme_fire_brigade_km','sme_claims_36m_count','sme_claims_36m_amount','sme_sections','sme_bi_gross_profit','sme_bi_indemnity_months','sme_burglary_si','sme_ee_si']], + ['Motor risk', ['motor_reg_no','motor_make_model','motor_mfg_year','motor_cc','motor_fuel','motor_idv','motor_ncb_pct','motor_addons','motor_prev_insurer','motor_prev_policy_no','motor_prev_expiry','motor_prev_claim']], + ['AI advice', ['ai_recommended_cover','ai_recommended_addons','ai_recommendation_rationale','ai_recommendation_confidence']], + ['Quote', ['product_code','quoted_od_premium','quoted_tp_premium','quoted_addon_premium','quoted_section_premiums','quoted_gst','quoted_premium','quoted_breakup','quote_valid_till']], + ['Conversation', ['customer_reply','customer_reply_from','customer_answer','answer_count']], + ['Proposal', ['acceptance_ref','accepted_at']], + ['KYC', ['kyc_mode','kyc_ref','kyc_outcome','kyc_mismatch_notes']], + ['Underwriting', ['uw_outcome','uw_survey_required','referral_analysis','uw_referral_reason','uw_decision_notes']], + ['Policy', ['payment_link','payment_ref','premium_realised','realised_at','policy_no','policy_issued_at']], + ['Commission', ['commission_rate_pct','commission_base','commission_amount','payout_status','payout_ref','payout_at']], + ['Outcome', ['lost_reason','welcome_sent','renewal_due']], +] + +/** Past this, a value is prose and gets folded rather than printed in full. */ +export const LONG = 150 + +/** + * WHAT THE PAGE SHOWS WITHOUT BEING ASKED. + * + * Three things are always true of a lead — who the customer is, what is being + * insured, and what has been attached — so those are always here. The fourth + * section depends on where the lead has got to: a lead in Quoted needs the + * cover and the quote's expiry; the same lead in Onboarded needs the policy + * number and when it renews. Everything else is in the full file. + * + * THIS IS A MIRROR, in the same sense as STAGES, ACTIONS and DOC_SLOTS, and it + * carries the same hazard: a stage not listed here simply gets no fourth + * section, and a field renamed in the workflow quietly stops appearing. That is + * the safe direction to fail — the full file is generated from the data and + * still holds everything — but it is a mirror, not a source. + * + * The metrics strip at the top of the page already carries premium, commission, + * product, renewal date, lead age and AI confidence. Nothing is repeated here. + */ +export const GLANCE_STAGE = { + 'zk-state-new': ['lead_score', 'eligibility_outcome'], + 'zk-state-qualified': ['lead_score', 'eligibility_outcome', 'outreach_window'], + 'zk-state-contacted': ['contact_outcome', 'outreach_window'], + 'zk-state-docs': ['documents_status', 'motor_prev_expiry'], + 'zk-state-quoted': ['ai_recommended_cover', 'quote_valid_till', 'acceptance_ref'], + 'zk-state-payment': ['payment_ref', 'quote_valid_till'], + 'zk-state-issued': ['policy_no', 'policy_issued_at', 'payment_ref'], + 'zk-state-onboarded': ['policy_no', 'policy_issued_at', 'renewal_due', 'payout_status'], + 'zk-state-referred': ['uw_outcome', 'uw_referral_reason'], + 'zk-state-parked': ['contact_outcome', 'outreach_window'], + 'zk-state-lost': ['lost_reason', 'contact_outcome'], +} + +/** The risk, in whichever line's vocabulary this lead is written. */ +export const GLANCE_RISK = { + motor: ['motor_reg_no', 'motor_make_model', 'motor_mfg_year', 'motor_idv', 'motor_ncb_pct'], + sme: ['sme_product_variant', 'sme_occupancy', 'sme_value_at_risk'], +} + +/** + * Field ids are snake_case and several carry acronyms, which sentence-casing + * turns into "Pan" and "Gstin". Only the words that need it are listed; every + * other word passes through. + * + * This is the FALLBACK. The detail view ships an output_label for every field + * and that is preferred — this covers a field the config does not describe. + */ +export const WORDS = { + pan: 'PAN', gstin: 'GSTIN', kyc: 'KYC', ai: 'AI', sme: 'SME', uw: 'UW', + od: 'OD', tp: 'TP', gst: 'GST', idv: 'IDV', ncb: 'NCB', rm: 'RM', si: 'SI', + cc: 'CC', id: 'ID', no: 'no.', pct: '%', wip: 'WIP', bi: 'BI', ee: 'EE', + amc: 'AMC', km: 'km', posp: 'POSP', +} + +export function label(k) { + const words = k.split('_').map((w) => WORDS[w] ?? w).join(' ') + return words.charAt(0).toUpperCase() + words.slice(1) +} + +/** The uploaded files on a field value, if that is what it holds. */ +export function filesOf(v) { + return Array.isArray(v) ? v.filter((f) => f && typeof f === 'object' && f.uuid) : [] +} + +export function fmt(k, v) { + if (v === null || v === undefined || v === '') return null + if (k === 'product_line') return PRODUCTS[v] ?? String(v) + if (Array.isArray(v)) { + // A file field holds an array of upload references — {uuid, original_name, + // blob_path, …} — so joining it raw prints [object Object]. + return v + .map((x) => (x && typeof x === 'object' ? (x.original_name || x.file_name || x.uuid || '') : x)) + .filter((x) => x !== '' && x !== null && x !== undefined) + .join(', ') || null + } + // No field carries a bare object today, but one arriving as JSON should not + // print as [object Object]. + if (typeof v === 'object') return JSON.stringify(v) + if (MONEY.has(k)) { const n = Number(v); return Number.isFinite(n) ? '₹' + n.toLocaleString('en-IN') : String(v) } + return String(v) +} + + diff --git a/src/api/permissions.js b/src/api/permissions.js new file mode 100644 index 0000000..dc6c31a --- /dev/null +++ b/src/api/permissions.js @@ -0,0 +1,159 @@ +import { ACTIONS, STAGES } from './config.js' + +/** + * Who may perform what. + * + * A MIRROR of workflow.tbl_wf_activity_permissions on app 536, in the same + * sense as STAGES and ACTIONS: the console needs it to decide what to draw, + * and the API returns a refusal rather than a capability list. + * + * ── This is presentation, never enforcement ────────────────────────────── + * The workflow refuses server-side on every submission, and that refusal is + * the real control. Nothing here can grant anything; a role added here that + * the platform does not recognise gets a 403 the moment it submits. What this + * buys is that an operator is not shown four buttons they will be refused for + * pressing — which on a demo reads as a broken app rather than as a fence. + * + * Keep in step with the permissions table. A role REMOVED there but left here + * shows a button that 403s: recoverable and visible. A role ADDED there but + * missing here hides a button that would have worked: invisible, and the + * failure mode worth watching for. + */ +export const ACTIVITY_ROLES = { + 'zk-act-init-agent': ['ops_admin', 'partner_agent'], + 'zk-act-init-bank': ['ops_admin', 'bank_rm'], + 'zk-act-init-direct': ['ops_admin', 'csr_direct'], + + 'zk-act-qualify': ['ops_admin', 'ai_intake'], + 'zk-act-contact': ['ops_admin', 'ai_engage'], + 'zk-act-request-docs': ['ops_admin', 'ai_engage'], + 'zk-act-collect-docs': ['ops_admin', 'partner_agent', 'bank_rm', 'csr_direct'], + 'zk-act-capture-motor':['ops_admin', 'ai_engage'], + 'zk-act-capture-sme': ['ops_admin', 'ai_engage'], + 'zk-act-advise': ['ai_advisor'], + 'zk-act-quote': ['ops_admin', 'ai_engage'], + 'zk-act-accept': ['ops_admin', 'partner_agent', 'bank_rm', 'csr_direct'], + // Ops only. The customer's questions are normally Engage's, and this is + // the way a person answers one Engage declined — through the same WhatsApp + // thread, so the reply lands on the lead file instead of somewhere nobody + // can find it later. + 'zk-act-answer-customer': ['ops_admin'], + 'zk-act-kyc': ['ops_admin', 'ai_kyc'], + 'zk-act-uw-screen': ['ops_admin', 'ai_kyc'], + 'zk-act-uw-prepare': ['ai_uw_referral'], + + // The only exclusive permission in the application. Ops runs everything + // else and cannot touch these two — a referral is cleared by an underwriter + // or it is not cleared. + 'zk-act-uw-clear': ['sme_underwriter'], + 'zk-act-uw-decline': ['sme_underwriter'], + + 'zk-act-payment': ['ops_admin', 'ai_engage'], + // Zero roles in the workflow since 86 — the scheduler performs it, and a + // scheduled activity with any role list fails silently. Left here as an + // empty list so the mirror still records that the activity exists. + 'zk-act-nudge': [], + 'zk-act-realise': ['ops_admin'], + 'zk-act-onboard': ['ops_admin', 'ai_engage'], + 'zk-act-resume': ['ops_admin', 'partner_agent', 'bank_rm', 'csr_direct'], + + // The AI's one way of saying "a person should take this". Every employee + // holds it, and so does ops — a person can park a lead for the same reasons. + 'zk-act-flag-review': ['ops_admin', 'ai_intake', 'ai_engage', 'ai_kyc', 'ai_advisor', 'ai_uw_referral'], + // And the two ways back out of Needs a Person. The underwriter is here too: + // a flag they are sent is theirs to route, not only ops'. + 'zk-act-review-resume':['ops_admin', 'sme_underwriter'], + 'zk-act-review-refer': ['ops_admin', 'sme_underwriter'], + 'zk-act-drop': ['ops_admin', 'partner_agent', 'bank_rm', 'csr_direct'], + + // ── The one place this mirror deliberately DISAGREES with the workflow ── + // + // Both of these carry NO roles in tbl_wf_activity_permissions, which the + // platform reads as "open to anyone". That is not generosity: the scheduler + // performs them as the synthetic `system` actor, and the trigger's own + // perform step ignores allow_system_perform, so zero roles is the only + // configuration under which a scheduled activity can run at all. See + // 63_scheduled_activities_rbac.sql. + // + // Open to the SYSTEM is not the same as open to everyone signing in. Left + // literal, an underwriter is offered "Send Document Reminder" on a queue + // they have no business in. So the UI narrows them to the roles that would + // plausibly chase by hand. The workflow still accepts either from anyone — + // this hides a button, it does not close a door. + 'zk-act-doc-reminder': ['ops_admin', 'partner_agent', 'bank_rm', 'csr_direct'], + 'zk-act-retry-call': ['ops_admin', 'partner_agent', 'bank_rm', 'csr_direct'], +} + +/** Roles that belong to an AI employee. They never sign in. */ +export const AI_ROLES = new Set([ + 'ai_intake', 'ai_engage', 'ai_advisor', 'ai_kyc', 'ai_uw_referral', +]) + +export function rolesOf(user) { + const r = user?.roles + if (Array.isArray(r)) return r.filter(Boolean).map(String) + if (Array.isArray(user?.role_assignments)) { + return user.role_assignments.map((x) => x?.role_id).filter(Boolean).map(String) + } + return [] +} + +/** + * An empty role list means the activity is open to any signed-in user — that + * is what the platform's RBAC does with no roles attached, so mirroring it + * here keeps the two from disagreeing. + */ +export function canPerform(roles, activityUid) { + const allowed = ACTIVITY_ROLES[activityUid] + if (!allowed) return true // unknown activity: show it, let the API decide + if (allowed.length === 0) return true + return roles.some((r) => allowed.includes(r)) +} + +/** The activities this user may actually run from a given stage. */ +export function actionsFor(roles, stageUid) { + return (ACTIONS[stageUid] || []).filter((a) => canPerform(roles, a.uid)) +} + +/** + * Activities that are available almost everywhere, or that no person runs. + * + * They must not count towards "does this role have business in this queue". + * Mark Lost is offered in eight stages to every agent role, and the two + * scheduled activities carry no roles at all — which the platform reads as + * open. Left in the test, between them they make every queue look relevant + * to everybody, which is the whole thing this is trying to avoid. + */ +const AMBIENT = new Set(['zk-act-drop', 'zk-act-doc-reminder', 'zk-act-retry-call']) + +/** + * Which queues a role has any business WORKING IN. + * + * Terminal stages stay visible to everyone — closed business is reporting, + * not work, and hiding it would leave an underwriter unable to see what + * became of a file they declined. Everything else appears only where the + * role can do something substantive. + * + * This gates the SIDEBAR, not the data. The overview still counts the whole + * book for every role, because an agent tracking leads they filed is a + * reasonable thing to want and a queue they cannot act in is not. + */ +export function visibleStages(roles) { + // Operations runs the desk. They cannot clear a referral — that stays + // exclusive to the underwriter — but the underwriting queue is theirs to + // watch, and an ops console that hides a queue because it holds one + // activity they may not press is hiding the wrong thing. + if (roles.includes('ops_admin')) return STAGES + + return STAGES.filter((s) => { + if (s.kind === 'end') return true + return (ACTIONS[s.uid] || []) + .filter((a) => !AMBIENT.has(a.uid)) + .some((a) => canPerform(roles, a.uid)) + }) +} + +/** Whether this user can file a lead at all, and through which doors. */ +export function entryDoorsFor(roles, entries) { + return entries.filter((e) => canPerform(roles, e.uid)) +} diff --git a/src/api/portfolio.jsx b/src/api/portfolio.jsx new file mode 100644 index 0000000..4d46450 --- /dev/null +++ b/src/api/portfolio.jsx @@ -0,0 +1,109 @@ +import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' +import { useZino } from './provider.jsx' +import { RV_LEADS, STAGES, phaseOf } from './config.js' + +/** + * The whole book, fetched ONCE and shared. + * + * The sidebar used to carry no counts, on the reasoning that a tally could only + * come from a second full list call that would then disagree with the queue's + * own total. That reasoning was right about the cost and wrong about the + * conclusion: a sidebar with no numbers means the only way to learn whether + * anything is waiting on you is to click all nine queues, which is the one + * question a console's navigation exists to answer. + * + * So there is no second call. The overview already fetched the whole book on a + * timer; that fetch moves here and both surfaces read it, which is one call + * fewer than before and makes the two agree by construction. + * + * Bounded at 200 rows, as the overview always was. Beyond that the honest + * answer is an aggregate endpoint rather than a bigger limit, and the counts + * would need to say they are partial — worth knowing before this app meets a + * real book. + */ + +const PortfolioContext = createContext(null) +const EMPTY = [] + +export function PortfolioProvider({ children }) { + const { client, user } = useZino() + // Identity, not just presence: switching user must not show the previous + // one's book while the new fetch is in flight. + const who = user?.id ?? user?.email ?? null + // Seeded from `who` rather than set inside the effect. Nothing here writes + // state synchronously during a render pass — a signed-out shell is 'ready' + // and empty from the first frame, and the first fetch only ever moves it + // forwards, so there is no loading flash and no cascading render. + const [state, setState] = useState(() => ({ + status: who ? 'loading' : 'ready', rows: EMPTY, at: null, error: null, + })) + const cancelled = useRef(false) + + const load = useCallback(() => { + if (!who) return Promise.resolve() + return client.recordView(RV_LEADS, { limit: 200 }) + .then((res) => { + if (cancelled.current) return + setState({ status: 'ready', rows: res?.data ?? res?.rows ?? res?.records ?? EMPTY, at: new Date(), error: null }) + }) + .catch((err) => { + if (cancelled.current) return + // A failed poll leaves a good book on screen. Only a first load is an error. + setState((p) => (p.status === 'ready' ? p : { status: 'error', rows: EMPTY, at: null, error: err })) + }) + }, [client, who]) + + useEffect(() => { + cancelled.current = false + load() + const id = setInterval(() => { if (document.visibilityState === 'visible') load() }, 30000) + return () => { cancelled.current = true; clearInterval(id) } + }, [load]) + + const value = useMemo(() => ({ ...state, reload: load }), [state, load]) + return {children} +} + +export function usePortfolio() { + const ctx = useContext(PortfolioContext) + if (!ctx) throw new Error('usePortfolio must be used inside PortfolioProvider') + return ctx +} + +const DAY = 86400000 +const daysToExpiry = (v) => { + if (!v) return null + const d = Date.parse(String(v).substring(0, 10) + 'T00:00:00Z') + return isNaN(d) ? null : Math.round((d - Date.parse(new Date().toISOString().substring(0, 10) + 'T00:00:00Z')) / DAY) +} + +/** + * Per-stage tallies for the sidebar. + * + * `waiting` is the number that goes on the badge: leads whose PHASE still needs + * a person. `working` is the rest — in the state, carried by an agent, not + * anyone's task. Badging the state total told an operator four leads needed + * them when two did, which is how a queue stops being believed. + * + * `urgent` marks a queue holding a renewal that has lapsed or expires within a + * week. It is the only reason to look at one queue before another, and it was + * invisible until you opened each one. + */ +export function useStageCounts() { + const { rows, status } = usePortfolio() + return useMemo(() => { + const out = {} + for (const s of STAGES) out[s.uid] = { total: 0, waiting: 0, working: 0, urgent: 0 } + for (const r of rows) { + const s = STAGES.find((x) => x.name === r.current_state_name) + if (!s) continue + const t = out[s.uid] + t.total += 1 + if (s.kind !== 'end' && phaseOf(s, r).kind === 'auto') t.working += 1 + else if (s.kind !== 'end') t.waiting += 1 + const d = daysToExpiry(r.renewal_due_date) + if (s.kind !== 'end' && d !== null && d <= 7) t.urgent += 1 + } + return { counts: out, ready: status === 'ready' } + }, [rows, status]) +} diff --git a/src/api/provider.jsx b/src/api/provider.jsx new file mode 100644 index 0000000..9adcfca --- /dev/null +++ b/src/api/provider.jsx @@ -0,0 +1,51 @@ +import { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react' +import { ZinoClient } from './client' + +const ZinoContext = createContext(null) + +/** + * Holds the client and the session. + * + * The stored user is restored on boot so a refresh does not flash the login + * screen. It restores an IDENTITY, never a permission set: every permission + * decision is the workflow's, made server-side on each submission. Nothing here + * hides a button to enforce a rule — the platform refuses, and the console + * reports what it said. + */ +export function ZinoProvider({ baseUrl, children }) { + const clientRef = useRef(null) + if (!clientRef.current) clientRef.current = new ZinoClient(baseUrl) + const client = clientRef.current + + const [user, setUser] = useState(() => (client.getToken() ? client.getStoredUser() : null)) + + const signOut = useCallback(() => { + client.logout() + setUser(null) + }, [client]) + + client.setAuthErrorHandler(() => setUser(null)) + + const signIn = useCallback( + async (email, password, orgId) => { + const res = await client.login(email, password, orgId) + const u = res?.user || { email } + setUser(u) + return u + }, + [client], + ) + + const value = useMemo( + () => ({ client, user, signIn, signOut, isAuthed: Boolean(user && client.getToken()) }), + [client, user, signIn, signOut], + ) + + return {children} +} + +export function useZino() { + const ctx = useContext(ZinoContext) + if (!ctx) throw new Error('useZino must be used inside ') + return ctx +} diff --git a/src/api/thread.js b/src/api/thread.js new file mode 100644 index 0000000..0ac01f8 --- /dev/null +++ b/src/api/thread.js @@ -0,0 +1,216 @@ +import { AGENTS } from './agents.js' +import { baseFieldId } from './config.js' + +/** + * THE WHATSAPP THREAD, BUILT ONCE. + * + * The conversation was being reconstructed twice — the timeline read it per + * audit row, the dialog read it per field — and the two disagreed. The trail + * printed one entry per turn, so a four-message exchange took more of the page + * than the entire underwriting chain, and a message the workflow recorded from + * inside a trigger (the payment request, the issuance note) appeared in the + * dialog and nowhere in the trail. One builder, two readers, one answer. + * + * WHY A THREAD IS NOT A LIST OF ROWS. The audit trail records activities; the + * conversation is a thing that persists ACROSS them. Three facts make it awkward + * and they are all handled here rather than in each screen's own guess: + * + * 1. The customer's turns and ours are separate activities — `customer-reply` + * is performed by the channel, `answer-customer` by Engage — so a turn is + * a FIELD on a row, not a row. + * 2. Two of our sends are not chat activities at all. Request Premium and the + * issuance step compose their message inside a trigger and write it to + * `customer_answer` alongside their own work (see 98/99/100 in the seed + * SQL). They belong in the thread and stay on their own step in the trail. + * 3. One submission is recorded up to three times — the trigger commit, its + * repeat, and the settle — so the same sentence arrives three times. + * + * `episodes` is what makes this renderable as a timeline entry. The thread is + * one conversation, but it happens in bursts: the customer argues about the + * quote, then KYC and underwriting run for twenty minutes, then the premium + * request reopens the same thread. An episode is one burst. Collapsing the + * whole thread into a single entry would date the payment exchange to the + * moment of the quote objection and destroy the chronology the trail exists + * for; leaving every turn as its own entry is what it did before. A burst is + * the unit that is both honest and short. + */ + +/** The two activities that ARE the thread — one turn each, either direction. */ +export const CHAT_ACTS = new Set(['zk-act-customer-reply', 'zk-act-answer-customer']) + +const INBOUND = 'customer_reply' +const OUTBOUND = 'customer_answer' + +/** + * The fields the thread OWNS. A step that writes one is not asked to print it + * as well — the message belongs to the conversation, and quoting it on the step + * too is how the payment request came to say the same sentence twice. + */ +export const THREAD_FIELDS = new Set([INBOUND, OUTBOUND]) + +/** Bookkeeping rows. They interrupt nothing: the platform writing a field is + * not a step that broke off a conversation. */ +const SYSTEM_ACT = 'DATA_UPDATE' + +/** + * Last resort for a step whose activity_name did not come back — without it the + * trail prints a raw slug like "zk-act-doc-reminder" in the middle of an + * otherwise readable story. A guess, but one that reads as English. + */ +export function prettyUid(uid) { + if (!uid) return 'Step' + return String(uid) + .replace(/^zk-act-/, '') + .split('-') + .filter(Boolean) + .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) + .join(' ') +} + +/** What to call a step. The server's own name first; the slug, tidied, after. */ +export function stepName(row) { + return row?.activity_name || prettyUid(row?.activity_id) +} + +/** + * `fields[]` is the platform's typed rendering of a submission; `data` is the + * raw fallback for a row the workflow could not resolve. + */ +function fieldsOf(row) { + return Array.isArray(row.fields) && row.fields.length + ? row.fields + : Object.entries(row.data || {}).map(([k, v]) => ({ field_id: k, value: v })) +} + +/** Who sent an outbound turn. Usually Engage; sometimes a person answering by + * hand, which must not be attributed to the machine. */ +function senderOf(row) { + const key = (row.user_roles || []).find((r) => AGENTS[r]) || null + return { agentKey: key, by: key ? AGENTS[key].short : (row.user_name || 'Zurich Kotak') } +} + +/** The turns carried by one audit row, in field order. */ +function turnsInRow(row) { + const out = [] + for (const f of fieldsOf(row)) { + const base = baseFieldId(f.field_id) + if (!THREAD_FIELDS.has(base)) continue + const text = typeof f.value === 'string' ? f.value.trim() : '' + if (!text) continue + out.push({ side: base === INBOUND ? 'them' : 'us', text }) + } + return out +} + +/** + * The thread, its bursts, and which audit row carries what. + * + * Returns: + * turns every message, oldest first + * episodes contiguous bursts, each with the steps that preceded it + * byRow row id -> { episodeId, sent, received }, so a step that sent a + * message can link into the thread instead of quoting it + */ +export function buildThread(rows) { + const empty = { turns: [], episodes: [], byRow: new Map() } + if (!Array.isArray(rows) || !rows.length) return empty + + // Sorted on (timestamp, id). One submission writes three rows in the same + // second, so a timestamp alone leaves their order to the sort's stability and + // puts a reply before the message it answers whenever the two land together. + const ordered = [...rows].sort((a, b) => { + const t = String(a.created_at).localeCompare(String(b.created_at)) + return t !== 0 ? t : (Number(a.id) || 0) - (Number(b.id) || 0) + }) + + const turns = [] + const episodes = [] + const byRow = new Map() + let current = null + // The steps seen since the last message, and whether any of them broke off + // the conversation. `pending` accumulates even before the first message so + // that the first episode can drop it: there is nothing to bridge yet. + let pending = [] + let broke = false + + for (const row of ordered) { + const mine = turnsInRow(row) + + if (!mine.length) { + // A chat activity that recorded no text is not a step that interrupted + // anything — it is an empty row. Bookkeeping is not a step either. + if (row.activity_id === SYSTEM_ACT || CHAT_ACTS.has(row.activity_id)) continue + if (current) broke = true + const name = stepName(row) + if (name && !pending.includes(name)) pending.push(name) + continue + } + + const who = senderOf(row) + for (const t of mine) { + const prev = turns[turns.length - 1] + // De-duped against the PREVIOUS turn only. A customer who asks the same + // thing twice because the first went unanswered has said it twice, and a + // thread that showed it once would hide exactly the impatience an + // operator needs to see. Only an immediate repeat is the platform + // recording one submission three times. + if (prev && prev.side === t.side && prev.text === t.text) continue + + if (!current || broke) { + current = { + id: `ep${episodes.length + 1}`, + turns: [], + // What ran between this burst and the one before it. Empty on the + // first, which begins the conversation rather than resuming it. + after: episodes.length ? pending : [], + anchorRowId: row.id, + anchorIsChat: CHAT_ACTS.has(row.activity_id), + } + episodes.push(current) + broke = false + } + pending = [] + + const turn = { + key: `${row.id}-${t.side}-${turns.length}`, + side: t.side, + text: t.text, + at: row.created_at, + rowId: row.id, + episodeId: current.id, + agentKey: t.side === 'us' ? who.agentKey : null, + by: t.side === 'us' ? who.by : 'the customer', + } + current.turns.push(turn) + turns.push(turn) + + const tally = byRow.get(row.id) || { episodeId: current.id, sent: 0, received: 0 } + if (t.side === 'us') tally.sent += 1 + else tally.received += 1 + byRow.set(row.id, tally) + } + } + + for (const ep of episodes) { + ep.count = ep.turns.length + ep.from = ep.turns[0].at + ep.to = ep.turns[ep.turns.length - 1].at + // The last exchange, which is where the conversation GOT to — what an + // operator scanning the trail is actually looking for. + ep.preview = ep.turns.slice(-2) + } + + return { turns, episodes, byRow } +} + +/** + * "Verify KYC and Underwriting Screen", "A, B +2 more" — a bridge, not a list. + * Used for the steps that interrupted a conversation and for the voices in it. + */ +export function listOf(names, max = 2) { + if (!names || !names.length) return '' + if (names.length <= max) { + return names.length === 1 ? names[0] : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}` + } + return `${names.slice(0, max).join(', ')} +${names.length - max} more` +} diff --git a/src/assets/brand/zurich_logo.webp b/src/assets/brand/zurich_logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..6f5c27ee2a8861a6e17d4b5b4bebd74348d57965 GIT binary patch literal 12418 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 CZCFG00A}vBm;^N1Rw>4b_b17 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�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 KeSM!!^6mjJc@zEs literal 0 HcmV?d00001 diff --git a/src/assets/fonts/source-sans-3-latin-600-normal.woff2 b/src/assets/fonts/source-sans-3-latin-600-normal.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..93511778f601f037194a86a011b356f298b4e035 GIT binary patch literal 15668 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 aqzmRLuoH$SetW;ZrJeO{{e>r+0RRA?c26?^ literal 0 HcmV?d00001 diff --git a/src/assets/fonts/source-sans-3-latin-700-normal.woff2 b/src/assets/fonts/source-sans-3-latin-700-normal.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3cb944ca31199f76bc2684bcd50a0ef935b2b8f0 GIT binary patch literal 15596 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 G0RR9FN-o#{ literal 0 HcmV?d00001 diff --git a/src/assets/fonts/source-sans-3-latin-ext-400-normal.woff2 b/src/assets/fonts/source-sans-3-latin-ext-400-normal.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..73c9edc69b3656ed236b864995329a4972d679d1 GIT binary patch literal 33024 zcmV)6K*+y$Pew8T0RR910D%Ai5dZ)H0Zh~Y0DzeQ0RR9100000000000000000000 z0000PMjC@q8-bZB9H&SIU_Vn-K~zWpk0KEW3WDQwf}2wdi#PxQHUcCAmI4GI1%*rp zwO0%WThbwM2i385KS1;`>LvqtGHv5;T4ePNnqA*c2Gg7A!wUCvs8HR~anapMr^z7* z+5i9le|}OC*_!-M+wI>sIDjH3s)YVPLgWvvXTdCp?3= zn_Sug{J500z`5piEzr}#0>aUQxz{R7IHg;fz)iM+cTE_!!QQeExgR9Tv>R#ddXE8R zdgGe$ys_TeJz@Qz(((>cLCag=g2Q&)EVEG2uH{60R;%z>UV|?j{mI4*FfAcan1Q-gT3j$#C~lE-g6AP4v5F* zNF`ddv7Y4Yed+nwuYbSSK96Q5Kq?9y11LbBii{%oi0TUsqySjq{fVF3yZe7*u(82l zV~jDzs2&U?QUMVxRD@wrMqwd>h|wrHK#6n)rG!<17>G&6hUb^tWB12c#qD-?+b;TF z*Z=pgYuT`|C}0Q-T6z*TV@RZ=iVcXBSV4tifRsWH+z;^X{bguG(JW~|6Wb_*FmdBG zNo3yf@6?)+?1dR?ckeF5w7?H!Ddd#!?|_nD=eJD}?I4#iaQ|yDD4j@YP@-6DQ1{$d z#O|%x%-`YPW0|K#YiZF-F9`TLiK05GXEh=bjHVKK2~psMpX@>C2In*<ln!q1**B>49IENXI zX)xVjYR`Y{?@c&`nP0s^-jjRXI_(HsFO3YCfiu!ukL=r;-zCqXhJd2zckNqBx$Wh& zOlbfGu)r|f3Lqbr;XwiTCoJq+t5;p>zOA!moxS$zlvBx^Hb6M}Kcc2<8OY_gwzTqU zExXWca{Ey>)qt{xo{S>Uq~%Azz&vxCjGOHtJq!?JY=;r8=5#ddbKxYG*x@W9az$dl z@G+-oAt=j+P z46w6DnFFd8u;`N9R0rG@(tG-n{J&(7>={FxoybFW(DtHzAWBa5kdtLP0EjOK**O5J z=9(I~#G>oDp1QjKou)K8XD`58RzTv8jbIwv6)!}9R$IzVY3F9eFAO#(!Urne-ECT$964(}*5wX21uX_uk7w)YUsA0~zvbA(8ZgSc^nc=CjJ^M?2ffP|O|nQkT| z%xp-MC`gPL$Z{(nE3JVfN`xd!hNMb`Y_S8f$6iRLOh~p|NWKG*V &O*++0J-c6 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 Y8Pn(tBbTt#o;>6oE584)RGI+*0RF0LegFUf literal 0 HcmV?d00001 diff --git a/src/assets/fonts/source-sans-3-latin-ext-500-normal.woff2 b/src/assets/fonts/source-sans-3-latin-ext-500-normal.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..dcaff794ba8181a0a0791aa3d5cbf83b3265c451 GIT binary patch literal 32940 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যQ-x!^{wAce7!mdvT26uF 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 literal 0 HcmV?d00001 diff --git a/src/assets/fonts/source-sans-3-latin-ext-600-normal.woff2 b/src/assets/fonts/source-sans-3-latin-ext-600-normal.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4ebc744fb4125323f1a0b9c4c099ce7f574d53ce GIT binary patch literal 32704 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 z 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 LKVPQ5z8wGnENw=q literal 0 HcmV?d00001 diff --git a/src/assets/fonts/source-sans-3-latin-ext-700-normal.woff2 b/src/assets/fonts/source-sans-3-latin-ext-700-normal.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2b448cb4f6b0f57e0acc5e4bce63fcce901ba6ae GIT binary patch literal 32956 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%0AaoFty@&t>sWqRPbG1l(yHF8gu*3#`2 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 Gsu2K%y%MMZ literal 0 HcmV?d00001 diff --git a/src/components/ActivityForm.css b/src/components/ActivityForm.css new file mode 100644 index 0000000..4cacf91 --- /dev/null +++ b/src/components/ActivityForm.css @@ -0,0 +1,398 @@ +.af { + display: flex; + flex-direction: column; + gap: 20px; +} + +.af__loading { + color: var(--zk-muted); + font-size: var(--fs-xs); +} + +.af__grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); + gap: 16px 20px; +} + +.af__field { + display: flex; + flex-direction: column; + gap: 6px; +} + +.af__field--wide { + grid-column: 1 / -1; +} + +.af__field > span { + font-size: var(--fs-2xs); + font-weight: 500; + letter-spacing: 0.03em; + color: var(--zk-muted); + display: flex; + align-items: center; + gap: 8px; +} + +.af__req { + font-style: normal; + font-size: var(--fs-3xs); + font-weight: 500; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--zk-blue); + background: var(--zk-tint-blue); + padding: 2px 7px; + border-radius: var(--r-pill); +} + +.af input, +.af select, +.af textarea { + font: inherit; + font-size: var(--fs-xs); + padding: 10px 12px; + border-radius: var(--r-md); + border: 1px solid var(--zk-line); + background: var(--zk-white); + color: var(--zk-ink); + width: 100%; + transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast); +} + +.af input:hover, +.af select:hover, +.af textarea:hover { + border-color: var(--zk-blue-light); +} + +.af input:focus, +.af select:focus, +.af textarea:focus { + outline: none; + border-color: var(--zk-blue); + box-shadow: var(--ring); +} + +.af select { + appearance: none; + padding-right: 34px; + /* The caret is drawn rather than loaded: an inline data URI keeps the select + consistent across platforms without another asset to serve. */ + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%235d6162' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 12px center; + background-size: 12px; +} + +.af textarea { + resize: vertical; + min-height: 84px; + line-height: 1.55; +} + +.af__multi { + display: flex; + flex-wrap: wrap; + gap: 7px; +} + +.af__chip { + font: inherit; + font-size: var(--fs-2xs); + padding: 6px 13px; + border-radius: var(--r-pill); + cursor: pointer; + border: 1px solid var(--zk-line); + background: var(--zk-white); + color: var(--zk-muted); + transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast); +} + +.af__chip:hover { + border-color: var(--zk-blue-light); + background: var(--zk-tint); + color: var(--zk-ink); +} + +.af__chip.is-on { + background: var(--grad-blue); + border-color: var(--zk-blue); + color: var(--zk-white); + box-shadow: var(--sh-xs); +} + +.af__actions { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 10px; + padding-top: 4px; +} + +.af__submit { + font: inherit; + font-size: var(--fs-xs); + font-weight: 500; + padding: 10px 26px; + border-radius: var(--r-md); + cursor: pointer; + border: 0; + background: var(--grad-blue); + color: var(--zk-white); + box-shadow: var(--sh-sm); + transition: background var(--t), box-shadow var(--t), transform var(--t-fast), opacity var(--t-fast); +} + +.af__submit:hover:not(:disabled) { + background: var(--grad-blue-hover); + box-shadow: var(--sh-md); + transform: translateY(-1px); +} + +.af__submit:active:not(:disabled) { + transform: none; + box-shadow: var(--sh-xs); +} + +.af__submit:disabled { + opacity: 0.5; + cursor: default; + box-shadow: none; +} + +.af__ghost { + font: inherit; + font-size: var(--fs-xs); + padding: 10px 20px; + border-radius: var(--r-md); + cursor: pointer; + border: 1px solid var(--zk-line); + background: var(--zk-white); + color: var(--zk-muted); + transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast); +} + +.af__ghost:hover { + border-color: var(--zk-grey); + background: var(--zk-tint); + color: var(--zk-ink); +} + +.af__err { + background: var(--zk-danger-tint); + border: 1px solid var(--zk-danger-line); + border-left: 3px solid var(--zk-danger); + border-radius: var(--r-xs) var(--r-md) var(--r-md) var(--r-xs); + padding: 12px 16px; + font-size: var(--fs-xs); + color: var(--zk-ink); + animation: zk-rise 0.2s var(--ease) both; +} + +.af__err strong { + font-family: var(--font-mono); + font-size: 0.85em; + margin-right: 8px; + padding: 1px 7px; + border-radius: var(--r-xs); + background: rgba(211, 47, 47, 0.1); + color: var(--zk-danger-ink); +} + +.af__err p { + margin: 7px 0 0; + font-size: var(--fs-2xs); + color: var(--zk-muted); + line-height: 1.55; +} + +.af__auto { + font-size: var(--fs-xs); + padding: 10px 12px; + border-radius: var(--r-md); + min-height: 41px; + border: 1px dashed var(--zk-line); + background: var(--zk-tint); + color: var(--zk-muted); + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.af__auto span { + font-size: var(--fs-3xs); + font-weight: 500; + letter-spacing: 0.09em; + text-transform: uppercase; + color: var(--zk-grey); + border: 1px solid var(--zk-line); + border-radius: var(--r-pill); + padding: 2px 8px; + background: var(--zk-white); +} + +/* ---- file / ocr ---- */ +.ff { + display: flex; + flex-direction: column; + gap: 8px; +} + +.ff__input { + display: none; +} + +.ff__drop { + display: flex; + flex-direction: column; + align-items: center; + gap: 3px; + width: 100%; + font: inherit; + padding: 16px 12px; + border-radius: var(--r-md); + cursor: pointer; + border: 1px dashed var(--zk-blue-light); + background: var(--zk-tint-blue); + color: var(--zk-blue-dark); + text-align: center; + transition: background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast); +} +.ff__drop svg { width: 20px; height: 20px; } +.ff__drop strong { font-size: var(--fs-2xs); font-weight: 500; } +.ff__drop span { font-size: var(--fs-3xs); color: var(--zk-grey); } + +.ff__drop:hover:not(:disabled) { + background: var(--zk-white); + border-style: solid; + border-color: var(--zk-blue); +} +.ff__drop:focus-visible { outline: none; box-shadow: var(--ring); } +.ff__drop:disabled { opacity: 0.65; cursor: default; border-style: solid; } + +/* Uploaded: the file as a fact, not a call to action. */ +.ff__file { + display: flex; + align-items: center; + gap: 8px; + padding: 9px 9px 9px 11px; + border: 1px solid var(--zk-line); + border-radius: var(--r-md); + background: var(--zk-white); +} +.ff__file > svg { width: 15px; height: 15px; flex: none; color: var(--zk-blue-dark); } + +.ff__name { + flex: 1; + min-width: 0; + font-size: var(--fs-2xs); + color: var(--zk-ink); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ff__replace { + flex: none; + font: inherit; + font-size: var(--fs-3xs); + font-weight: 500; + padding: 4px 10px; + border: 1px solid var(--zk-line); + border-radius: var(--r-pill); + background: var(--zk-white); + color: var(--zk-blue-dark); + cursor: pointer; + transition: background var(--t-fast), border-color var(--t-fast); +} +.ff__replace:hover { background: var(--zk-tint-blue); border-color: var(--zk-blue-mid); } +.ff__replace:focus-visible { outline: none; box-shadow: var(--ring); } + +.ff__read { + border: 1px solid var(--zk-blue-light); + border-left-width: 3px; + background: var(--zk-tint); + border-radius: var(--r-xs) var(--r-md) var(--r-md) var(--r-xs); + padding: 10px 12px; + display: flex; + flex-direction: column; + gap: 3px; + animation: zk-rise 0.22s var(--ease) both; +} + +.ff__readlabel { + font-size: var(--fs-3xs); + font-weight: 500; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--zk-blue-dark); + margin-bottom: 3px; +} + +.ff__read div { + font-size: var(--fs-2xs); + color: var(--zk-ink); +} + +.ff__read em { + font-style: normal; + color: var(--zk-grey); + text-transform: capitalize; + margin-right: 6px; + font-size: var(--fs-2xs); +} + +.ff__err { + font-size: var(--fs-2xs); + color: var(--zk-danger-ink); + background: var(--zk-danger-tint); + border: 1px solid var(--zk-danger-line); + border-radius: var(--r-md); + padding: 8px 11px; +} + +/* A field the form is waiting on. Marked on the label rather than the input so + the name is highlighted too — an operator scanning a wide form is looking for + the LABEL they missed, not for a red box. */ +.af__field.is-missing > span { color: var(--zk-danger-ink); } +.af__field.is-missing input, +.af__field.is-missing select, +.af__field.is-missing textarea { + border-color: var(--zk-danger-line); + background: var(--zk-danger-tint); +} +.af__field.is-missing input:focus, +.af__field.is-missing select:focus, +.af__field.is-missing textarea:focus { + border-color: var(--zk-danger); + outline-color: var(--zk-danger); +} + +/* The form talking about itself, or relaying a field-level refusal. Distinct + from af__err, which is for a failure the operator cannot fix by typing. */ +.af__err--soft { + background: var(--zk-danger-tint); + border: 1px solid var(--zk-danger-line); + color: var(--zk-danger-ink); +} +.af__err--soft ul { margin: 6px 0 0; padding-left: 18px; } +.af__err--soft li { margin: 2px 0; } + +/* ---- form sections ---- */ +.af__sec + .af__sec { margin-top: 22px; } + +.af__sech { + margin: 0 0 10px; + font-size: var(--fs-3xs); + font-weight: 500; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--zk-grey); +} + +/* Uploads size to their content and never stretch to the tallest card in the + row, so a document that has been read does not pull its neighbours down. */ +.af__grid--docs { align-items: start; } diff --git a/src/components/ActivityForm.jsx b/src/components/ActivityForm.jsx new file mode 100644 index 0000000..8ee1ab3 --- /dev/null +++ b/src/components/ActivityForm.jsx @@ -0,0 +1,402 @@ +import { useEffect, useRef, useState } from 'react' +import { useZino } from '../api/provider.jsx' +import { baseFieldId, fieldApplies, fieldIsStamped } from '../api/config.js' +import { describeError, describeValidation } from '../api/errors.js' +import FileField from './FileField.jsx' +import './ActivityForm.css' + +/** + * The HTML input each workflow data_type maps to. `phone` and `email` were both + * falling through to plain text, which costs the keyboard on a phone and the + * browser's own validation everywhere. + */ +const INPUT_TYPES = { + number: 'number', + date: 'date', + phone: 'tel', + email: 'email', +} + +/** + * Renders whatever /view/form-screens returns for an activity — labels, types, + * select options and which fields are mandatory — and submits it straight back. + * + * Nothing about this form is defined in the frontend. Add a field to the + * activity in Studio, redeploy, and it appears here with no code change. That + * is the point: the workflow is the source of truth, and a hardcoded form would + * quietly drift from it. + * + * The ONE thing filtered here is which upload slots apply to the lead's product + * line. Collect Documents serves motor and SME from a single form and the + * activity carries no `field_rules`, so without this a motor renewal is asked + * for a Udyam certificate. See DOC_SLOTS in api/config.js — including why that + * table should stop existing once the rules are seeded on the activity. + */ +export default function ActivityForm({ activityUid, instanceId, lead, onDone, onCancel, onStale }) { + const { client } = useZino() + const [schema, setSchema] = useState(null) + const [values, setValues] = useState({}) + const [error, setError] = useState(null) + // Which required fields were empty on the last attempt. Kept separate from + // `error`, because this is the form talking about itself rather than the + // server refusing something. + const [missing, setMissing] = useState([]) + // Field ids filled from the lead record rather than typed. OCR may overwrite + // these — the document is more authoritative than a copy of the record — but + // must never overwrite something a person typed. + const seededRef = useRef(new Set()) + const [busy, setBusy] = useState(false) + + useEffect(() => { + let dead = false + setSchema(null); setError(null); setValues({}) + client.formSchema(activityUid, instanceId) + .then((s) => { + if (dead) return + setSchema(s) + // The server resolved a prefill pipeline for this activity — it stamps + // the channel from the door and the agent from the signed-in user, so + // the form never asks for either. Seed the inputs with what it sent. + // + // The two sides key differently, and matching only on f.id is why this + // silently did nothing. A form field is the ACTIVITY key, which carries + // a numeric suffix because a workflow version may use one global on + // several activities — partner_code_3, rm_or_agent_id_3, + // source_channel_4. The pipeline's fieldMapping names the GLOBAL — + // partner_code, rm_or_agent_id, source_channel. Neither is wrong; they + // are different names for the same field, and nothing between them + // reconciles it. + // + // So: exact id first, then the field's uid, then the global name with + // the suffix stripped. Accepting all three means this keeps working + // whichever convention a pipeline is authored in, rather than breaking + // again the next time one is written the other way. + const pre = s.prefill_data || s.prefillData || s.field_defaults || {} + const seed = {} + if (pre && typeof pre === 'object') { + for (const f of s.fields) { + const base = baseFieldId(f.id ?? '') + const v = pre[f.id] ?? pre[f.uid] ?? (base ? pre[base] : undefined) + if (v !== undefined && v !== null && v !== '') seed[f.id] = v + } + } + + // THE LEAD ALREADY KNOWS MOST OF THIS. The document form mirrors + // fourteen fields the record carries — registration, make and model, + // previous insurer, expiry, policy number, PAN — so the OCR can write + // into them. Rendered blank, they read as fourteen more things to type. + // Seed each from the lead by its base key, so an agent uploading for + // KA01MF6618 sees KA01MF6618 already there. + // + // Server prefill wins, then anything already typed. Files and generated + // ids are never seeded — a file reference is not a value to copy, and an + // id_gen is the platform's to issue. Only on an existing lead: an INIT + // form has no record behind it. + const seededFromLead = new Set() + if (lead && instanceId) { + for (const f of s.fields) { + if (seed[f.id] !== undefined) continue + if (['file', 'ocr', 'id_gen'].includes(f.data_type)) continue + const v = lead[baseFieldId(f.id ?? '')] + if (v !== undefined && v !== null && v !== '' && typeof v !== 'object') { + seed[f.id] = v + seededFromLead.add(f.id) + } + } + } + seededRef.current = seededFromLead + + if (Object.keys(seed).length) setValues(seed) + }) + .catch((e) => { if (!dead) setError(e) }) + return () => { dead = true } + // `lead` is READ here but deliberately not a dependency. It is the parent's + // polled record object, so its identity changes on every refresh; listing it + // would re-run this effect, re-fetch the schema and call setValues(seed) — + // discarding whatever the operator had typed, every few seconds, mid-form. + // The seed is a one-time starting point, not a subscription. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [client, activityUid, instanceId]) + + function set(id, v) { + // Typed by hand: from here on it outranks any document. + seededRef.current.delete(id) + setValues((p) => ({ ...p, [id]: v })) + // Clear the complaint as soon as the field is filled. Leaving a red field + // marked after it has been corrected teaches people to ignore the marking. + setMissing((p) => (p.includes(id) ? p.filter((x) => x !== id) : p)) + } + + // Computed before the early returns below use it, and before submit: a field + // that was never offered must never be sent. + // + // If the lead's line would hide EVERY field, the filter is not removing noise + // any more — it is removing the activity. Capture Motor Risk is twelve motor + // fields and is runnable from Contacted whatever the product is, so on an SME + // lead this would otherwise render a form with nothing in it and a live Submit + // button. Show the activity whole and let the operator see what it is asking. + // + // THE LINE CAN BE CHOSEN ON THE FORM ITSELF. On an INIT form there is no + // lead yet, so `fieldApplies` had nothing to filter on and every entry form + // asked a motor renewal for a business name. But the product line IS on that + // form, three boxes up — the person has already said "Motor" by the time the + // question is drawn. So visibility reads the live answer first and the saved + // lead second, and the form narrows as it is filled. + const effLead = (() => { + const live = schema?.fields.find((f) => baseFieldId(f.id) === 'product_line') + const chosen = live ? values[live.id] : undefined + if (!chosen) return lead + return { ...(lead || {}), product_line: chosen } + })() + + const applicable = schema ? schema.fields.filter((f) => fieldApplies(f.id, effLead)) : [] + // Filtering must never hide a field the workflow requires: `submit` sends only + // what is rendered, so a hidden mandatory field becomes a 400 naming something + // that is not on screen and cannot be filled. Hiding everything is the same + // failure in the large — it removes the activity rather than its noise, and + // Capture Motor Risk is twelve motor fields that stay runnable on an SME lead. + const hidesMandatory = schema ? schema.fields.some((f) => f.mandatory && !fieldApplies(f.id, effLead)) : false + const fields = applicable.length && !hidesMandatory ? applicable : (schema?.fields ?? []) + + /** + * Turn an /ocr-extract response into form values. + * + * THE ENDPOINT DOES NOT SPEAK THE FORM'S LANGUAGE. It answers keyed by the + * ocr_config's `extraction_fields[].key` — `reg_no`, `engine_cc`, `fuel` — + * because that is what the vision prompt was asked to produce. The form's + * fields are `motor_reg_no_6`, `motor_cc_3`, `motor_fuel_3`. Written straight + * in, as they were, every extracted value landed on a key no field renders: + * the read succeeded, the panel said so, and nothing filled. + * + * The bridge is already on the field. `ocr_config.field_mappings` maps + * extraction_key -> target_field (the GLOBAL name), and the form field is that + * global plus a per-form suffix. So: key -> target -> the field whose base id + * matches. Same suffix rule as prefill and the same trap, in a third place. + */ + function applyExtraction(ocrField, extracted) { + const maps = ocrField?.properties?.ocr_config?.field_mappings + ?? ocrField?.ocr_config?.field_mappings ?? [] + const all = schema?.fields ?? [] + + // extraction_key -> form field id + const target = {} + for (const m of maps) { + if (!m?.extraction_key || !m?.target_field) continue + const hit = all.find((f) => f.id === m.target_field) + ?? all.find((f) => baseFieldId(f.id) === m.target_field) + if (hit) target[m.extraction_key] = hit.id + } + + setValues((prev) => { + const next = { ...prev } + for (const [key, val] of Object.entries(extracted)) { + if (val === null || val === undefined || String(val) === '') continue + // An unmapped key may still name a field directly on forms whose + // extraction keys ARE the field names. + const id = target[key] + ?? all.find((f) => f.id === key)?.id + ?? all.find((f) => baseFieldId(f.id) === key)?.id + if (!id) continue + // Never overwrite something a person typed. A value we copied off the + // lead is fair game — the document is the better source for it. + const isBlank = next[id] === undefined || next[id] === '' + if (isBlank || seededRef.current.has(id)) { + next[id] = val + seededRef.current.delete(id) + } + } + return next + }) + } + + function isEmpty(v) { + return v === undefined || v === null || v === '' || (Array.isArray(v) && v.length === 0) + } + + async function submit(e) { + e.preventDefault() + + // Check here rather than letting the workflow do it. The server's answer is + // correct and unreadable — "product_line_4(required)" — and it costs a round + // trip to be told something this form already knew. id_gen is issued + // server-side and is never the operator's to fill. + const gaps = fields.filter((f) => f.mandatory && f.data_type !== 'id_gen' && isEmpty(values[f.id])) + if (gaps.length) { + setMissing(gaps.map((f) => f.id)) + setError(null) + // Put the first offender on screen. On a form this wide the empty field + // is often above the fold and the message below it. Scrolling to the + // LABEL rather than focusing an input works for every field type, + // including the file and OCR widgets that render no input at all. + requestAnimationFrame(() => { + document + .querySelector('.af__field.is-missing') + ?.scrollIntoView({ behavior: 'smooth', block: 'center' }) + }) + return + } + + setMissing([]) + setBusy(true); setError(null) + // Send only fields the activity defines. A submission is schema-validated + // and an unknown field is fatal, so empties are dropped rather than sent. + const payload = {} + for (const f of fields) { + // id_gen is issued server-side and stripped from the submission. Sending + // it would be forging a reference the platform owns. + if (f.data_type === 'id_gen') continue + const v = values[f.id] + if (v === undefined || v === '' || (Array.isArray(v) && v.length === 0)) continue + payload[f.id] = f.data_type === 'number' ? Number(v) : v + } + try { + const res = instanceId + ? await client.activity(instanceId, activityUid, payload) + : await client.start(activityUid, payload) + onDone?.(res) + } catch (err) { + setError(err) + // The lead moved under the form. Nothing the operator can fix by reading — + // tell the page to re-fetch so the actions on offer are the real ones. + if (describeError(err).kind === 'stale') onStale?.() + } finally { + setBusy(false) + } + } + + if (error && !schema) return
Could not load the form — {describeError(error).title}
+ if (!schema) return

Loading the form…

+ + // Stamped fields are in `fields` — they validate and they submit — but they + // are not drawn. See STAMPED_FIELDS. A stamped field that came back EMPTY is + // drawn anyway: source_channel is mandatory, so a prefill that did not + // resolve would otherwise fail validation against a box that is not on the + // screen and cannot be filled. + const visible = fields.filter((f) => !fieldIsStamped(f.id) || isEmpty(values[f.id])) + + /* DOCUMENTS GET THEIR OWN ROW. In one flat auto-fit grid the uploads sat + beside plain inputs, and an upload that has read a document is several + times taller than a text box — so a row carried three tall OCR cards and + three short fields, and the form went ragged with the inputs stranded up + beside the buttons. Split in two, each grid is internally one height. */ + const isDoc = (f) => f.data_type === 'file' || f.data_type === 'ocr' + const docFields = visible.filter(isDoc) + const dataFields = visible.filter((f) => !isDoc(f)) + + const renderField = (f) => { + const opts = f.properties?.options || [] + const v = values[f.id] ?? (f.data_type === 'multiselect' ? [] : '') + return ( +