Skip to content

Admin Panel MVP, round 2: what round 1 left open ​

Purpose. Round 1 (prompt) came back on 2026-09-28. It was pulled fresh, diffed against the pre-round files and checked item by item. Most of it is resolved. This round closes what is still open, the regressions round 1 introduced, and the owner's three decisions of the same day. Nothing in the Admin Panel is built until round 2 comes back and is approved.

  • Status: sent and returned 2026-09-29: 24 of 37 points resolved, 13 partly, none still open, no regression. What remains is round 3 (QRS-1451). Drafted 2026-09-28; tracker QRS-1450, programme QRS-1404.
  • Send it as one message in the same Claude Design chat. The paste-ready copy is D:\DevCache\design-prompts\PROMPT-3-admin-round-2.txt (under 15 KB). The round-1 paste of 46 KB lost its middle section, so no round is sent with the PDPR attached again: that chat already holds it.
  • Review surface: the approved artboards and, later, the build side by side on http://localhost:8091/admin-review.html (outside the repo; see the assessment, increment 1).

What round 1 delivered ​

Three independent reviews read the new files against the round-1 brief, each verdict with a file and line. The two highest-impact claims of each review were re-checked by hand, and one was withdrawn: a review reported no RBAC_v1.dc.html, but list_files shows it exists (the review only had the local mirror). Files are under prototype/.

ItemVerdictWhat is resolvedWhat is still open (this round)
1 · Staff sign-inresolved, 3 defectsA standalone SignIn.dc.html, with all eight states as a prop and one "session ended" state that returns the person to the desk they were on (verified end to end). The role picker and hub links are gone.The stop screens name the wrong person (admin-shell.js:1006 ends the session first). There is no dark mode. The copy says more than the app knows.
2 · Set your passwordresolved, 2 defectsInvite with name and role, reset, one "link no longer valid", success straight into the panel, the four rules live (staff-core.js:418).There is no network-failure state. The reset copy contradicts Access control on when sessions end.
3 · Staff in Access controlresolved, 5 defectsThe staff list, invite, pending, resend, revoke, deactivate with lead handover, reactivate, the refusals, a real staff picker, the in-app date picker, and the union of assignments.Two refusals cannot be previewed. A revoked invite becomes "Deactivated". There is no way to extend or end an assignment. A role change can orphan leads. The SCREENS.md row still describes the enterprise desk.
4 · One role modelresolved, 4 defectsplatform/staff-core.js is the only model. The shell's canOpen comes from view. Users and Leads read the signed-in person. Own-leads scope works (Super Admin 1,840, Sales Executive 301).A Platform Administrator can assign roles. crm.create, crm.export and crm.delete gate nothing. Lead owners include admins. The Users record does not link to Access control.
5 · Not built yetresolved, 6 defectscapabilities.js has all eleven desks plus role editing, lead messaging, user segments and the support view. The nav marks them "Not ready yet". The Overview shows reserved tiles."Active cards" is dropped, not reserved. "Waiting on you" shows 0. The Users chain hides values as well as links. Segment and lifecycle controls are still live in Users.
6 · What is livemostly resolved, 1 regressionHolds name what is held, with copy that follows the choice and a reason-privacy line. Won needs an account link. The import flow gives a verdict per row, with line numbers and both kinds of duplicate. The Overview's Access control signals are exactly as corrected.Regression: the Users record no longer shows workspaces and roles. The WhatsApp health row reads the unbuilt Communications figure. Pulse counts leads as registered people. The audit seed shows reserved actions as done. Bulk actions are wrong.
7 · Handbook entry pointsresolved, 1 defectA Handbook link in the shell, and "How this desk works" on every desk.The URLs use internal ids (/crm, /rbac).
8 · Copy and controlspartlyAuditor banners. Expiry shown as a derived line. The reset-or-OTP action is gone. Two-key erase is reserved.Stage ids are only half done (about ten label comparisons remain). Dashes are used as empty-value placeholders on Users, Leads and the Overview.

Done well, keep as is: the session names a staff member and never a role, so an expired assignment takes effect on the next check. Refusals are sentences, never silently disabled controls. The reserved-panel rule comes from one registry. Deactivating someone blocks until their leads have a new owner.

Owner decisions, 2026-09-28 (settled, in the prompt below):

  1. Only a Super Admin assigns roles. A Platform Administrator views Access control and changes nothing.
  2. Only Sales Manager and Sales Executive own leads and appear on the Team tab.
  3. A reset ends every session when the link is sent.

Settled from existing rules, not re-asked:

  • Industries are the platform's fourteen keys from supabase/migrations/20260808120000_v2_taxonomy.sql:236 (QRS-874).
  • The sign-in health row reads sign-in code delivery, a figure the backend holds in communication_messages. It never reads the Communications desk's channel figure.
  • Deleting a lead is reserved: a lead is closed as Lost, never deleted, so the audit trail survives.
  • A revoked invite leaves the staff list, and the audit log keeps the event.

The prompt ​

Paste Block 1 and Block 2 as one message. Do not paste the PDPR again: the chat already holds it.

Block 1: the product you are extending ​

text
YOU ARE EXTENDING AN EXISTING APPLICATION, NOT BUILDING A NEW ONE.

This is round 2 of the QR setu Admin Panel correction, in prototype/admin-panel/ and
prototype/platform/. Round 1 is APPROVED except the points in Block 2. Keep everything else
exactly as it is: do not restyle, rename or restructure anything Block 2 does not name.

STUDY THESE BEFORE CHANGING ANYTHING. They are the product you are extending.
  prototype/admin-panel/admin-shell.js       the chrome: nav, header, palette, deny screen, change password
  prototype/admin-panel/SignIn.dc.html       staff sign-in (round 1)
  prototype/admin-panel/SetPassword.dc.html  set your password (round 1)
  prototype/admin-panel/RBAC.dc.html         Access control: staff, roles, assignments, audit log
  prototype/admin-panel/Users.dc.html        the people and accounts desk
  prototype/admin-panel/Leads.dc.html        Leads & CRM
  prototype/admin-panel/Overview.dc.html     the command centre
  prototype/admin-panel/future-date-picker.js  the in-app date picker
  prototype/admin-panel/qr-toast.js          the toast pattern
  prototype/platform/staff-core.js           the one role model and staff lifecycle (round 1)
  prototype/platform/users-core.js           the user ecosystem model
  prototype/platform/leads-core.js           the lead model
  prototype/platform/ops-signals.js          the only cross-desk aggregate
  prototype/platform/capabilities.js         the reserved-panel registry
  prototype/platform/desk-records.js         records the unbuilt desks work on
  prototype/platform/controls.js             platform policies as data
  SCREENS.md                                 the registry; update every row you change

BEFORE CHANGING ANYTHING, PRODUCE TWO SHORT LISTS: REUSED (what you use unchanged) and NEW (only
if something genuinely needs a new pattern, with one sentence of why). Then make the changes. No
new screens are expected in this round.

Block 2: this round ​

text
ADMIN PANEL, ROUND 2. EVERY POINT BELOW IS SETTLED. DESIGN TO IT.

OWNER DECISIONS (new)
  D1. ONLY A SUPER ADMIN ASSIGNS ROLES. A Platform Administrator holds view on Access control and
      nothing else there: remove its assign grant. Everywhere the copy says "a Super Admin, or
      anyone who can assign roles", it says "a Super Admin". The deny screen and Access control agree.
  D2. ONLY SALES MANAGER AND SALES EXECUTIVE OWN LEADS and appear on the Leads Team tab. Admins can
      still open and edit any lead, but are never offered as an owner and never counted as a rep.
  D3. A PASSWORD RESET ENDS EVERY SESSION WHEN THE LINK IS SENT. Set your password (reset) no longer
      says choosing a password ends sessions; it says the link was sent at a Super Admin's request and
      any open sessions have already ended. Setting the password ends nothing more.

A. SIGN-IN AND SET YOUR PASSWORD
  1. Dark mode on both pages: a theme prop (Light, Dark) like the other artboards, and each page
     follows the saved admin theme, setting data-theme the same way.
  2. The "no current role" and "deactivated" screens name the person actually concerned. When the
     shell sends someone there, it passes who they are with the redirect; never fall back to the
     default persona.
  3. Missing states. Change your password: current password wrong; could not save (retry).
     Set your password: network or service unavailable (retry); add "saving" to its state prop.
  4. Copy. Remove "Nothing was sent." (the app cannot know). "Sign-in is paused for this account"
     becomes "Sign-in is paused for a while" (do not confirm that an account exists).
  5. In the prototype, an email that is not on the staff list shows the wrong email or password
     state. It must not sign in as the persona.

B. ACCESS CONTROL
  6. A revoked invite leaves the staff list and the pending list. The audit log keeps "revoked the
     invite for". It does not become a Deactivated record.
  7. Make the two hidden refusals previewable: "the last Super Admin cannot be removed or demoted"
     and "this email already belongs to a QR setu account". Use a preview prop or seeded data, not
     new UI.
  8. Extend and End now on every time-bound assignment (Super Admin only, the in-app date picker for
     the new end date, an audit row each). The Overview's "Extend it or let it lapse" then has a
     place to act.
  9. Changing someone's role, or ending an assignment, so that they lose their sales role while
     they own open leads asks for the new owner of those leads in the same flow, as deactivation
     already does. A time-bound sales role that simply reaches its end date puts its open leads
     in the unassigned queue, and Leads says why.
  10. desk-records.js ACCESS_REQUESTS still holds the enterprise-era rows (an org scope, External
      Partner, and Meera Nair's elevation to a role she now holds). Approvals are reserved in this
      release, so remove them; nothing in attention() or a reserved tile reads that list.
  11. The staff record in Users links to that person in Access control, and Access control opens
      them from the link (for example ?staff=<id>).
  12. A deactivated staff member shows as "Deactivated" in Users, never "Deleted by the user".
  13. Update the SCREENS.md Access control row to describe the staff-only desk (it still describes
      create and clone roles and an approval queue). Keep RBAC_v1.dc.html as it is.

C. LEADS AND ROLES
  14. Auto-assignment is recorded as "Assignment rules", never as a merchant persona (today it
      writes "Vedaa Lahade"). Lead owners are read live from staff-core, not computed once at load.
  15. crm permissions gate real controls: "Add a lead" needs crm.create, Import needs crm.import,
      and an Export control on the lead list needs crm.export (every export writes an audit row).
      Deleting a lead is reserved in this release: a lead is closed as Lost, never deleted. Show
      crm.delete as reserved in the matrix.
  16. Stage ids everywhere. Records store the stage id, and every comparison (Won, Lost, terminal,
      stalled, the funnel, ops-signals) uses the id. Labels are for display only.
  17. Industry options come from ONE list, the platform's fourteen industries, used by Users and
      Leads alike (replace the list in users-core.js):
        festival_stall Festival / Seasonal Vendor · dairy Dairy · tiffin Tiffin / Home Food Service
        kirana Kirana / Grocery Store · boutique Boutique / Apparel · sweet_shop Sweet Shop / Bakery
        salon Salon / Beauty Professional · yoga_fitness Yoga / Fitness Trainer · tutor Academic Tutor
        electrician_plumber Electrician, Plumber, Carpenter · real_estate Real Estate Agent
        car_sales Car / Bike Sales Agent · photographer Photographer · direct_seller Direct Seller / Distributor
  18. CRM policies, read only: a panel in Leads listing each Sales & lead operations control from
      controls.js with its current value (first response, follow-up grace, stale after, weekly
      contact cap, quiet period after a refusal, assignment mode, call-list ranking), saying they
      are changed in Mission Control, which is not ready yet.
  19. One masking rule for phone numbers in Users and Leads: never more than the last four digits.
  20. Remove "save any filter as a reusable segment" from Leads (segments are reserved).

D. USERS
  21. REGRESSION: the record's workspaces and the person's role in each are live. Show the value;
      reserve only the link into the Workspaces desk. The same for Setu Cards and Subscription on
      the chain: the fact stays, only the door is reserved.
  22. The Directory's lifecycle column, the "widen the lifecycle" copy, the saved-segment chips and
      "Send to Communications" become the reserved presentation. No toast claims a handoff.
  23. Bulk actions offer only suspend, block and sign out everywhere. Bulk suspend and block ask what
      is held, exactly like the single action (both by default for a solo merchant), with that
      choice's copy. The toast confirms only what ran.
  24. Pulse: "Registered people" counts only people with a QR setu login. Unconverted leads are shown
      separately and read from Leads, so both desks show one number.
  25. The audit seed and the Overview feed hold no rows for actions reserved in this release (plan
      change, view as user, identity verification). Every actor is on the staff roster (there is no
      "Kabir Mehta"). Verbs read as words ("blocked", not "block").
  26. A consumer's timeline shows consumer actions, never "published a card".

E. OVERVIEW
  27. The sign-in health row reads sign-in code delivery on its own (codes delivered in the last 24
      hours), never the Communications desk's channel figure, which stays reserved.
  28. "Active cards" becomes a reserved tile (Mission Control), not dropped.
  29. "Waiting on you" shows no 0 badge, and its heading copy agrees that no approval queue runs in
      this release.
  30. The headline counts are exact: "N more are dated" counts dated items only.
  31. Every reserved note in capabilities.js is a correct sentence (today "... queue land here").

F. COPY EVERYWHERE
  32. No em dash or en dash anywhere visible, including as an empty-value placeholder: write
      "None" or "Not set", or leave the cell empty.
  33. Handbook links use plain desk words: /handbook/overview, /handbook/users, /handbook/leads,
      /handbook/access-control.
  34. _ds tokens/colors.css line 67, inside the dark block, repeats half a comment without its
      opening "/*". Delete that line.

DELIVERABLES: the files above revised in place, SCREENS.md rows updated, and one
line per point (D1 to D3, 1 to 34) saying where it now lives.

After it comes back ​

The same loop as round 1: the owner says it was passed; pull fresh (list_files, then get_file for every changed file); materialise it into the review mirror (node admin-materialise.mjs, admin-graph.mjs, admin-verify.mjs, admin-review-check.mjs); and give a verdict per point: resolved · still open · new gap. Anything not resolved opens round 3. Once approved: the parity contracts (QRS-1420), the design review pages, then increment 1.

Cross-references ​