From 8939b1cab9da45b2ee6a39db9e39cc0bbd08a6ab Mon Sep 17 00:00:00 2001 From: LincPay Date: Thu, 6 Aug 2026 20:02:38 +0530 Subject: [PATCH] =?UTF-8?q?docs:=20UI=20README=20=E2=80=94=20the=20three?= =?UTF-8?q?=20surfaces=20and=20the=20house=20pattern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Points at the backend README for project documentation and covers what is specific to this app: the three routes and their tiers, why login routing is a convenience the backend does not trust, and the useQuery + demo fallback + Demo data pill pattern every screen follows. Records why the demo fallbacks deliberately contain failure states. A demo where every upload is clean and every cell is publishable teaches the wrong thing — a reviewer who only sees green rows will not know the rejection panel or the suppression behaviour exist. Carries the DataMeet CC BY 4.0 attribution. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..34a8019 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# UdyamLinc — UI + +Three surfaces in one Vite/React app, matching the three institutional tiers. Full project documentation, including the demo path and what is real versus seeded, lives in **`../UdyamLinc-Backend/README.md`**. + +```bash +npm install +npm run dev # http://localhost:5182 +``` + +The backend is expected at `http://localhost:8082/api/v1/udyam`. Override with `VITE_UDYAM_API_BASE_URL` in `.env.local`. + +--- + +## The three surfaces + +| Route | Tier | Shell | +|---|---|---| +| `/nabard` | NABARD — aggregates only | `features/nabard` | +| `/officer` | Bank console — one institution's book | `features/officer` | +| `/app` | Enterprise PWA — offline, Hindi-first | `features/enterprise` | + +Both staff tiers share one sign-in form and land in different portals; `homeFor()` picks the destination from the role. That routing is a **convenience only** — the backend re-derives the tier from the signed JWT and refuses the other surface with a `403`, so a tampered session gains nothing. + +The NABARD portal is deliberately a different chrome from the bank console. An apex user and a branch officer are not two ranks of one job, and a portal that looked identical would invite the assumption that the apex user is a bank user with more rights. + +--- + +## The house pattern + +Every screen follows the same shape, and new ones should: + +```tsx +const { data, isError } = useQuery({ queryKey: [...], queryFn: () => get('/path') }) +const demo = isError +const rows = data ?? demoRows() // in-file fallback from lib/demo/ +… +{demo && } +``` + +A screen must render with the backend down — field devices are on patchy 2G — but it must **say so**. The "Demo data" pill means that screen's call failed, not that the whole app is a mock. + +Demo fallbacks deliberately include failure states: the data-entry fallback contains rejected rows, and the NABARD fallback contains a bank below the suppression threshold. A demo where everything is clean teaches the wrong thing — a reviewer who only ever sees green rows will not know the rejection panel exists. + +--- + +## Screens that carry the argument + +- **`/officer/rules`** — every trip-wire with its outcome, including the ones that were *skipped* and why. This is the screen that shows the system refusing to fire on stale data. +- **`/officer/feeds`** — provenance. Mandi rows carry a source: `Agmarknet`, or an amber **Hand** chip for a price somebody typed. By the time a price reaches a feature the two are indistinguishable, so the distinction has to be visible here. +- **`/officer/data-entry`** — upload, preview, commit. Accepted, rejected and overwriting rows stay in three separate groups. +- **`/nabard`** — the India choropleth and the zone → state → district drill-down. States with no portfolio are drawn in a neutral grey that is nowhere on the stress ramp, so absence is never read as health. + +--- + +## Checks + +```bash +npx tsc -b # types +npx oxlint src # lint +npm run build # production build +``` + +All three are expected to pass before a commit. + +--- + +## Attribution + +State boundaries by the [DataMeet India community](http://datameet.org/) ([datameet/maps](https://github.com/datameet/maps)), used under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Simplified for display and **not an authoritative depiction of any boundary**. The credit renders on the map itself, as the licence requires.