01 — Product Requirements Document
Product: PrepRounds (working title)
One-liner: A mobile app where newly promoted charge nurses and frontline nurse leaders rehearse the specific hard conversations their role forces on them, against a realistic AI “staff member,” and get structured feedback before it happens for real.
Build target: RevenueCat Shipaton 2026 · Submission deadline Sep 30, 2026, 11:45pm PDT
1. Vision
Charge nurses and new nurse managers are promoted almost entirely on clinical skill, then immediately expected to have hard, high-stakes people conversations they’ve never been trained for. PrepRounds gives them a private, judgment-free place to rehearse those exact conversations before they happen on the floor. Full problem/market/impact research lives in the companion concept brief delivered earlier in this project; this PRD assumes that context and focuses only on what to build.
2. Personas
Primary — “New Charge Nurse Nadia.” Just picked up her first charge shifts. Clinically confident, has never formally given a peer feedback, said no to her manager, or de-escalated a shift conflict. Wants to feel ready before the moment arrives.
Secondary — “Health Informatics/Nursing Student Sam.” Not yet in a leadership role but anticipates one. This persona is also who unlocks the Next Gen Award submission path.
3. Goals / Non-Goals
In scope (v1):
- 4 named, fixed roleplay scenarios (defined verbatim in
04-SCENARIO-PROMPTS.md — do not add a 5th)
- Text-based live roleplay against an LLM-backed persona
- Structured post-session feedback (fixed JSON schema, not free text)
- Session history with a simple confidence trend
- Full RevenueCat subscription + paywall integration
- RevenueCat Ads bonus-session unlock
- OneSignal daily practice nudge
Explicitly out of scope (v1) — reject these if suggested mid-build:
- EHR/clinical-record integration of any kind
- Real patient data anywhere in the app, at any layer
- A general-purpose “practice any conversation” mode
- Wearable integration
- Multiplayer/community/social features
- Clinical diagnosis, triage, or medical-advice functionality
- Voice mode (STT/TTS) — v1.5 stretch only, build after the text core loop is fully working, never at the expense of it
4. User Stories & Acceptance Criteria
Each acceptance criterion below must be independently verifiable — if you can’t check it off with a yes/no, it isn’t done.
US-1 — Onboarding
- AC1: Onboarding is exactly 3 screens: role select → unit-type select → notification opt-in
- AC2: Role options are exactly: “Charge Nurse”, “Aspiring Charge Nurse”, “New Nurse Manager” — stored as
role enum (see §10 of architecture doc for exact values)
- AC3: Unit-type options are exactly: “Med-Surg”, “ED”, “ICU”, “Other” — stored as
unit_type enum
- AC4: Declining notifications on step 3 does not block progressing to Home
- AC5: Onboarding runs exactly once per user; a returning user goes straight to Home
US-2 — Scenario selection
- AC1: Home screen renders exactly 4 scenario cards, sourced from
constants/scenarios.ts (built from 04-SCENARIO-PROMPTS.md) — never hard-code scenario text inline in a component
- AC2: Each card shows: name, one-line description, difficulty badge (Easy/Realistic/Intense), time estimate (“~3–5 min”)
- AC3: Tapping a card navigates to that scenario’s pre-brief screen, passing
scenarioId as a route param
US-3 — Live roleplay
- AC1: The AI’s reply must be generated per-turn from the actual conversation history sent to the LLM — never a pre-scripted response
- AC2: A visible “typing” indicator shows between the user sending a message and the AI reply rendering
- AC3: The session ends when either: (a) the LLM signals resolution per its system prompt, or (b) 10 user turns are reached, whichever comes first
- Resolved (Sep 2026): the in-session turn counter must display as “Turn X”, not “Turn X/10”. Verified real sessions resolve at turn 3–7 in practice (scenario prompts target ~8 exchanges), so 10 is a rarely-reached safety backstop, not a real target — showing it as a denominator implies a false progress goal. This is not a spec inconsistency (the ~8 target and the 10-turn cap serve different jobs: expected resolution point vs. hard stop), only a display fix.
- AC4: On session end, the full transcript is persisted before navigating to the feedback screen — if persistence fails, show a retry option, do not silently discard the transcript
US-4 — Structured feedback
- AC1: Feedback is generated by a second, separate LLM call over the finished transcript (never the roleplay persona grading itself — see
02-ARCHITECTURE-AND-DATA.md §11 for the exact contract)
- AC2: Feedback response must validate against the fixed JSON schema in
02-ARCHITECTURE-AND-DATA.md §11 before rendering — if it fails to parse, retry the call once, then show an error state (never render partial/malformed data)
- AC3: UI shows, in order: one-line summary → “What landed” card → “Try this instead” card → confidence score (1–5)
US-5 — Practice history
- AC1: History screen lists all past sessions, newest first, showing scenario name + date + confidence score
- AC2: A simple line/sparkline shows confidence score trend across the last up-to-10 sessions
- AC3: Empty state (zero sessions) shows an encouraging prompt to start the first scenario, not a blank list
US-6 — Paywall
- AC1: Free tier = 3 total roleplay sessions across all scenarios combined (not 3 per scenario)
- Resolved (Sep 2026): usage is recorded on genuine completion, not on start.
recordSessionUsage() must fire at the same point ended_at is set (inside concludeAndNavigate, after the transcript successfully persists) — not in the pre-brief screen before the scenario begins. A session abandoned before completion must not consume any of the free allotment, consistent with 03-DESIGN-SYSTEM-AND-SCREENS.md §5.6’s “never be tappable or counted” for abandoned sessions — that clause was written with this case in mind, the increment simply hadn’t been checked against it until now. canStartPracticeSession()’s gating logic is unaffected; only the timing of the increment changes.
- AC2: On attempting a 4th session without an active
pro entitlement, present RevenueCat’s Paywalls v2 component (RevenueCatUI.presentPaywallIfNeeded) — do not build a custom paywall screen
- AC3: A successful purchase immediately unlocks unlimited sessions without requiring app restart
US-7 — Bonus session via ad (Catvertising)
- AC1: Once free sessions are exhausted and the user is not subscribed, the paywall screen (or a screen reachable from it) offers “Watch an ad for 1 more session” as a secondary, non-blocking option
- AC2: Completing the rewarded ad grants exactly 1 additional session, tracked separately from the free-session count and from the subscription entitlement
- AC3: This flow never auto-triggers — it is only ever user-initiated by tapping the offer
US-8 — Daily nudge (OneSignal)
- AC1: If notifications were accepted in onboarding, one OneSignal campaign fires daily at the user’s chosen time
- AC2: Users can change or disable this in Settings at any time, and the change takes effect without requiring reinstall
5. Non-Functional Requirements
- Every async screen has 3 explicit states: loading, error, and success/data. No screen may render silently blank while data is in flight — see
03-DESIGN-SYSTEM-AND-SCREENS.md §5 for the exact pattern per screen.
- No crash on network failure. Every LLM/Supabase/RevenueCat/OneSignal call is wrapped in error handling that surfaces a user-facing message, never an unhandled promise rejection.
- Accessibility: minimum 44×44pt tap targets, ≥4.5:1 text contrast, Dynamic Type support (see design doc §7).
- No PHI/PII beyond what’s required. Do not collect patient information, real names of coworkers, or facility identifiers anywhere in the app.
6. MVP Build Priority
| Feature |
Priority |
Blocks |
| Onboarding |
P0 |
Everything |
Scenario library (data only, from 04-SCENARIO-PROMPTS.md) |
P0 |
Home, roleplay |
| Roleplay engine |
P0 |
Feedback |
| Feedback engine |
P0 |
History |
| History screen |
P0 |
— |
| RevenueCat subscription + Paywalls v2 |
P0 |
Hard hackathon requirement |
| RevenueCat Ads bonus session |
P1 |
Catvertising category only |
| OneSignal daily nudge |
P1 |
OneSignal category only |
| Voice mode |
P2 (stretch) |
Nothing — cut first if time is short |
7. Hackathon Requirements Crosswalk
| Requirement |
Status to hit before submission |
| First public release during Aug 1–Sep 30 window |
N/A if submitting Next Gen only (no store release required) |
| RevenueCat SDK powering ≥1 purchase or ads |
Subscription entitlement configured + tested purchase completed |
| 1024×1024 app icon |
Produce from design tokens in 03-DESIGN-SYSTEM-AND-SCREENS.md |
| Screenshot 1179×2556, no device frame |
Capture from Feedback or Roleplay screen |
| Demo video ≤2 min, YouTube/Vimeo, public |
Script after core loop is stable |
| Next Gen: public repo + OSS license visible in About |
Add LICENSE (MIT) on day 1 |
| Free trial or promo code for judges |
Configure in RevenueCat dashboard (not required for Next Gen–only path) |