{"ns":"hub","title":"Scenario Hub","version":"2.0","summary":"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.","personas":[{"name":"Portal user","need":"Sign in, get clear feedback on failure, and reach their own data."},{"name":"Operations clerk","need":"Find the one correct record among look-alikes and change only that one."},{"name":"Customer or patient","need":"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."],"features":[{"id":"IDX","title":"Scenario index","summary":"Landing page and API listing of all scenarios.","reqs":[{"id":"FR-IDX-01","weight":"Must","text":"The hub lists all 17 scenarios as cards with a title and blurb and each card opens its app.","accept":["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\""]}]},{"id":"SLG","title":"Portal sign-in","summary":"Email and password sign-in to a demo portal (Bluepine).","reqs":[{"id":"FR-SLG-01","weight":"Must","text":"Valid demo credentials open the dashboard and Sign out returns to an empty form.","accept":["Button shows \"Signing in…\", then \"Welcome back, Demo User\" and \"Your Bluepine dashboard is ready.\""]},{"id":"FR-SLG-02","weight":"Must","text":"A rejected sign-in tells the user why and clears the password.","accept":["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"]}]},{"id":"AIA","title":"AI assistant workspace","summary":"Chat workspace (Helix) with files, saved prompts and a model selector.","reqs":[{"id":"FR-AIA-01","weight":"Should","text":"The workspace shows its tabs, seeded chats and composer defaults.","accept":["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"]},{"id":"FR-AIA-02","weight":"Must","text":"Asking to summarise an attached file that has several audiences asks a clarifying question before answering.","accept":["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"]},{"id":"FR-AIA-03","weight":"Should","text":"Answers depend on the attachment and the question as documented.","accept":["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.\""]},{"id":"FR-AIA-04","weight":"Should","text":"POST /api/hub/ai-assistant/messages validates its input.","accept":["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"]}]},{"id":"CTC","title":"Billing contacts","summary":"Edit a billing contact with revision tracking.","reqs":[{"id":"FR-CTC-01","weight":"Should","text":"Saving a contact without changes reports there was nothing to change and keeps the revision.","accept":["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\""]},{"id":"FR-CTC-02","weight":"Should","text":"A real change bumps the revision by one and shows in the list.","accept":["Phone \"+1 555 0199\" saved: \"Saved — revision 8\" and \"Avery Stone · Revision 8\"","The contacts list shows Rev. 8"]},{"id":"FR-CTC-03","weight":"Could","text":"Invalid fields are rejected per field and nothing is saved.","accept":["\"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"]}]},{"id":"DEL","title":"Customer records deletion","summary":"Delete one of several look-alike records after confirmation.","reqs":[{"id":"FR-DEL-01","weight":"Should","text":"Deleting a record removes only the one chosen after a confirmation that identifies it.","accept":["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"]},{"id":"FR-DEL-02","weight":"Could","text":"Cancel keeps the record; \"Reset demo\" restores deleted records.","accept":["Cancel closes the modal and the count stays 4","After deleting CR-3902, \"Reset demo\" shows \"Demo reset\" and \"4 records\""]}]},{"id":"TPL","title":"Notification templates","summary":"Searchable table of notification templates with create dialog.","reqs":[{"id":"FR-TPL-01","weight":"Should","text":"The template table filters by name or subject.","accept":["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\""]},{"id":"FR-TPL-02","weight":"Must","text":"Creating a template adds it with today's date and keeps it for the tab session.","accept":["\"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"]},{"id":"FR-TPL-03","weight":"Should","text":"Template name and subject are required and names are unique case-insensitively.","accept":["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"]}]},{"id":"SSO","title":"Single sign-on to templates","summary":"Multi-step sign-in in front of the template screen.","reqs":[{"id":"FR-SSO-01","weight":"Must","text":"The multi-step sign-in (email, password, \"Stay signed in?\") ends on the Notification Center templates table and the session survives reload.","accept":["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"]},{"id":"FR-SSO-02","weight":"Should","text":"Each sign-in step reports its own error.","accept":["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.\""]}]},{"id":"HLP","title":"Help centre","summary":"ParcelHelp articles, topics menu and order tracking.","reqs":[{"id":"FR-HLP-01","weight":"Could","text":"Inline links, the help icon and the Topics menu open the correct articles.","accept":["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\""]},{"id":"FR-HLP-02","weight":"Should","text":"The Billing \"invoice guide\" link opens \"Reading your invoice\" in a new tab and leaves the first tab on the Help Center home."},{"id":"FR-HLP-03","weight":"Could","text":"Track is enabled only for an order number of \"ORD-\" plus exactly 8 digits.","accept":["ORD-12345678 enables Track","ORD-1234567, ORD-123456789 and ord-12345678 leave it disabled"]}]},{"id":"INT","title":"Intake packet","summary":"Reconcile a 100-field draft against the scanned source and submit.","reqs":[{"id":"FR-INT-01","weight":"Should","text":"The seeded draft differs from the source in 9 fields; Audit draft reports the match count and an incomplete packet is rejected.","accept":["Audit draft: \"91 of 100 fields match\"","Submit packet: \"Packet PKT-100 rejected: 91 of 100 fields match\""]},{"id":"FR-INT-02","weight":"Must","text":"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.","accept":["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"]}]},{"id":"MKT","title":"Marketing site and demo booking","summary":"Vantage product pages, demo request form and slot booking.","reqs":[{"id":"FR-MKT-01","weight":"Could","text":"The \"Vantage Platform\" mega menu opens product pages; other menus show \"Coming soon\".","accept":["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\""]},{"id":"FR-MKT-02","weight":"Should","text":"The demo form enforces its required fields and business-email rule.","accept":["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.\""]},{"id":"FR-MKT-03","weight":"Must","text":"A valid demo request leads to a calendar where a free weekday slot can be booked.","accept":["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.\""]},{"id":"FR-MKT-04","weight":"Should","text":"The slot API returns per-day slots, no weekend slots and refuses double booking.","accept":["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\""]}]},{"id":"PAT","title":"Clinic appointment booking","summary":"Willow Health: sign-in, appointment booking and history.","reqs":[{"id":"FR-PAT-01","weight":"Must","text":"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.","accept":["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\""]},{"id":"FR-PAT-02","weight":"Must","text":"A booking confirmation and the History list reflect the chosen facility, program and date.","accept":["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)\""]},{"id":"FR-PAT-03","weight":"Could","text":"Visit Date must be dd/mm/yyyy.","accept":["Empty or \"2026-12-24\": \"Visit Date is required (dd/mm/yyyy)\" and nothing is added to History"]}]},{"id":"POL","title":"Policy register","summary":"Register of 24 policies with look-alike titles.","reqs":[{"id":"FR-POL-01","weight":"Should","text":"Each policy opens its own detail page even when titles are identical.","accept":["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"]}]},{"id":"HND","title":"Order handoff","summary":"Three-step flow where the handoff code shown on step 1 must be re-entered on step 3.","reqs":[{"id":"FR-HND-01","weight":"Must","text":"The handoff completes when the receipt code is re-entered and the delivery city has been changed to Austin.","accept":["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.\""]},{"id":"FR-HND-02","weight":"Could","text":"POST /api/hub/remember-code/handoff refuses wrong codes and cities; the code is case-insensitive.","accept":["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\""]}]},{"id":"RPT","title":"Report queue","summary":"800 reports with search, filters, review and paging.","reqs":[{"id":"FR-RPT-01","weight":"Should","text":"Search and filters narrow the 800 reports to the exact subset.","accept":["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"]},{"id":"FR-RPT-02","weight":"Should","text":"Mark reviewed changes only that report and updates the counter and activity feed.","accept":["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"]},{"id":"FR-RPT-03","weight":"Could","text":"The reports API pages and filters correctly.","accept":["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\""]}]},{"id":"STK","title":"Stock locations","summary":"SKU table with an inline location editor.","reqs":[{"id":"FR-STK-01","weight":"Should","text":"The inline editor moves only the chosen SKU to a known location.","accept":["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"]},{"id":"FR-STK-02","weight":"Could","text":"Free-text or unknown locations are refused (names are case-sensitive) and the demo can be reset.","accept":["\"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"]},{"id":"FR-STK-03","weight":"Could","text":"A saved move persists across reload in the same tab.","accept":["After moving SKU-071 to South dock and reloading, \"Page load: Reloaded\" and SKU-071 is still in South dock"]}]},{"id":"TRV","title":"Travel agent portal","summary":"German-language portal with password plus 6-digit 2FA.","reqs":[{"id":"FR-TRV-01","weight":"Must","text":"Password then a valid 6-digit code opens the dashboard.","accept":["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\""]},{"id":"FR-TRV-02","weight":"Should","text":"Wrong credentials or code are refused and protected pages need the full sign-in.","accept":["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.\""]}]},{"id":"WRK","title":"Work queue","summary":"Six cards routed to Inbox, Urgent, Review and Archive by drag and drop or a Move-to select.","reqs":[{"id":"FR-WRK-01","weight":"Should","text":"Cards can be dragged between queues and Check assignments reports how many are misplaced.","accept":["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.\""]},{"id":"FR-WRK-02","weight":"Could","text":"The \"Move to\" select is a keyboard alternative to dragging and Reset returns every card to Inbox.","accept":["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"]}]},{"id":"YDS","title":"Turkish quiz login","summary":"LinguaYDS sign-in with format rules.","reqs":[{"id":"FR-YDS-01","weight":"Should","text":"Any well-formed username and password signs in and logout returns to the form.","accept":["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"]},{"id":"FR-YDS-02","weight":"Could","text":"Username needs at least 6 alphanumerics and password 6 to 12 alphanumerics; every failure shows the same message.","accept":["\"ab12\"/\"abc123\", \"abcdef\"/\"abc12\", \"abcdef\"/\"abc1234567890\" and \"abc-def\"/\"abc123\": role=alert \"Kullanıcı bulunamadı\"","\"abcdef\"/\"abc123\" signs in"]}]}],"nfr":[{"id":"NFR-01","weight":"Must","text":"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.","accept":["Moving INC-104 and deleting CR-4117 in one context leaves a new context with all cards in Inbox and \"4 records\""]}],"glossary":[{"term":"Look-alike record","meaning":"A record with a near-identical id or title (for example POL-137 and POL-173) that must not be confused with the target."},{"term":"Reset","meaning":"Control that restores a scenario's seeded data for the current tab."}],"outOfScope":["Placeholder links (Forgot password, Log in, Start free trial, Profile/Einstellungen)","Marketing copy and imagery","Help Center search box"]}