What every screen is for, what data it shows and where each field comes from, what every call-to-action does, and how the data flows — for a builder with zero EHFL context. The clickable truth is the prototype; doc 02 holds the rules.
Easy Branch Desk — the company's single working surface. This document tells a builder with zero EHFL context what every screen is for, what data it shows and where each field comes from, what every call-to-action does, and how data flows end to end. The clickable truth is reference/branch-desk-prototype.html (v11); the rules are doc 02; the tables are doc 04; the API is doc 05. Where this BRD and doc 02 differ, doc 02 wins.
Problem. Case work at EHFL runs on offline artefacts — a DRM stuck-cases Excel, a reply-tracker sheet, morning/evening commitment mails, per-case WhatsApp threads. They cost hours daily, die with attrition, and hide cases.
Product. One role-based desk where every stuck loan is a card with a named owner, a clock and one best next action; where every function plans its morning on the system, the plans consolidate to HO at 10:30, and the evening result is compiled from LOS/LMS — never reported; and where every chase, reply and escalation is an event on the case, visible to everyone on it.
Success measures (tracked from the read models, targets in Settings): ≥90% of field users open the desk each working day; ≥80% of past-TAT cases touched same-day by week 2; ≥95% of in-flight cases carry a real (non-placeholder) disbursal date; ≥70% of chases answered within 1 working day; new-joiner time-to-first-productive-day ≤ 1 day; the four offline artefacts retired after two clean parallel days.
Login (SSO / LOS token) resolves a person → role + scope from org_person (+ org_los_user mapping, C3a rules; HRMS designation wins conflicts). A person sees only their scope. The prototype's header tabs simulate exactly these logins.
| Role | Level | Scope of data | Screens |
|---|---|---|---|
| RM | L1 | Own cases in own branch | Simple list, case sheet, Plan, Close, Messages |
| DBM | L2 | Own spoke | RM screens + approve spoke plans |
| DRM | L3 | Hub + spokes (cluster) | Simple/Full desk, team, leads bulk, approve + confirm branch plan, consolidated branch plan |
| BCM (U1) | — | Branch credit queue (+ state pickup) | Credit queue, credit plan, replies |
| Regional credit (U2) | — | State credit | Same + accepts BCM plans |
| Branch/State Ops | — | Branch / state ops queues | Ops queue, ops plan, replies |
| Collection Manager | — | Branch overdue book | CM screen, plan, close |
| Legal (cluster/state), Technical (branch→zonal) | — | State queue for their function | Queue, plan, replies |
| Regional head → Sr RBM → ZBM → Business Head → HO | L4–L7 | Own span, read-only | Standards, 10:30 grid, evening result, leaderboard; drill to any branch desk |
Server-side scope checks on every endpoint (CLAUDE.md rule 4). Customer phone/email/address/PAN/Aadhaar never reach any client (rule 3); collections show masked account ids only.
Every role's screen = (a) identity header with live scope numbers, (b) the standard strip — Plan my day · Close my day · Messages — always in the same position, (c) the role's queue as cards (phone) or table (desktop), (d) the shared case sheet/drawer for actions. Simple mode rules (rule 6): ≥16px text, ≥56px labelled buttons, one red main action per card, no codes, date chips not date inputs, lasting Done ✓, EN/HI via i18n_string.
The day cycle (all times are Settings rows): plans filed by 09:30 → manager acceptance by 10:30 → freeze_morning_grid job at 10:30 writes the branch×function grid → workday of case actions → compile_day_plans 19:00 (provisional; final 23:55) writes said-vs-done from LOS/LMS → compile_scores → planning window flips to tomorrow at 19:00. Plans are immutable after submit except through the approver; the plan button renders filed-locked (green) until 19:00.
Format per screen: Purpose · Data (field → source) · CTAs (control → effect → event) .
desk_case scoped to rm_code; progress bar = touched-today / needed (desk_event); ranked list per doc 02 R9 priority score.desk_stage_label); late/on-time (days_in_stage vs TAT from desk_config); highest-priority trigger line (R10 triggers: rmx/conflict/proposed/expiring/noaccept/nocall); waiting-on (owner resolution R3) or customer's WhatsApp reply (S8 feed); last status line ▸ + thread summary ("n updates · last by X (role) · time") — recomputed from desk_event on every write, so a save anywhere updates every viewer's card face; Done ✓ line if touched today; committed-date pill with moves count and conflict note (R5).desk_picklist per lane) + note → status event.date event with official = (actor is DRM/DBM); RM dates are proposals; DRM one-tap confirm; history + conflict per R5.chase event → notification_outbox (WhatsApp Business API/email/in-app).call event; duration via webhook.comment event; tagged parties notified + case flagged "Tagged" in their queue.reassign), Escalate now (esc), Cancel with reason (cancel).status:Application started, Not-mine reassign to DRM pool); login stepper (norm ⚙) + file ticks; money-out ticks; ADR ticks; collection ticks. Submit → day_plan row (plan_function business) with items JSON; toast confirms; button locks green.U1 pending + BUW done · awaiting U1, ordered oldest-first; other branches' U1 queues in the state (oldest 6); PD pool = U1 queue + awaiting-U2; ADRs raised by credit.next event per case ("Day close — next action reply event lands on the branch's card instantly; others land in Comment. Delivery pipes (WhatsApp/email) are transport only; the thread is the record.desk_config (doc 14). Scores appear only here — never on field screens.LOS (read replica) ─┐
LMS (read replica) ─┼─ case builder job (15 min, staging-swap, LAN-dedupe) → desk_case (read model)
HRMS↔LOS users ─┘ org_person / org_branch_scope / routing chains
user action (form) → POST /events (idempotent) → desk_event (append-only) ─┬→ recompute card face / thread / counters
├→ notification_outbox → WhatsApp API / email / in-app
└→ Metabase (reads branch_desk directly)
Exotel: click-to-call POST → masked bridge; call-log webhook → call event with duration
Customer WhatsApp replies (S8) → desk_case.customer_says → cards + triggers
06:00 snapshot_open_items → desk_open_snapshot
09:30 plans (day_plan) → 10:30 freeze_morning_grid → HO grid (read-only L4–L7)
19:00 compile_day_plans (LOS/LMS only) → results on plans/grid → compile_scores → desk_score → leaderboard
19:00 planning window flips to next working day; 23:55 final compile catches late LOS entries (F3a)
escalation job (daily, working days): unanswered chase → +1 level, skip unnamed, cc manager → outbox
No AI and no workflow orchestrator anywhere above — plain scheduled SQL/TypeScript jobs (rule 0). All schedules and thresholds are desk_config rows.
Privacy: rule 3 + masked telephony + masked account ids; access logs on owner/HO views. Performance: Today list < 2s on 3G-class connections at 09:25 load (C11 drill); read model refresh ≤15 min; chase delivery ≤1 min. Reliability: idempotent writes (client_event_id), append-only events, 10-s undo only; kill switch per module; parallel run week 1. Auditability: every number on a management screen reproducible from desk_event + desk_case as of its timestamp; config changes maker–checker with config_audit. Localisation: every string through i18n; Hindi at launch. Offline: retry queue for event posts; plans require connectivity (accepted).
Out: credit decisioning screens, collections legal workflows, document upload (stays in LOS), bureau-alert screens, voice-note transcription. Future (additive, config-first): tranche/partial-disbursement module, customer-ticket feed into open items, more languages, TSM/ASM layers, contest views reading desk_score (e.g. Diwali se Pahle Diwali), Lovable/EASY-OS convergence.
Rules → doc 02 (R1–R17) · tables → doc 04 · API → doc 05 · frontend patterns → doc 06 + reference/source · jobs & integrations → doc 07 · privacy → doc 08 · build order & prompts → doc 09 · acceptance → doc 10 + golive-checks.xlsx (C1–C12) · config → doc 11 · day plan → doc 12 (F1–F11) · risks → doc 13 · scoring → doc 14. Golden cases: docs/golden-cases.json must pass before any screen ships.