Appearance
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/.
| Item | Verdict | What is resolved | What is still open (this round) |
|---|---|---|---|
| 1 · Staff sign-in | resolved, 3 defects | A 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 password | resolved, 2 defects | Invite 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 control | resolved, 5 defects | The 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 model | resolved, 4 defects | platform/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 yet | resolved, 6 defects | capabilities.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 live | mostly resolved, 1 regression | Holds 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 points | resolved, 1 defect | A Handbook link in the shell, and "How this desk works" on every desk. | The URLs use internal ids (/crm, /rbac). |
| 8 · Copy and controls | partly | Auditor 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):
- Only a Super Admin assigns roles. A Platform Administrator views Access control and changes nothing.
- Only Sales Manager and Sales Executive own leads and appear on the Team tab.
- 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
- Admin Panel MVP, round 1, the brief this round corrects.
- Account holds, round 1, still to send. Round 1 already produced
prototype/setu-card/HeldPage.dc.html(the neutral public page), so that prompt reviews it rather than asking for it. - Screen coverage mandate.