PostureVision
Master Plan
Complete product architecture from first landing page through deep in-app usage. Reference for the full team during Sprint Days 7–14.
Product Philosophy
"PostureVision is a wellness companion, not a medical device."
We meet people where they are — curious, slightly uncomfortable in their bodies, wanting to feel better — and we give them a mirror, a practice, and a community to grow with. Clinical precision under the hood, approachable aspiration on the surface.
Who We're Building For
- 📊 3 Daily Checks per week
- 📈 Basic posture scoring (single dimension)
- 🔍 Onboarding: Posture Read + Movement Quality + ROM Preview
- 📅 Daily streak counter
- 🔒 Mirror Mode (locked — demo preview only)
- 🔒 ROM Functional Tests (locked)
- 🔒 Activations (locked)
- 🔒 Challenges (locked)
- ♾️ Unlimited Daily Checks
- 🎯 Full 4-dimension composite score
- 🪞 Mirror Mode — real-time posture coaching
- 🏃 Active Mode — movement progression
- 📐 ROM Functional Tests (+ ID verify)
- ⚡ Activations — targeted 2-min modules
- 🏆 Challenges — 30-day programs + social
- 📷 Lateral photo capture + sagittal trend
The premium tier is called Poise — not "Pro." Poise is an aspiration: grace, balance, presence. It signals to users that upgrading is about becoming, not just unlocking features. This distinction is load-bearing for all copy and marketing.
The Core Loop
Every screen, every feature, every unlock — serves one of these three moments.
The 4 Poise Dimensions
Full Funnel Map
Every user enters through marketing and converges on the same onboarding experience — regardless of platform. Cloud vs. local inference splits only after install.
iOS · Alain
Android · after iOS
Electron stub install · Hiep (Full-Stack)
50–90cm from camera · front-facing
iOS and Android use cloud inference — camera frames are processed server-side (An's API). Desktop (Electron, Hiep's lane) runs local inference only — no camera data ever leaves the device. Encrypted model bundle, stub installer with on-demand model download. Same UI/UX, different data path.
Onboarding gives a snapshot — 40 seconds, front-view only, three scores (Posture Read, Movement Quality, ROM Preview). It's the hook. Daily Check is where the full 4-dimension Poise composite lives — Posture · Stability · Focus · Presence — scored against your own baseline and population norms. The backend pipeline during Daily Check runs the same cervical rotation tracker, the same shoulder symmetry model, and additionally streams Focus (blink rate, gaze drift) and Presence (attentiveness composite) that the onboarding 40s window is too short to capture reliably. Daily Check also generates the trend line — the chart that shows whether you're improving week over week. That chart is the retention hook. Onboarding shows you where you are. Daily Check shows you where you're going.
Module Unlock Sequence
Modules unlock progressively — each unlock is earned, not dumped on the user. Free users experience a meaningful arc; Poise users get the full depth. Color = tier required.
No feature is hidden — everything is visible, named, and described. Locked features show what they do before asking for payment. The sequence is designed so the user wants to unlock the next step before they hit the gate.
Platform Architecture
Three platforms, one product experience. Infrastructure diverges at inference layer — cloud for mobile, local for desktop.
- Cloud inference — frames → An's API
- RevenueCat for subscriptions
- Apple Sign-In + Apple IAP
- 375×812px base (iPhone 14 target)
- Deep link support for social share / challenges
- Priority platform — ships first
- Background motion alerts (optional)
- Cloud inference — same API as iOS
- Google Play Billing
- Google Sign-In
- Multiple viewport sizes
- Deep link support (App Links)
- Follows iOS launch by ~4–6 weeks
- Not in current sprint scope
- Local inference only — no camera data leaves device
- Encrypted model bundle in app package
- Installer target: much smaller than 100MB — stub installer + on-demand model download
- Stripe for desktop subscriptions
- macOS · Windows · Linux builds
- Auto-update via electron-updater
- Clinician / desk-worker primary audience
- Hiep also handles full-stack API integrations (Stripe webhooks, auth middleware, PostHog server-side)
Camera Distance Specifications
| Module | Distance | View | Why |
|---|---|---|---|
| Daily Check / Onboarding | 50–90 cm | Front | Face + upper body in frame; shoulder alignment + head position readable |
| Mirror Mode | 50–90 cm | Front | Real-time shoulder/head tracking; same position as Daily Check — no reset needed |
| Lateral Photo Capture | 2.0–2.5 m | Side (90°) | Full upper body sagittal view: forward head angle, thoracic kyphosis, lumbar lordosis |
| Balance Tests (single-leg) | 1.5–2.0 m | Front or 45° | Full body including feet visible; sway radius measurable at this range without distortion |
| ROM Rotation | 50–90 cm | Front | Cervical rotation tracking; same close range; shoulder fixed as reference plane |
Premium Upgrade Touchpoints
Eight distinct moments where a free user encounters a Poise upgrade prompt. Each is contextual — triggered by user intent, not interruption. The goal: upgrade feels like the obvious next step, not a barrier.
🪞 Mirror Mode Demo Strategy (Non-Poise Users)
"Let them feel the product before asking for payment. After 15 seconds, fade to paywall with: 'This is what you just saw — running on you, in real time.'"
- User taps Mirror Mode card (Free)
- 15-second animated preview begins — no real camera
- CSS/canvas silhouette with floating posture metrics
- Preview ends → fade to Poise paywall
- "This is what you just saw — running on you, in real time"
- Start 7-day trial CTA
- 🔄 Drift % indicator animating (e.g. "2.3% left drift")
- 💬 Coaching cue text cycling ("Chin back slightly")
- 🌊 Presence indicator pulsing (0–100)
- 👁️ Eye health chip ("Blink rate: normal")
- 🕐 15-second countdown visible
Silhouette gently sways, metrics animate as if live. After 15s, blur → paywall overlay slides up with the closing line.
🏃 Active Mode Demo Strategy (Non-Poise Users)
- User sees Active Mode teaser on Home (after 1st Mirror session)
- Shows progress toward unlock: "2 more Mirror sessions needed"
- Non-Poise: tap → short CSS animation of exercise sequence
- Animated stick figure cycling through a cervical retraction exercise
- Fade to paywall: "Active Mode builds on your Mirror data. Unlock Poise to start."
- 🔄 Animated exercise rep counter cycling (1 → 2 → 3…)
- 📐 ROM arc overlay showing target range
- ✅ Green "in range" flash on correct position
- 💬 Coaching cue: "Hold 2 seconds at end range"
- ⏱️ 8-second loop — enough to feel real without overstaying
📐 ROM Functional Tests Demo Strategy
- User taps ROM card → sees a blurred result card showing "74° / 68°"
- Copy: "Your cervical rotation is ready to measure. Takes 90 seconds."
- Short animation: a head-turn arc overlaid on a silhouette
- ID verify prompt appears (name + DOB, not government ID)
- Poise gate if not subscribed — with specific ROM value as the hook
- 🔢 Show a blurred specific number: "Your rotation: ••°"
- 📊 "Normal range: 70–90° each side. Where do you land?"
- 🏆 "Top 15% of PostureVision users have symmetric rotation. Are you?"
- 📋 "Your result is yours to keep and share — verify to unlock."
Body Tracking Technical Specs
Precise camera, distance, and anti-cheat specifications for An (backend inference), Alain (iOS camera pipeline), and Hiep (desktop local model).
| Module | Distance | Why | View |
|---|---|---|---|
| Daily Check | 50–90 cm | Face + upper body; shoulder, neck, head alignment readable at this range | Front |
| Mirror Mode | 50–90 cm | Shoulder/head real-time tracking; same position as Daily Check, no repositioning needed | Front |
| Lateral Capture — Posture Analysis | 1.0–1.5 m | Seated first: close range captures upper-body sagittal curve (FHA, kyphosis). Then standing full-body at 2.0–2.5m for exercise form reference. | Side (90°) |
| Balance Tests (single-leg) | 1.5–2.0 m | Full body including feet visible; sway radius measurable at this range without fisheye distortion | Front or 45° |
| ROM Rotation | 50–90 cm | Cervical rotation tracking; shoulder as fixed reference plane; close range for angular precision | Front |
⚖️ Single-Leg Balance Anti-Cheat Protocol
Required for social share / leaderboard integrity. All checks must pass before a balance session is recorded.
- 👣 Foot separation pre-check: Both feet must be >30cm apart before lift is registered. If not: "Please stand with feet hip-width apart."
- 📏 Sway radius limit: If center of mass sways >15cm from starting point → session flagged "re-position." Score not recorded.
- 🙌 Hand detection: If hands detected near hips or gripping surface during hold → prompt "Arms relaxed by sides." Repeat offenses → session invalid.
- 🏠 Environment check: Ask user to stand in open space before session. Detect furniture/walls within 60cm → warn "Please clear space around you."
- 📐 Depth calibration: Use shoulder width (avg 40cm real-world) as reference to compute metric distances from pixel measurements. Calibrated at session start.
📷 Lateral Photo Capture Protocol
⚡ ROM Rotation — tooFast / tooSlow Flags
- ⚡tooFast: Rotation completed in under 1.2s → flag: "Please rotate slowly and steadily." Score not valid for this rep. Implemented in
rotation_tracker.js. - 🐌tooSlow: Rotation stalls mid-way (>3s pause) → flag: "Keep moving through the full range." Partial ROM recorded. Also in
rotation_tracker.js.
🏎️ Chin Jut / Tuck Fine-Tuning ("Ferrari Engine")
The precision engine for detecting forward-head / chin-jut posture patterns during Daily Check and Mirror Mode. Fine-tuned thresholds for what constitutes clinically meaningful deviation.
- 📁File: test_chin_tuck_mechanics.py — PostureVision root
- 🎯Use: Threshold calibration for head translation (anterior), chin angle, and ear-to-shoulder offset. Reference before tuning Daily Check posture scoring.
- 🔗Related: front_view_analyzer.py · posture_score_processor.py
Gamification Architecture
Four levels of engagement — personal, communal, competitive, and ambassadorial. Each level deepens the user's relationship with the product and with other users. Levels 2–4 require Poise.
- 🔥 Daily streak counter (1-day to ∞)
- 🏅 Session badges (First Breath, First Mirror, etc.)
- 📈 Poise score history chart
- 🎯 Personal best tracking per module
- 📅 2 launch challenges (see below)
- 🏃 User browses and opts in — not auto-enrolled
- 📊 Days remaining, your streak, top 3 leaderboard
- 🔔 Daily completion nudge notification
- ⚖️ Single-leg balance: seconds + sway score
- 🔄 Cervical rotation: degrees vs personal best
- 🌊 Poise Score vs friends composite
- 🔥 Streak Length leaderboard
- 🔗 "Beat my score" deep link share
- 🏆 Unlock: 30-day streak + 3+ friend shares
- 🌟 "Poise Ambassador" badge in profile
- 📧 Feature in monthly Poise Ambassador digest
- ⚡ Priority support + early access
- 💬 "You're in the top 1% — share your story"
🏆 Launch Challenges (2 at Launch)
Daily Activation completion for 30 consecutive days. Solo or group.
- 📅 Duration: 30 days
- ✅ Completion: daily Activation logged
- 🏅 Badge: "Mobility Reset Champion"
- 📊 Leaderboard: most consistent completions
Invite 2 friends. All 3 complete 7 Daily Checks in one week. Social accountability at its simplest.
- 📅 Duration: 1 week
- 👥 Team: you + 2 friends via invite link
- ✅ Completion: all 3 hit 7 checks
- 🏅 Badge: "Rise Together" (all 3 get it)
📣 Best Shareable Exercises
| Exercise | What's Shared | Share Copy Template |
|---|---|---|
| ⚖️ Single-Leg Balance | Seconds held · sway score | "I held single-leg balance for 47 seconds. Can you beat it?" + deep link |
| 🔄 Cervical Rotation | Degrees (L+R) vs personal best | "My cervical rotation hit 74° today — that's a personal best. Yours?" + link |
| 🌊 Poise Score | Composite score (0–100) | "My Poise Score is 83 today. Where are you?" + challenge link |
| 🔥 Streak Length | Days consecutive | "Day 21 — still going. Join me?" + invite link |
| 👁️ Eye Tracking Score | Smooth pursuit score + blink rate | "My focus score hit 91 today — 45-min session with zero drift. Try it." + link |
| 🦵 Single-Leg Reach | Reach distance + stability hold | "Reached 78% of my leg length on the Y-balance. Can you beat that?" + link |
⚡ Activations — Session Durations
Users choose duration before each Activation. All options available to Poise subscribers. Free users via invited-friend tier get 10 min/week (see below).
If a free user is invited by anyone (Poise subscriber or another invited free user), they unlock 10 minutes of Activations per week + access to join Challenges. The viral loop compounds: invited users can invite others — each new person gets the same 10 min/week taste. You don't need Poise to spread the product. Poise users share first; their friends share next; their friends' friends share after that. No timer needed to browse Activations — they see all modules, they just get 10 min/week to run them.
🏅 Leaderboard & Social Module
All competitive features live in one unified social/competitive module space — accessed via the Achievements tab. Challenges, leaderboards, friend scores, and share moments all live here. This avoids scattering social touchpoints across every screen and gives competition a home users learn to visit intentionally.
Screen Inventory
All current HTML design files in the /Code/ root. These are the canonical references for frontend implementation. Alain and Hiep: treat v3 as the design system source of truth.
🆕 New Files (Apr 28)
posturevision_daily_check_harness_ios.html etc. Target viewport: iPhone 14 (375px wide, 812px tall, 3x DPR). Priority: Day 9–10.
7-Day Sprint (Days 7–14)
April 28 → May 5, 2026. Production deploy on Day 14. Color-coded by owner. Each task is a discrete deliverable — no ambiguous "work on X" items.
| Day | Owner | Task | Status |
|---|---|---|---|
| Day 7 Apr 28 |
Brian/Claude | Nav fixes · ProGate upgrade wall · Challenges page wire · This presentation | ⚠️ In Progress |
| Day 8 Apr 29 |
An | Daily Check backend WebSocket endpoint · onboarding_result payload · Active Mode backend skeleton | 📅 Scheduled |
| Day 8 Apr 29 |
Brian/Claude | Self-Corrections replay UI · Daily Check frontend wire to An's endpoint · PostHog event tracking setup | 📅 Scheduled |
| Day 8 Apr 29 |
Hiep | Stripe webhook middleware · setProStatus store wiring after subscription API response · Electron stub installer build | 📅 Scheduled |
| Day 9 Apr 30 |
An | Gentle history drip (score context messages) · Deep-link invite system for social share | 📅 Scheduled |
| Day 9 Apr 30 |
Alain | iOS RevenueCat end-to-end confirm · Cancellation flow confirm · iOS harness variants start | 📅 Scheduled |
| Day 10 May 1 |
Zoraiz/An | ROM mini-harness · Real cervical rotation scoring · tooFast/tooSlow flag decision | 📅 Scheduled |
| Day 11 May 2 |
All | Streak engine · Badges system · License flow · Profile screen polish | 📅 Scheduled |
| Day 12 May 3 |
An/Brian | Activations 2-min module · Live coaching feedback during Activation | 📅 Scheduled |
| Day 13 May 4 |
All | Red flag gate (injury/contraindication detection) · QA sweep · Copy polish · Legal review | 📅 Scheduled |
| Day 14 May 5 |
All | 🚀 Production deploy · Smoke test · Announce to waitlist · GHL trial drip goes live · PostHog funnel review | 📅 Scheduled |
Open Questions for Team
These need answers before we can close the sprint. Each is assigned to a specific owner. Resolution target: EOD Day 9 at latest, or the downstream task is at risk.
Zustand store — the app's shared memory while it's running. Think of it as a live whiteboard that every screen can read and update. When the user subscribes to Poise, we write isPro: true to the store and every locked screen instantly unlocks — no page reload. It also persists to localStorage so the user stays logged in and subscribed across sessions.
WebSocket — a live two-way connection between the app and An's server. Unlike a regular API call (ask → wait → answer), a WebSocket streams data continuously frame-by-frame. The camera feed during Daily Check and Mirror Mode uses this to receive posture scores in real time.
setProStatus — the specific action in the Zustand store that flips the subscription state. After Stripe or RevenueCat confirms payment, the app calls store.setProStatus(true) and every ProGate unlocks immediately. Hiep is wiring this for desktop; Alain for iOS.
1. Daily Check WebSocket schema — /module/daily-check/{peer_id} field list. Minimum: posture_score, head_tilt, shoulder_balance, phase.
2. Onboarding result payload — onboarding_result WebSocket final message. Fields: postureRead, movementQuality, romPreviewDegreesL, romPreviewDegreesR.
Both frontends are fully built and waiting. Every day without these schemas = Day 8 wire is at risk. Drop schemas in Slack before you sleep.
Each open question blocks a downstream task. Post answers in Slack with the question owner tag (e.g. "@An — Q2 answer:") so this doc can be updated. Target: all questions resolved by EOD Day 9 (April 30).
Marketing Stack
Julia and Christiane own top-of-funnel and lifecycle marketing. The stack is GHL-first — Brian already has the infrastructure. PostHog closes the loop between product behavior and marketing triggers.
Rise Science (riseapp.com) is a well-funded sleep/energy app that owns "Rise" in the wellness category. Using "Rise" as a core brand word risks confusion and SEO dilution. Current uses in PostureVision: "Rise Together" challenge, "Rise Ambassador" program, "Rising" email newsletter. Recommended alternatives:
"Poise Ambassador" is the strongest rename — it ties directly to the premium tier brand and avoids any Rise Science overlap entirely.
- 🎯 Paid ads strategy (Meta, Google, TikTok)
- 📣 Social content calendar + organic posts
- 🔗 Deep link tracking (UTM → PostHog → GHL)
- 📊 PostHog dashboard: acquisition funnel, CAC, ROAS
- 🤝 Poise Ambassador program outreach
- 📬 GHL email sequences — trial drip, re-engagement
- 🔔 Push notification copy (streak reminders, feature reveals)
- 📈 PostHog cohort analysis: who upgrades, who churns
- 🎁 Referral program copy + invite flow
- 📰 Monthly Poise Ambassador digest email
📧 Email Stack — GHL + SendGrid
The stack is already decided and already built. SendGrid (@sendgrid/mail ^8.1.6) is live in pv-auth-service — it handles email verification, password reset, and welcome emails via direct API calls. GoHighLevel handles the full lifecycle marketing layer (trial drip, re-engagement, ambassador sequences). Stripe handles payment receipts natively. Nothing else is needed — Resend was never in the actual codebase.
| Email Type | Platform | Owner | Trigger |
|---|---|---|---|
| Trial welcome | GHL | Julia | PostHog trial_started → GHL webhook |
| Day 2–7 drip sequence | GHL | Julia | GHL time-based automation in sequence |
| Trial expiry warning | GHL | Julia | GHL day-6 trigger in trial sequence |
| Re-engagement (Day 8+) | GHL | Julia | PostHog session_inactive_7d → GHL webhook |
| Email verification | SendGrid | An | pv-auth-service — sendVerificationEmail() via @sendgrid/mail |
| Password reset | SendGrid | An | pv-auth-service — sendPasswordResetEmail() via @sendgrid/mail |
| Poise Ambassador digest | GHL | Julia | Monthly batch — top 1% cohort from PostHog |
🔗 Integration Stack Diagram
PostHog fires a webhook on key events (trial_started, session_inactive_7d, upgrade_clicked). GHL receives the webhook and enrolls the contact in the matching automation sequence. This means every in-app behavior can trigger a precise lifecycle email — without building a custom notification system.
Household & Social Architecture
Couples + Family plans · social challenges · the wholesome viral moat
Households are sticky. A couple or family that posture-checks together on shared progress doesn't churn — it becomes a daily ritual. Couples and families also unlock parent-suggesting-to-kid and partner-encouraging-partner as the dominant invite mechanism, which converts at 3-5× cold acquisition.
Pricing & SKU structure
Account hierarchy & data model
id (uuid)
primary_user_id ← billing owner
plan_tier (solo | couples | family)
seat_limit
stripe_subscription_id
created_at
household_members
household_id (fk)
user_id (fk)
role (primary | partner | child | adult_member)
is_minor (bool)
parental_consent_at ← required if is_minor
privacy_share_level (none | streak_only | scores | full)
joined_at
Privacy boundaries · default-private, opt-in to share
- →Default share level for new household members:
streak_only— others see "currently on a 12-day streak" but never raw posture data, scores, or video. - →Each member opts in independently to share scores or full insights with other household members. No automatic visibility based on payment relationship.
- →Minors (under 13): COPPA-compliant flow — parent creates the account, parental consent recorded, child's data is parent-visible by default but never visible to other household adult-members without parent toggle.
- →No video, ever: camera-only architecture means even within a household, no member sees another member's actual video. Only derived metrics share-able.
- →HIPAA isolation: household data is
pv-*tagged only. Never crosses intodh-*clinical practice records.
Invite mechanics · how households grow
Primary user upgrades to Couples plan → invites partner via email/SMS → partner clicks magic-link → onboarding flow → joins household at streak_only share level.
Primary parent invites adult members same as couples. For minors, parent creates child profile, completes parental-consent form, child onboards under parent's supervision (parent can sit beside camera).
Shared experiences · what households see together
- ◆Household streak counter — combined "we've been at it for X days" badge. One miss by anyone resets only that person's solo streak, not the household.
- ◆Joint challenges — Crown-Line Duet, Synchronized Stretch, Mirror Partner, Family Relay (see Section 13 for spec).
- ◆Private household leaderboard — opt-in. Friendly head-to-head on streaks, challenges, weekly Poise.
- ◆Weekly household digest — Sunday email "this week in your household" — combined wins, individual milestones (only for members opted into score-sharing).
- ◆Member switcher in app — primary user can switch between member views (with their consent) to support kids using the household device.
Billing model
- ·Single Stripe subscription tied to
household.stripe_subscription_id, paid by primary user only. - ·Plan upgrades (solo→couples, couples→family) prorate current billing cycle.
- ·Plan downgrades take effect at end of billing cycle. Members beyond new seat limit retain access through cycle end, then transition to free tier.
- ·Cancellation: members keep their account + history but lose Premium features at cycle end. Household entity persists for re-activation.
Challenge Library
Social-first exercise specs · all monitorable with existing keypoint pipeline
Every challenge below uses only the existing 200+ keypoint pipeline — joint angles, COM drift, position over time. No new ML models. UI + scoring logic only.
v1 launch · 5 exercises
Score logic: time held before COM drifts >5 cm OR raised foot touches down. Eyes-closed mode uses 1.5× difficulty multiplier on ranking. Cheat detection: wrist position relative to torso (no leaning on wall/counter).
Score logic: knee angle ~90° + hip angle ~90° + back-line straight. Time held until any angle slips >5°.
Score logic: shoulder-hip-ankle alignment within tolerance + no hip drop >5 cm. Time held.
Score logic: count clean reps where hip drops below knee then returns to standing, no hand-on-thigh assist (hand-keypoint vs. thigh distance gate). Real clinical fitness metric.
Score logic: hold neutral posture for 60s — no drift events fire. Uses existing drift-detection pipeline.
Couples/Family-only · the upgrade unlock
Both partners hold neutral standing posture for 2 minutes on separate cameras. Score = combined Poise average + form-symmetry bonus. Marketed as "the household ritual" — wholesome, shareable, drives Couples-plan upgrades.
v2 expansion (4-6 weeks post-launch)
Wall angel slide · Squat depth 10-rep · Forward fold reach · Y-balance reach · Synchronized stretch · Mirror partner · Family relay · Posture reset speed · Slow-motion squat · Hip hinge form.
Confidential — Internal team use only