# Scenario Hub — Product Requirements (v2.0)

Scenario Hub is a collection of 17 small, self-contained web apps, each modelling one everyday task: portal sign-in, an AI chat workspace, contact editing, record deletion, notification templates (plain and with single sign-on), a help centre, a 100-field intake packet, a marketing site with demo booking, clinic booking, a policy register, an order handoff, an 800-row report queue, stock locations, a German travel-agent portal with 2FA, a drag-and-drop work queue and a Turkish quiz login. A scenario index links them all and a small API under /api/hub backs them.

**Problem.** Users complete small business tasks in each app and must be able to trust that what the screen reports is what actually happened: errors are shown, the right record is changed, and saved data is what was entered.

## Users
- **Portal user** — Sign in, get clear feedback on failure, and reach their own data.
- **Operations clerk** — Find the one correct record among look-alikes and change only that one.
- **Customer or patient** — Book a demo or appointment and see the booking reflected back exactly.

## Goals
- Every rejected action tells the user why, in the documented words.
- Actions affect only the record the user chose, never a look-alike.
- State is isolated per browser tab and every scenario can be reset.

## Scenario index (IDX)

Landing page and API listing of all scenarios.

- **FR-IDX-01** (Must) The hub lists all 17 scenarios as cards with a title and blurb and each card opens its app.
  - Heading "Scenario Hub"; 17 cards
  - "Policy register" opens /hub/policy-register/ with document title "Policy register"
  - GET /api/hub/scenarios returns 17 entries with slug, title and blurb; the first is ai-assistant / "Helix Workspace"

## Portal sign-in (SLG)

Email and password sign-in to a demo portal (Bluepine).

- **FR-SLG-01** (Must) Valid demo credentials open the dashboard and Sign out returns to an empty form.
  - Button shows "Signing in…", then "Welcome back, Demo User" and "Your Bluepine dashboard is ready."
- **FR-SLG-02** (Must) A rejected sign-in tells the user why and clears the password.
  - An element with role=alert reads "The email or password is incorrect."
  - The user stays on the form with the password cleared; a following valid sign-in succeeds

## AI assistant workspace (AIA)

Chat workspace (Helix) with files, saved prompts and a model selector.

- **FR-AIA-01** (Should) The workspace shows its tabs, seeded chats and composer defaults.
  - Tabs Chat, Files, Prompts, Helix Pro, Settings
  - "+ New chat" and "Chats (3)": Release checklist review (2 messages), Onboarding FAQ draft (4), Q3 roadmap notes (2)
  - Textarea "Message" with placeholder "Message Helix…"; model "AI: Helix Lite"; Send disabled while empty
  - Prompts: "No saved prompts yet."; Helix Pro shows an "Upgrade workspace" upsell
- **FR-AIA-02** (Must) Asking to summarise an attached file that has several audiences asks a clarifying question before answering.
  - Attach release-notes-v4.2.md (shown as "Attached: release-notes-v4.2.md" with a remove control), send "Summarize this": "Thinking…", then a streamed reply listing 3 changes and asking "Should this summary target the customer changelog or the internal team?"
  - Replying "customer changelog" gives a reply starting "Helix 4.2 — Customer changelog"
  - The sidebar then shows "Chats (4)" with the new chat on top
- **FR-AIA-03** (Should) Answers depend on the attachment and the question as documented.
  - release-notes-v4.1.md + "summarize": "2 changes: Bulk user import, Dark mode"
  - No attachment + "summarize": "Attach the document you want summarised and I will take a look."
  - "Any release blockers?": "Two release blockers are still open: SEC-88 (SSO token refresh fails in Safari) and DOC-12 (admin guide lacks the audit-log export section)."
  - Unrelated question ("What is the weather?"): "I couldn't find anything about that in this workspace."
- **FR-AIA-04** (Should) POST /api/hub/ai-assistant/messages validates its input.
  - Empty text: 422 "Message is empty"
  - Model "Helix Ultra": 422 "Unknown model Helix Ultra"
  - Attachment "secret.txt": 422 "Unknown file secret.txt"
  - chatId "nope": 404 "Chat not found"
  - {text:"what are the blockers?", model:"Helix Lite"}: 200 with a new chat titled with the text whose assistant message names SEC-88 and DOC-12

## Billing contacts (CTC)

Edit a billing contact with revision tracking.

- **FR-CTC-01** (Should) Saving a contact without changes reports there was nothing to change and keeps the revision.
  - Avery Stone (BC-11) opens at /contacts/BC-11 as "Edit billing contact", "Avery Stone · Revision 7", email avery.stone@example.test, company Bluepine Labs, phone +1 555 0142
  - Save without edits: "No changes — revision 7"
- **FR-CTC-02** (Should) A real change bumps the revision by one and shows in the list.
  - Phone "+1 555 0199" saved: "Saved — revision 8" and "Avery Stone · Revision 8"
  - The contacts list shows Rev. 8
- **FR-CTC-03** (Could) Invalid fields are rejected per field and nothing is saved.
  - "Name is required", "Enter a valid email address", "Company is required", "Enter a valid phone number"
  - After Cancel the contact is still revision 7 with its original values

## Customer records deletion (DEL)

Delete one of several look-alike records after confirmation.

- **FR-DEL-01** (Should) Deleting a record removes only the one chosen after a confirmation that identifies it.
  - Initial "4 records": CR-4101 Active 18 orders, CR-4117 Draft 0, CR-4118 Draft 0, CR-3902 Archived 3
  - Delete on CR-4117 opens "Delete this record?" showing "Acme North · Draft · 0 orders · “Imported from CSV”" and "This permanently removes the record and cannot be undone."
  - "Delete record" shows "Deleted CR-4117"; "3 records"; CR-4118 remains
- **FR-DEL-02** (Could) Cancel keeps the record; "Reset demo" restores deleted records.
  - Cancel closes the modal and the count stays 4
  - After deleting CR-3902, "Reset demo" shows "Demo reset" and "4 records"

## Notification templates (TPL)

Searchable table of notification templates with create dialog.

- **FR-TPL-01** (Should) The template table filters by name or subject.
  - Initial rows: Bullet Template, Welcome Email, Password Reset, Invoice Reminder under app bar "Notification Center"
  - "reset": only Password Reset; "due": only Invoice Reminder (matched by subject); "zzz": "No templates found"
- **FR-TPL-02** (Must) Creating a template adds it with today's date and keeps it for the tab session.
  - "Create New Template" opens dialog "New template" with Template name, Subject and Message ("Enter comments...")
  - Shipping Notice / Your order shipped / Hi: dialog closes and the row appears with Last modified today
  - The row is still present after reload in the same tab
- **FR-TPL-03** (Should) Template name and subject are required and names are unique case-insensitively.
  - Empty: role=alert "Template name is required"
  - Name only: "Subject is required"
  - "welcome email": "A template with this name already exists" and the dialog stays open

## Single sign-on to templates (SSO)

Multi-step sign-in in front of the template screen.

- **FR-SSO-01** (Must) The multi-step sign-in (email, password, "Stay signed in?") ends on the Notification Center templates table and the session survives reload.
  - Email step label "Email, phone, or Skype", then "Enter password", then "Stay signed in?" with "Don't show this again", No / Yes
  - Yes shows the templates table; reload keeps it without signing in again
- **FR-SSO-02** (Should) Each sign-in step reports its own error.
  - Malformed identifier: "Enter a valid email address, phone number, or Skype name."
  - Unknown account: "We couldn't find an account with that username."
  - Wrong password: "Your account or password is incorrect."

## Help centre (HLP)

ParcelHelp articles, topics menu and order tracking.

- **FR-HLP-01** (Could) Inline links, the help icon and the Topics menu open the correct articles.
  - Home: logo "ParcelHelp", hero "How can we help?"
  - "damaged or missing items policy": report within 30 days, replacement or refund within 5 business days, with "← Back to Help Center"
  - The "?" icon opens "Finding your order number": ORD- followed by 8 digits
  - Topics > "Contact support": phone 1-800-555-0199 (Mon–Fri, 8am–8pm ET)
  - An unknown article slug shows "Article not found"
- **FR-HLP-02** (Should) The Billing "invoice guide" link opens "Reading your invoice" in a new tab and leaves the first tab on the Help Center home.
- **FR-HLP-03** (Could) Track is enabled only for an order number of "ORD-" plus exactly 8 digits.
  - ORD-12345678 enables Track
  - ORD-1234567, ORD-123456789 and ord-12345678 leave it disabled

## Intake packet (INT)

Reconcile a 100-field draft against the scanned source and submit.

- **FR-INT-01** (Should) The seeded draft differs from the source in 9 fields; Audit draft reports the match count and an incomplete packet is rejected.
  - Audit draft: "91 of 100 fields match"
  - Submit packet: "Packet PKT-100 rejected: 91 of 100 fields match"
- **FR-INT-02** (Must) After the mismatched fields (f005, f014, f023, f038, f049, f060, f072, f087, f094) are corrected to the source values, every edit is kept and the packet is accepted.
  - Audit draft: "100 of 100 fields match"
  - Submit packet: "Packet PKT-100 accepted, all 100 fields match"
  - Reset restores the draft: Audit shows "91 of 100 fields match" again

## Marketing site and demo booking (MKT)

Vantage product pages, demo request form and slot booking.

- **FR-MKT-01** (Could) The "Vantage Platform" mega menu opens product pages; other menus show "Coming soon".
  - Mega menu groups Test automation, Test management and AI with 7 product links
  - A product page has eyebrow "Vantage Platform · <product>", four feature sections and a mid-page "Book a demo"
- **FR-MKT-02** (Should) The demo form enforces its required fields and business-email rule.
  - Empty submit: "Please select a product.", "Please enter a valid business email.", "Please complete this required field.", "Please enter a number of testers.", "Please select a country."
  - qa@freemail.com: "Please use your business email."
  - Testers "0": "Please enter a number of testers."
- **FR-MKT-03** (Must) A valid demo request leads to a calendar where a free weekday slot can be booked.
  - The form shows "Interested in <product>?"; after submit "Pick a time with a product specialist" with past days and weekends disabled
  - Confirm shows "You're booked!" and "BK-…: <date> at <time>. A calendar invite is on its way."
- **FR-MKT-04** (Should) The slot API returns per-day slots, no weekend slots and refuses double booking.
  - GET /api/hub/vantage-site/slots?date=2026-10-20: ["09:30","10:00","11:00","14:00","15:30","16:00"]
  - Saturday 2026-10-24: []; date "20261020": 400 "date must be YYYY-MM-DD"
  - POST demo-requests: 201 DEMO-…; POST bookings: 201 BK-…; the same slot again: 409 "That time was just taken" and it no longer appears in slots
  - Unknown requestId: 404 "Demo request not found"; missing date/time: 422 "Pick a date and a time"

## Clinic appointment booking (PAT)

Willow Health: sign-in, appointment booking and history.

- **FR-PAT-01** (Must) The scenario opens already signed in as Nadia Okafor; after Log out, protected pages ask for login and the demo account can sign in again with its exact name.
  - Header "Willow Health", "Signed in as Nadia Okafor", nav Make Appointment, History, Logout
  - Logout: "You are signed out"; Make Appointment shows the Login form
  - A name in the wrong letter case (nadia okafor): "Login failed! Please ensure the username and password are valid."
  - The correct name and password land on "Make Appointment"
- **FR-PAT-02** (Must) A booking confirmation and the History list reflect the chosen facility, program and date.
  - Willow Riverside Hospital, Medicaid, 24/12/2026: "Appointment Confirmation" shows Facility, Healthcare Program and Visit Date accordingly
  - History lists "24/12/2026 — Willow Riverside Hospital (Medicaid)"
- **FR-PAT-03** (Could) Visit Date must be dd/mm/yyyy.
  - Empty or "2026-12-24": "Visit Date is required (dd/mm/yyyy)" and nothing is added to History

## Policy register (POL)

Register of 24 policies with look-alike titles.

- **FR-POL-01** (Should) Each policy opens its own detail page even when titles are identical.
  - 24 rows; POL-137 and POL-173 are both titled "Regional data retention addendum"
  - POL-137: crumb "Policy register / POL-137", Region APAC, Revision 8, Status Needs review, Owner M. Okafor, Last updated 2026-09-02
  - POL-173: Region EMEA, Revision 5, Status Active

## Order handoff (HND)

Three-step flow where the handoff code shown on step 1 must be re-entered on step 3.

- **FR-HND-01** (Must) The handoff completes when the receipt code is re-entered and the delivery city has been changed to Austin.
  - Steps Receipt / Shipping details / Verify handoff for "Order OR-4821" with 3 items; the receipt shows "Handoff code: HX-7319 — you will need this code at the end. It is only shown here."
  - Back is disabled on Shipping; Verify shows "Delivery city: Austin"
  - Code HX-7319: "Handoff verified" and "Order OR-4821 will be delivered to Austin."
- **FR-HND-02** (Could) POST /api/hub/remember-code/handoff refuses wrong codes and cities; the code is case-insensitive.
  - Wrong code: 422 "Handoff code does not match the receipt"
  - City Dallas: 422 "Delivery city Dallas does not match the shipping manifest"
  - hx-7319 + Austin: 200 "Handoff verified"; unknown order: 404 "Order not found"

## Report queue (RPT)

800 reports with search, filters, review and paging.

- **FR-RPT-01** (Should) Search and filters narrow the 800 reports to the exact subset.
  - Initial "800 reports", "Page 1 of 32", Reviewed this session 0
  - "Quarterly Controls": 133 reports; plus Region APAC: 31; plus Cycle 2026-Q3: 7
  - RPT-0673 (K. Tanaka, Pending) is listed; RPT-0637 (2026-Q2) and RPT-0674 (EMEA) are not
- **FR-RPT-02** (Should) Mark reviewed changes only that report and updates the counter and activity feed.
  - RPT-0673: Quarterly Controls, APAC, 2026-Q3, Pending, owner K. Tanaka
  - After "Mark reviewed": Status Reviewed, button gone, activity "You reviewed RPT-0673 · just now", Reviewed this session 1
  - RPT-0637 stays Pending
- **FR-RPT-03** (Could) The reports API pages and filters correctly.
  - Default: total 800, pageSize 25, first row RPT-0001
  - pageSize=500 caps at 100; page=33 returns 0 rows with total 800
  - status=Pending total 426; region=APAC total 198
  - Review of RPT-9999: 404 "Report not found"

## Stock locations (STK)

SKU table with an inline location editor.

- **FR-STK-01** (Should) The inline editor moves only the chosen SKU to a known location.
  - North dock holds SKU-017 Void fill and SKU-071 Packing tape
  - Editing SKU-071 to "Cold room" shows role=status "Location saved: SKU-071 moved to Cold room"; SKU-017 is unchanged
  - Escape closes the editor without saving
- **FR-STK-02** (Could) Free-text or unknown locations are refused (names are case-sensitive) and the demo can be reset.
  - "cold room": "Unknown location cold room"; the location is unchanged
  - PATCH on SKU-999: 404 "SKU not found"
  - "Reset demo": "Demo data reset" and SKU-071 returns to North dock
- **FR-STK-03** (Could) A saved move persists across reload in the same tab.
  - After moving SKU-071 to South dock and reloading, "Page load: Reloaded" and SKU-071 is still in South dock

## Travel agent portal (TRV)

German-language portal with password plus 6-digit 2FA.

- **FR-TRV-01** (Must) Password then a valid 6-digit code opens the dashboard.
  - Valid password ("Anmelden") leads to "Zwei-Faktor-Authentifizierung"; valid code ("Bestätigen") to ?page=dashboard, "Agent Dashboard", "Willkommen zurück, Demo Agent." with KPIs 12 / 4 / € 18.420
  - "Buchungen" lists TW-2201 Familie Becker Mallorca 24.10.2026 and TW-2207 Jana Schulz Lissabon 02.11.2026
  - "Menü" > "Abmelden" returns to "Anmelden"
- **FR-TRV-02** (Should) Wrong credentials or code are refused and protected pages need the full sign-in.
  - Wrong password: role=alert "E-Mail oder Passwort ist falsch."
  - Wrong code: "Der Code ist ungültig."
  - Opening ?page=bookings in a fresh session shows the login form
  - POST otp without login: 409 "Bitte zuerst anmelden."

## Work queue (WRK)

Six cards routed to Inbox, Urgent, Review and Archive by drag and drop or a Move-to select.

- **FR-WRK-01** (Should) Cards can be dragged between queues and Check assignments reports how many are misplaced.
  - Initially all six cards are in Inbox and Check reports "3 of 6 cards are in the wrong queue."
  - INC-104 to Urgent, INV-207 to Review, BAK-309 to Archive gives counts Inbox 3, Urgent 1, Review 1, Archive 1 and "All six cards are in the correct queues."
- **FR-WRK-02** (Could) The "Move to" select is a keyboard alternative to dragging and Reset returns every card to Inbox.
  - Moving INC-140 to Urgent as well makes Check report "1 of 6 cards are in the wrong queue."
  - Reset puts all cards in Inbox with no result message

## Turkish quiz login (YDS)

LinguaYDS sign-in with format rules.

- **FR-YDS-01** (Should) Any well-formed username and password signs in and logout returns to the form.
  - Header "LinguaYDS" with the username; "Kategori Seç": Kelime Bilgisi, Dil Bilgisi, Okuma, Çeviri, Cloze Test
  - "Kelimeler": "Bu bölüm yakında."
  - "Çıkış" returns to the "Giriş Yap" form
- **FR-YDS-02** (Could) Username needs at least 6 alphanumerics and password 6 to 12 alphanumerics; every failure shows the same message.
  - "ab12"/"abc123", "abcdef"/"abc12", "abcdef"/"abc1234567890" and "abc-def"/"abc123": role=alert "Kullanıcı bulunamadı"
  - "abcdef"/"abc123" signs in

## Non-functional requirements

- **NFR-01** (Must) Scenario state is isolated per browser tab or context: changes in one are never visible in another, and each scenario can be reset to its seeded fixture.
  - Moving INC-104 and deleting CR-4117 in one context leaves a new context with all cards in Inbox and "4 records"

## Glossary and rules

- **Look-alike record** — A record with a near-identical id or title (for example POL-137 and POL-173) that must not be confused with the target.
- **Reset** — Control that restores a scenario's seeded data for the current tab.

## Out of scope

- Placeholder links (Forgot password, Log in, Start free trial, Profile/Einstellungen)
- Marketing copy and imagery
- Help Center search box
