Skip to main content
Synced from the repo — do not edit here

Canonical source: docs/claude/app-redesign-data-contracts.md. This page is generated by docs/scripts/sync-handbook.mjs. Edit the source file in the repo; changes appear here on the next build.

App Redesign — Data Contracts & Backend Support

Companion to app-redesign-roadmap.md and app-redesign-wireframes.md. Captures the two backend-facing contracts the redesign UI assumes: (1) how a workout's assigned / logged / synced representations merge into one record, and (2) how every Atlas insight card in the mockups maps to backend detection so we know what to build. The Figma UI (fileKey 2Vs1e9IZVQh8KpMxc0W3PT) renders the result of these — this doc is the contract underneath.


1. Workout auto-merge / auto-complete contract

Problem: one real-world workout can be described by up to three separate inputs. The UI must show one unified summary, not three cards, and the plan must auto-complete without the user tapping "done".

The three inputs

InputSourceCarries
Assigned activityProtocol / plan (clinician- or Atlas-assigned)protocolActivityId, type, target params (e.g. 4×6 @ prescribed load), scheduled day/window
User-logged detailIn-app during the session (the Strong-style set rows)actual sets · reps · weight · isometric hold durations · notes · RPE, per exercise
Wearable-synced workoutWhoop / Apple Health / Garmin via Terra + HealthKitHR time-series, HR zones, calories, duration, GPS/route, cadence/power, start/end timestamps, source

Merge rule (canonical record)

  • Resolve the three to one canonical workout record per real session, keyed by (userId, activityType-family, overlapping time window).
    • A synced "strength / functional" workout whose window overlaps the assigned strength session → linked.
    • A synced "running/cycling/walking" workout with no assignment still produces a canonical record (standalone).
  • Auto-complete: when a matching logged or synced workout is detected, mark the assigned protocol activity complete and link it to the canonical record. User can still manually override completion.
  • The canonical record renders as the union: sets/reps/weight/notes (from log) + HR graph / zones / calories / route (from wearable) — exactly what the workout-summary screens show.

Precedence & provenance (per-field)

  • User-logged is authoritative for strength detail (sets/reps/weight/notes/holds).
  • Wearable is authoritative for biometrics (HR series, zones, calories, GPS, cadence/power).
  • Duration: prefer the wearable's verified duration; fall back to logged.
  • Store per-field provenance (which source supplied each value) so the summary can attribute ("via Whoop") and so dedup is auditable.

Dedup across wearables

  • If two devices record the same session (e.g. Whoop and Apple Health both log the run), canonicalize to one — reuse the existing source-attribution / workout-canonicalization path (same machinery as sleep dedup). Only one source contributes each metric; the rest are suppressed, not double-counted.

Timing / re-entrancy

  • Matching runs whenever the second representation arrives:
    • Terra webhook ingest (biometrics land) → look for same-day assigned activity + in-app log in window → merge.
    • In-app log finalize → look for an already-synced workout in window → merge.
  • Late-arriving wearable data back-fills an already-logged session in place (don't create a second record).
  • Webhooks fire in parallel and retry (see Terra rules in CLAUDE.md) → merge must be idempotent: per-user lock + upsert, never insert duplicates.
  • Edit preservation: once the user has edited merged detail, flag those fields and protect them from later wearable re-sync overwrite.

Backend to build

  • Canonical workouts (activity-completion) record: assignment ref + logged-detail blob + biometric blob + per-field provenance.
  • Merge/matching service invoked from (a) Terra webhook ingest and (b) in-app log finalize; windowed match by user + type-family + time.
  • Auto-complete write-back to the protocol activity (completion flag + link to canonical workout).
  • Idempotent upsert under per-user lock (reuse Terra per-uid lock pattern); no duplicates on parallel/retried webhooks.
  • Back-fill semantics (biometrics merge into existing logged record in place).
  • Edit-preservation flags (protect user-edited fields from re-sync clobber).
  • Extends existing Terra source-attribution / canonicalization — this is the workout analogue of the sleep canonicalization already shipped.

2. Atlas insight cards → backend support map

Every "helpful insight" in the redesign (e.g. "Your HRV dropped 14pts — take a rest day") is an output of the Atlas observation engine (scan → score → ground → card), which has 3 detector sources:

  • Template — curated detectors we ship so every clinic has good defaults day one.
  • Clinician-rule — provider-authored conditions (configured in basisflow-web; UI deferred, but the rule schema below is what backend must support).
  • Atlas-autonomous — model-detected patterns, gated through a clinician review queue before the client sees them.

Every card is grounded against the client's real data + personal baseline before display, and ships with confidence + source + "why" (non-negotiable per the roadmap).

Insight inventory (from the mockups) → what backend must produce

Insight (where it appears)SourceInput signalsTrigger / computationBaselineGroundingOutput card + actionProvider config knob
"HRV dropped 14pts → take a rest day" (Today hero)Templatenightly HRV, recent training loadHRV drop ≥ threshold vs rolling baseline60-day rolling HRVHRV series + workout logDiagnosticCard → adjust plan / log reston/off, Δ threshold, tone, action
"Skip strength Tuesday?" (Plan Cowork)Clinician-rule + Atlasmulti-day HRV trend, upcoming scheduleN-day declining trend + high-strain session aheadHRV baselineHRV trend + protocolCowork card → Approve/Discuss/Declinemutates protocol on approve, clinician notifiedtrend length, which activities, require-approval
"Deep sleep 20% below baseline" (Sleep)Templatesleep stages, bedtime, meal-log timingdeep-sleep deficit; correlate late meal/bedtimeper-stage baselinesleep data + meal logDiagnosticCard → view sleep tipsdeficit %, correlate-with-meals on/off
"14ms below personal baseline" (HRV detail)Derived statHRV seriescurrent vs rolling baseline deltarolling percentileHRV seriesinline baseline callout (no action)baseline window length
"ApoB trending up 4 panels → add fiber, recheck 8wk" (Lab / clinician note)Clinician-rule + Templatelab panels over timeper-analyte slope across panels → needs-attentionprior panelslab historyBiomarker card + clinician note → Discuss / order retestwhich analytes, out-of-range bands, retest interval
"Negative split · Zone 2 economy +4%" (Running)Atlas / Templatesplit paces, HR-vs-pacesplit analysis + HR efficiency vs historyprior runsGPS + HRinsight card (no action)on/off
"Climb power held 12 min" (Cycling)Templatepower streamsustained-power detectionpower meterinsight cardon/off
"Zone 1 walk after dinner → glucose + HRV" (Walk)Templateactivity timing, meal log, next-day HRVcross-domain correlationHRV baselinewalk + meal + HRVinsight cardon/off
"Volume +8% · new PR" (Strength)Templatetraining log historyvolume aggregation + PR detectionprior sessionsin-app loginsight card + PR badgeon/off
"Recommended for your ApoB — Omega-3" (Shop)Clinician-rule + Atlasout-of-range biomarkerbiomarker → intervention/product mappingreference rangebiomarker + catalogproduct rec card → add to cart (Rx needs clinician approval)mapping table, require-Rx-approval
Booking suggestion / protocol proposal (Chat)Atlas-autonomousschedule, recent datafollow-up cadence / drafted changerelevant datainline action card → Book / Approvereview-queue gating
"Needs attention: ApoB" (Health hero)Templateall biomarkersneeds-attention scoring, pick most-off-baselinereference + personalbiomarker setRangeBar card → Discussscoring weights

Shared backend primitives (build once, all rules reuse)

  • Signal store — normalized time-series across wearable / lab / in-app-log domains.
  • Personal-baseline service — rolling baselines/percentiles per metric (HRV, sleep stages, RHR, pace, etc.). Many cards depend on this; it's the highest-leverage primitive.
  • Detector framework — the observation engine's 3 lanes: template detectors, clinician rule engine (condition → copy → action → confidence gate), atlas-autonomous.
  • Confidence scorer — magnitude × signal-count × data recency/quality → the "% confidence" badge.
  • Grounding/citation — attach source refs to each card ("3 signals", "Whoop + sleep log") for the "why" affordance.
  • Observation/card store + delivery — persists cards (observations collection) → dashboard card + push; dedup so the same insight doesn't repeat.
  • Action framework — each card action maps to a handler: adjust_plan, book, order, log, notify_clinician, mutate_protocol. (Chat inline-action-card handler already partly scoped in copilot work.)
  • Provider config — per-clinic template on/off + thresholds + tone + action set (the "knob" column above). This is the data model behind the (deferred) basisflow-web rule-builder.
  • Review queue — clinician approves/edits Atlas-drafted insights before clients see them (clinician-side mirror of the Approve/Discuss/Decline card).

Clinician-rule schema (what the deferred basisflow-web builder writes)

Even without the builder UI, backend must accept rules of this shape so clinicians can seed/edit insights:

InsightRule {
clinicId
enabled: bool
name: string
when: { // condition
signal: 'hrv'|'deep_sleep'|'apob'|'training_load'|...
op: 'below_baseline'|'above'|'trend_down'|'slope_over_panels'|...
threshold: number
window: duration
}
ground_on: [signalRefs] // what to cite
say: { title, body, tone } // insight copy (or template ref)
action: 'adjust_plan'|'book'|'order'|'notify_clinician'|'mutate_protocol'|null
confidence_gate: number // suppress below this
require_clinician_approval: bool // route through review queue
}

Map each row in the inventory table to one InsightRule (or template) to enumerate the v1 detector set.


Open decisions (surface before backend build)

  • Personal-baseline window lengths per metric (HRV 60d? sleep 30d?).
  • Which insights are client-visible immediately vs must pass the clinician review queue.
  • Biomarker→intervention mapping table ownership (clinical content) and Rx-approval flow.
  • Confidence-score formula weights (magnitude vs signal count vs recency).