docs: UI README — the three surfaces and the house pattern
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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<T>('/path') })
|
||||
const demo = isError
|
||||
const rows = data ?? demoRows() // in-file fallback from lib/demo/
|
||||
…
|
||||
{demo && <StatusPill status="Demo data" />}
|
||||
```
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user