Qontak | Chatbot & AI | Unified Agent Quality Scorecard — Adj: Bulk-Score Keyboard Shortcuts
Template: ADJUSTMENT PRD v1.2 · Companion to PRD Section Reference v1.5 + Hierarchy v1.0 Note: Adjustment to Phase 2 (AI Auto-Scoring & In-Room Scorecard) of the Unified Agent Quality Scorecard initiative. Adds two keyboard shortcuts to the already-shipped in-room Scorecard panel — no other behavior changes.
HEADER BLOCK
| Field | Value |
|---|---|
| PM | Dimas Fauzi Hidayat |
| PRD Version | 1.0 |
| Status | DRAFT |
| PRD Type | ADJUSTMENT |
| Epic | BOT-4573 |
| Squad | BOT — Bot, AI & Automation |
| RFC Link | N/A — no RFC required (FE-only interaction change, no new API or data contract) |
| Figma Master | N/A — no new UI elements; reuses the existing Pass/Fail icons already shipped in the panel |
| Anchor | Yes — no Confluence ANCHOR page exists for this initiative yet; see the repo-local Unified Agent Quality Scorecard — ANCHOR |
| Labels | epic:qontak-chatbot-ai | module:chatbot-ai | feature:unified-agent-scorecard |
| Last Updated | 2026-07-17 |
Status values:
DRAFT→READY→BUILD→SHIPPEDREADY gate: Epic cannot move to In Progress in Jira without PRD Link + RFC Link populated (RFC is explicitly N/A for this adjustment — see above).
Table of Contents
- HEADER BLOCK
- 1. CONDITIONAL BLOCK: ADJUSTMENT CONTEXT
- 2. One-liner + Problem
- 3. Target Users + Persona Context
- 4. Non-Goals
- 5. Scope Changes
- 6. Constraints
- 7. Feature Changes
- 8. New Features
- 9. System Flow + User Stories + ACs
- 10. Rollout
- 11. Observability
- 12. Success Metrics
- 13. Launch Plan & Stage Gates
- 14. Dependencies
- 15. Key Decisions + Alternatives Rejected
- 16. Open Questions
- PRD CHANGELOG
1. CONDITIONAL BLOCK: ADJUSTMENT CONTEXT
| Field | Detail |
|---|---|
| Parent Anchor PRD | Unified Agent Quality Scorecard — ANCHOR (repo-local only — no Confluence ANCHOR page exists for this initiative; see the initiative README) |
| This adjustment covers | Two new keyboard shortcuts in the in-room Scorecard panel's edit mode (hub-chat ScorecardForm.vue): Ctrl/Cmd+Shift+↑ sets every parameter across every category to Pass (100); Ctrl/Cmd+Shift+↓ sets every parameter to Fail (0), bypassing the per-parameter reason popover. Both write only local component state — nothing is persisted until the reviewer clicks the panel's existing Submit button. |
| Parent PRD still owns | Everything else in Phase 2 — AI Auto-Scoring & In-Room Scorecard: individual per-parameter click-to-score, the reason-popover flow, the AI auto-scored mode + actor selector, the submit/edit/override flow, and every API contract. This adjustment adds an alternate fast-path input method alongside the existing click controls — it does not change what happens on Submit or how a score is computed. |
| Reason for adjustment | QA asked Dimas directly (2026-07-17) for a bulk-scoring shortcut, naming the two exact key combinations they want. Trigger: reviewing a full scorecard one parameter at a time is pure repetitive clicking once a reviewer has already reached an overall Pass/Fail verdict for the conversation — there's no fast path today. |
| Scope boundary | Only ScorecardForm.vue (the parameter table) and its mount context in AgentScorecard.vue. No change to useAgentScorecard.ts, the GET/POST/PATCH agent_scorecards/{roomId} contract, or backend submit.rb validation — the shortcuts produce the exact same score_value writes (0 or 100) a manual click already produces. |
2. One-liner + Problem
One-liner: Let a QA reviewer bulk-set every parameter in the open Scorecard to Pass or Fail with one keyboard shortcut, instead of clicking each parameter individually.
Problem: Scoring a conversation today means clicking Pass or Fail on every parameter in every category one at a time. For a reviewer who has already formed an overall verdict for the conversation, that's pure repetitive clicking with no shortcut path. See Phase 2 for the full panel background.
3. Target Users + Persona Context
Personas inherited from Phase 2 — see Phase 2 §5 for the full persona blocks. Primary: QA Lead / Supervisor.
This adjustment does not introduce or change a persona — it's a scoring-speed improvement for the same QA Lead/Supervisor who already scores conversations in this panel today. (It was requested directly by QA, who is the primary persona.)
4. Non-Goals
- Does not change what happens on Submit, the reason-popover UI, or the AI auto-scored mode — those stay exactly as Phase 2 shipped them.
- Does not add a confirmation dialog before applying the bulk action — it's local-state-only and reversible until Submit (see §15 Key Decisions).
- Does not add a way to bulk-score only one category at a time — the shortcut always applies to every parameter across every category currently on the panel, matching how QA asked for it.
- Does not touch the backend
submit.rbcontract or add a new API — the shortcut writes the samescore_value(0/100) fields a manual click already produces. - Does not force a reason to be captured for parameters bulk-marked Fail — QA can still open any parameter's popover individually afterward to add one (see NEG scenarios in §9.2).
5. Scope Changes
Engineering surfaces this PRD touches (controlled vocab). Kept in sync with the scope_changes frontmatter above.
- Frontend —
hub-chat: new keydown handling scoped tofeatures/inbox/features/main-section/features/room-details/features/agent-scorecard/components/ScorecardForm.vue(or a small composable it calls). No existing shortcut/hotkey infrastructure exists anywhere inhub-chat's inbox feature tree today (confirmed by repo search for keydown/hotkey/shortcut patterns) — this is net-new plumbing for the repo, not an extension of an existing system.
6. Constraints
| Field | Value |
|---|---|
| Platform | Same as parent: Web only — Qontak omnichannel web app |
| Performance | N/A — purely a client-side mutation of already-loaded scorecardData; no network call, no measurable latency |
| Backward compat | Yes — no stored data or API contract changes. Writes the identical score_value shape a manual click already produces (confirmed against the backend contract: submit.rb requires score_value to be exactly 0 or 100) |
| Feature flag | No new flag. Gated exactly like the existing Pass/Fail icons: only active while the panel is in edit mode (isEdit === true) and the reviewer holds inbox_scorecard_manage (Usman permission) — confirmed in AgentScorecard.vue |
| Rollout note | None — no schema, migration, or backend change |
7. Feature Changes
Change ID: CHG-001 — Bulk-Pass shortcut
| Field | Detail |
|---|---|
| Change Type | Modified component — new keyboard interaction added |
| Page | /inbox — conversation right panel → Scorecard tab (same surface as Phase 2 CHG-003) |
| Page Intent | A QA reviewer who has already judged a conversation an overall Pass wants to set every parameter without clicking each one |
| Before | Each parameter's Pass icon must be clicked individually; N categories × M parameters = N×M clicks |
| After | Pressing Ctrl/Cmd+Shift+↑ while the panel is in edit mode sets every parameter across every category to Pass (100) in one action — identical end-state to clicking every Pass icon |
Change ID: CHG-002 — Bulk-Fail shortcut
| Field | Detail |
|---|---|
| Change Type | Modified component — new keyboard interaction added |
| Page | /inbox — conversation right panel → Scorecard tab |
| Page Intent | A QA reviewer who has already judged a conversation an overall Fail wants to set every parameter without clicking each one or working through each reason popover |
| Before | Each parameter's Fail icon must be clicked individually; parameters with is_bad_rating_reason: true additionally require opening a popover and clicking Submit inside it before the Fail registers |
| After | Pressing Ctrl/Cmd+Shift+↓ sets every parameter across every category to Fail (0) in one action, without opening the reason popover — reason fields are left as-is (blank if previously unset). This is valid end-to-end: the backend contract treats reasons/bad_reason_description as optional (submit.rb), so a Fail with no reason is already a reachable state today via Submit-without-picking-a-reason inside the popover. The reviewer can still open any individual parameter's popover afterward to add a reason. |
| Element | Before | After |
|---|---|---|
| Bulk Pass | Not possible — click each Pass icon | Ctrl/Cmd+Shift+↑ sets all parameters to 100 |
| Bulk Fail | Not possible — click each Fail icon (+ popover for reason-flagged params) | Ctrl/Cmd+Shift+↓ sets all parameters to 0, reason left blank |
Figma: N/A — behavior/logic change only, no new visual element (reuses the existing Pass/Fail icon states). Confirmed against the qontak-designer prototype's agent-scorecard component: no shortcut affordance exists there either, so this is net-new for design, not just engineering. (If Design later wants a toast/flash confirming the bulk action fired, that's a Could Have — see §16 Open Questions.)
8. New Features
N/A — this adjustment modifies existing behavior only; no new screen or UI element.
9. System Flow + User Stories + ACs
9.1 System Flow
Flow: Bulk-Score via Keyboard Shortcut · Type: User Journey (single-actor decision flow)
- QA reviewer opens a resolved room's Scorecard panel in edit mode.
- Reviewer forms an overall verdict for the conversation (Pass or Fail).
- Reviewer presses
Ctrl/Cmd+Shift+↑(Pass) orCtrl/Cmd+Shift+↓(Fail). - Decision — is the panel in edit mode and does the reviewer hold
inbox_scorecard_manage? No → no-op. Yes → continue. - Decision — is
scorecardDataloaded (categories/parameters present)? No → no-op. Yes → continue. - System sets
score_valueon every parameter in every category to 100 (Pass) or 0 (Fail). Fail does not clear reasons on parameters that already had one set; Pass clears any stale reason state (mirrors today's individual-click behavior). - Panel re-renders — every parameter shows the new Pass/Fail icon state and each category's computed score updates.
- Reviewer optionally opens any individual parameter's popover to add/edit a reason, then clicks the existing Submit button (unchanged flow) to persist.
- Failure branch — none at this step: it is a synchronous client-side state write with no network call, so it cannot fail. Any failure happens later, at the existing (unchanged) Submit step.
📊 System Flow — Bulk-Score Shortcut
graph TD
A[Reviewer in Scorecard panel, edit mode] --> B{Ctrl/Cmd+Shift+Up or Down pressed?}
B -- No --> A
B -- Yes --> C{Edit mode AND inbox_scorecard_manage AND data loaded?}
C -- No --> A
C -- Yes, Up --> D[Set every parameter score_value = 100, clear stale reasons]
C -- Yes, Down --> E[Set every parameter score_value = 0, existing reasons untouched, no popover opened]
D --> F[Panel re-renders, category scores recompute]
E --> F
F --> G[Reviewer optionally edits a reason, then clicks existing Submit]
9.2 User Stories
[SCOREADJ-S01] — Bulk-Pass all parameters via Ctrl/Cmd+Shift+↑
| User Story | As a QA Lead / Supervisor, I want to set every parameter in the open Scorecard to Pass with one keyboard shortcut, so that I can score a conversation I've already judged an overall pass without clicking every parameter individually. |
| Before State | Every parameter must be clicked individually to mark Pass; no bulk action exists. |
| After Delta | Pressing Ctrl/Cmd+Shift+↑ while the panel is in edit mode sets score_value = 100 on every parameter across every category in one action. |
| Importance | Must Have — this is exactly what QA asked for; without it the adjustment delivers nothing. |
| Mockup / Technical Notes | Figma: N/A — no new visual element. Data Fields: none new — writes the existing score_value field on ScorecardParameter.Technical Notes: implemented as a keydown listener scoped to ScorecardForm's mounted lifecycle (no existing shortcut infra in hub-chat — confirmed by repo search). Should clear bad_reason_description / deactivate reasons the same way the existing individual Pass click does (updateParameterValue(index, paramIndex, true)), so a parameter previously marked Fail-with-reason and then bulk-Passed doesn't retain stale reason text. |
| Acceptance Criteria | — Happy Path — • AC-1: Given the panel is in edit mode with scorecard data loaded, when the reviewer presses Ctrl/Cmd+Shift+↑, then every parameter in every category shows score_value = 100 and each category's score recomputes to reflect all-Pass.• AC-2: Given a parameter was previously marked Fail with a reason selected, when the reviewer presses Ctrl/Cmd+Shift+↑, then that parameter's score_value becomes 100 and its reason state is cleared (same as an individual Pass click today).• AC-3: Given the reviewer has not yet clicked Submit, when they press Ctrl/Cmd+Shift+↑ and then individually click one parameter's Fail icon, then only that one parameter reverts to Fail — the bulk action is a one-time state set, not a locked mode.— Edge — • AC-4: Given the Scorecard has multiple categories with different parameter counts, when Ctrl/Cmd+Shift+↑ is pressed, then all parameters in all categories are set, not just the first/focused category.• AC-5: Given scorecardData has not finished loading yet (GET still in flight), when Ctrl/Cmd+Shift+↑ is pressed, then the shortcut no-ops — no error, no partial write.— Error / Unhappy Path — • ERR-1: N/A — purely a client-side state mutation on already-loaded data; there is no network call or failure mode for this action itself (failures only occur later, at the existing, unchanged Submit step). — Permission Model — • CAN: QA Lead/Supervisor with inbox_scorecard_manage, while the panel is in edit mode (same gate as the existing Pass/Fail icons).• CANNOT: view-only ( inbox_scorecard_view) users, end CS agents, or anyone viewing a submitted/non-edit scorecard.• Unauthorized: shortcut no-ops silently — matches today's behavior where the Pass/Fail icons simply aren't rendered outside edit mode. — UI States — • Loading: if scorecardData isn't loaded yet, shortcut no-ops (AC-5).• Empty: N/A — a resolved room always has categories/parameters once loaded (Phase 2 behavior unchanged). • Error: N/A (ERR-1). • Success: every parameter's icon flips to the filled "Pass" state; category scores update. — Negative Scenarios — (from Non-Goals) • NEG-1: Given the panel is NOT in edit mode (already submitted/reviewed), when Ctrl/Cmd+Shift+↑ is pressed, then nothing happens — view-only scorecards are never mutated by the shortcut.• NEG-2: Given the reviewer is typing in the Remarks textarea, when they press Ctrl/Cmd+Shift+↑, then the shortcut still fires (this key combination is not used for text editing/selection) — confirm no collision with browser/OS bindings during implementation. |
Dependencies: None — reuses Phase 2's already-shipped panel; no dependency on Phase 1 or AI-scoring work.
[SCOREADJ-S02] — Bulk-Fail all parameters via Ctrl/Cmd+Shift+↓
| User Story | As a QA Lead / Supervisor, I want to set every parameter in the open Scorecard to Fail with one keyboard shortcut, so that I can score a conversation I've already judged an overall fail without clicking every parameter individually or working through each reason popover. |
| Before State | Every parameter must be clicked individually to mark Fail; parameters with is_bad_rating_reason: true additionally require opening a popover and picking a reason (or at minimum clicking Submit inside it) before the Fail registers. |
| After Delta | Pressing Ctrl/Cmd+Shift+↓ while the panel is in edit mode sets score_value = 0 on every parameter across every category in one action, without opening any reason popover. |
| Importance | Must Have — the mirror of SCOREADJ-S01 and equally named by QA; a bulk-fail shortcut that still forces a popover per reason-flagged parameter would not deliver the speed QA asked for. |
| Mockup / Technical Notes | Figma: N/A — no new visual element. Data Fields: none new. Technical Notes: bypasses the MpPopover / reason-selection UI in ScorecardForm.vue entirely — calls the equivalent of updateParameterValue(index, paramIndex, false) directly for every parameter. Confirmed against the backend contract (chatbot repo submit.rb): bad_reason_description and reasons are optional fields, so submitting a Fail with no reason is already a valid, reachable state today (a reviewer can already click Submit inside the popover without picking a reason) — this shortcut does not create a new backend state, just a faster path to one that already exists. |
| Acceptance Criteria | — Happy Path — • AC-1: Given the panel is in edit mode with scorecard data loaded, when the reviewer presses Ctrl/Cmd+Shift+↓, then every parameter in every category shows score_value = 0 and each category's score recomputes to reflect all-Fail.• AC-2: Given a parameter has is_bad_rating_reason: true, when the reviewer presses Ctrl/Cmd+Shift+↓, then that parameter is set to Fail WITHOUT opening its reason popover, and bad_reason_description/reasons are left as-is (blank if previously unset).• AC-3: Given a parameter was already Fail with a reason filled in before the shortcut was pressed, when Ctrl/Cmd+Shift+↓ is pressed, then the existing reason is left untouched — the shortcut only writes score_value, it does not clear reason fields on parameters already in the Fail state.— Edge — • AC-4: Given the reviewer wants a reason recorded for a specific parameter after bulk-failing, when they open that parameter's popover and pick a reason, then it saves normally (unchanged existing flow) — the bulk action does not lock them out of the per-parameter reason UI. • AC-5: Given scorecardData has not finished loading yet, when Ctrl/Cmd+Shift+↓ is pressed, then the shortcut no-ops.— Error / Unhappy Path — • ERR-1: N/A — same as SCOREADJ-S01; no network call at the point the shortcut fires. — Permission Model — • CAN: QA Lead/Supervisor with inbox_scorecard_manage, panel in edit mode.• CANNOT: view-only users, end CS agents. • Unauthorized: shortcut no-ops silently. — UI States — • Loading: no-op if data isn't loaded (AC-5). • Empty: N/A. • Error: N/A. • Success: every parameter's icon flips to the filled "Fail" state; category scores update. — Negative Scenarios — • NEG-1: Given the panel is NOT in edit mode, when Ctrl/Cmd+Shift+↓ is pressed, then nothing happens.• NEG-2: Given a parameter requires a reason ( is_bad_rating_reason: true) and the reviewer bulk-Fails then clicks Submit without ever opening that parameter's popover, when Submit runs, then it still succeeds with a blank reason — this matches today's existing (non-shortcut) popover-Submit-without-a-reason path, so the shortcut introduces no new validation gap. (Flagged explicitly in §16 Open Questions in case QA wants this tightened.) |
Dependencies: None.
10. Rollout
| Field | Detail |
|---|---|
| Rollout type | Standard staged — low risk, no data/schema change |
| Feature flag | N/A — no new flag needed for this adjustment |
| Rollout | Stage 1 → Internal: QA team (the requesters) validates both shortcuts on a handful of resolved rooms Stage 2 → All accounts with existing inbox_scorecard_manage access (automatic — same gate as today's panel) |
| Backward compat | Yes — existing data unaffected |
| Migration | None |
11. Observability
Adds one new event on top of what the panel already tracks ([CHATBOT] - Agent Scoring, [CHATBOT] - Scoring with Bad Rating, [CHATBOT] - Scorecard_Submit — see ScorecardForm.vue / AgentScorecard.vue):
New or Modified Events:
| Event Name | Trigger | Properties | Change from parent |
|---|---|---|---|
[CHATBOT] - Bulk Score Shortcut Used | Reviewer presses Ctrl/Cmd+Shift+↑ or ↓ in the Scorecard panel | Role, Email, Company ID, Company Name, Room ID, Direction (pass/fail), parameter count affected | New — measures shortcut adoption |
12. Success Metrics
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| Bulk-shortcut adoption | % of Scorecard submissions preceded by at least one Bulk Score Shortcut Used event | 0% — shortcut doesn't exist yet | ≥20% of submissions within 30 days of rollout (directional — QA specifically requested this, so early adoption should be high among the team that asked for it) |
13. Launch Plan & Stage Gates
| Stage | Audience | Duration | Success Gate | Owner |
|---|---|---|---|---|
| Internal QA | QA team (the requesters) | 1 week | Both shortcuts work correctly across categories/parameters, no state-corruption reports, 0 P0/P1 | PM + QA |
| GA | All accounts with inbox_scorecard_manage | Ongoing (direct deploy, no flag) | No regression reports on the existing click-to-score / reason / submit flow for 1 week post-GA | PM |
14. Dependencies
No new dependencies introduced by this adjustment. Existing dependencies remain governed by Phase 2.
15. Key Decisions + Alternatives Rejected
8a — Decisions Made
| Date | Decision | Rationale |
|---|---|---|
| 2026-07-17 | Bulk-Fail bypasses the per-parameter reason popover entirely | Backend contract confirms reasons/bad_reason_description are optional (submit.rb) — forcing the popover per parameter in bulk mode would defeat the speed QA explicitly asked for; the manual per-parameter reason path stays available afterward |
| 2026-07-17 | Shortcut always applies to every parameter across every category on the panel — no per-category scoping | Matches QA's literal request ("score all parameter"); a full scorecard review is normally done in one sitting per room, so category-scoping would add a decision step without clear benefit |
| 2026-07-17 | No confirmation dialog before applying the bulk action | Purely local state until the existing Submit button is clicked — reversible by re-clicking individual icons or the opposite shortcut; a confirm dialog would defeat the point of a power-user shortcut |
| 2026-07-17 | Reuses the exact score_value semantics (0/100) a manual click produces — no new field, no new endpoint | Keeps the backend contract, submit validation, and the AI-scoring mode (Phase 2) completely untouched; lowest-risk implementation |
8b — Alternatives Rejected
| Alternative | Why Rejected | Date |
|---|---|---|
| Force the reason popover to open (sequentially) for every reason-flagged parameter during bulk-Fail | Defeats the purpose of a one-keystroke bulk action; QA asked for speed, not a guided walkthrough | 2026-07-17 |
| Scope the shortcut to only the category currently in view/focus | QA's request was "all parameter," and most reviewers score a whole room in one pass — per-category scoping adds friction for no clear win | 2026-07-17 |
| Add a confirmation modal before applying | Unnecessary friction for a reversible, pre-submit, local-only action | 2026-07-17 |
16. Open Questions
| # | Type | Question | Owner | Deadline |
|---|---|---|---|---|
| 1 | Assumption | Bulk-Fail leaves the reason blank for is_bad_rating_reason parameters rather than forcing or blocking on one — confirmed valid against the backend contract, and implicitly accepted when this PRD was requested (2026-07-17). Flagging so QA can object before build if they actually want reasons enforced. | Dimas + QA | 2026-07-24 |
| 2 | Open Question | Should there be a lightweight visual confirmation (toast/flash) when the shortcut fires, given there's no confirmation dialog? Nice-to-have, not blocking. | Design | 2026-07-24 |
| 3 | Open Question | Confirm Cmd+Shift+Arrow (not just Ctrl+Shift+Arrow) is the right binding on macOS — QA's original ask named "Ctrl" specifically; verify this isn't intentional (e.g. a Windows-only QA team) before defaulting to cross-platform support. | QA | 2026-07-24 |
| 4 | Risk | No automated test exists yet for this interaction. Mitigation: hub-chat's AGENTS.md requires a co-located __tests__ spec for any new composable/keydown handler as a Definition-of-Done item — enforced at build/PR time, not a gap today. | Engineering (hub-chat) | Before merge |
PRD CHANGELOG
| Version | Date | By | Section | Type | Summary |
|---|---|---|---|---|---|
| 1.0 | 2026-07-17 | Claude | All | CREATED | ADJUSTMENT PRD created for QA's bulk-score keyboard shortcuts (Ctrl/Cmd+Shift+↑ = Pass all, Ctrl/Cmd+Shift+↓ = Fail all) in the Phase 2 in-room Scorecard panel. |