Why Blood Pressure Tracking Is a Compliance Challenge
A blood pressure tracker sounds simple: store readings, display a trend chart. The compliance challenge is that blood pressure is a clinical measurement with established diagnostic thresholds. A 130/80 reading means something specific in clinical medicine, and so does 140/90. The 2025 AHA/ACC guideline calls the first stage 1 hypertension and the second stage 2. How you display that information in an educational app determines whether you are providing education or practicing medicine.
This post covers the architecture decisions made in building the blood pressure tracker for Hunters Holistic Health, with specific attention to the educational framing that keeps the feature in educator territory.
The Data Model
The blood pressure log table in Supabase has the following structure:
- id (UUID, primary key)
- user_id (UUID, foreign key to auth.users)
- systolic (integer, 60 to 250 range check)
- diastolic (integer, 40 to 200 range check, because readings above 120 diastolic are the severe range and a constraint at 150 would silently reject exactly the readings that matter most)
- pulse (integer, optional, 30 to 200 range check)
- context (text, optional: "morning", "evening", "stressed", "did not rest five minutes first", "within 30 minutes of caffeine, smoking, or exercise")
Those last two context values exist because the AHA measurement instructions matter more than the chart does. A reading taken within 30 minutes of caffeine, smoking, or exercise, or without five minutes of quiet rest, is not comparable to the rest of the log, so the app flags it rather than silently averaging it in. The logging screen carries the short version of the AHA protocol: validated automatic upper arm cuff, correct cuff size, feet flat, arm supported at heart level, two readings one minute apart.
- notes (text, optional, 500 character limit)
- logged_at (timestamp with time zone)
- created_at (timestamp with time zone)
The range checks are enforced at the database level, not just the UI level. This prevents obviously erroneous data from being stored and reduces the risk of the chart displaying values that could be misinterpreted as clinical data.
Row Level Security ensures that users can only read and write their own records. The educator can read all records for their clients but cannot write to client records.
The Chart Architecture
The trend chart uses Chart.js with a line chart type. The x-axis is time (logged_at), the y-axis is the reading value. Systolic and diastolic are displayed as separate lines.
The chart includes reference lines at 120/80 (the top of normal, which the 2025 AHA/ACC guideline defines as under 120 systolic and under 80 diastolic), at 130/80 (where stage 1 hypertension begins), at 140/90 (stage 2), and at 180/120 (the severe range that gets its own urgent action path). These reference lines are labeled as educational reference points, not diagnostic thresholds.
The color coding is intentional: readings below 120/80 are displayed in teal (the brand's positive color), readings of 120 to 129 systolic with diastolic under 80 are displayed in a light amber, readings of 130 to 139 systolic or 80 to 89 diastolic in a deeper amber, readings of 140 or higher systolic or 90 or higher diastolic in a muted red, and anything above 180/120 in a distinct color tied to the urgent action message. The colors are informational, not alarming.
The Educational Framing Pattern
The most important architectural decision in the blood pressure tracker is the educational framing pattern. Every time a reading is displayed in a zone that might prompt concern, the UI shows educational context rather than a diagnostic label.
Instead of stamping "WARNING: HYPERTENSIVE CRISIS" on any reading over 140/90, which borrows an emergency label for a number the guideline calls stage 2 hypertension
The UI shows: "This reading falls above the 130/80 reference point in the 2025 AHA/ACC blood pressure categories. One reading is not a diagnosis, and the American Heart Association suggests retaking it after five minutes of quiet rest. If your readings keep landing here, that is worth a conversation with your own healthcare provider. Above 180/120 the app drops the color coding entirely and shows one message: this reading is in the severe range, contact your healthcare provider now, and call 911 if you also have chest pain, shortness of breath, weakness or numbness, vision changes, or trouble speaking. Here is what this means: [link to AHA educational resource]."
This pattern is applied consistently throughout the app. The rule is: educational context, not diagnostic labels. Reference points, not thresholds. Recommendations to consult a provider, not diagnoses.
The "No DOB" Decision
The blood pressure tracker collects age, not date of birth. This is a deliberate data minimization decision. Age is useful context for a cardiovascular risk conversation, though it does not change the reference ranges themselves. The 2025 AHA/ACC guideline applies the same blood pressure categories to every adult regardless of age. Date of birth is more specific than necessary and creates a data point that, combined with other information, could be used to identify an individual.
The signup form collects first name, last name, age, and email. No date of birth, no address, no phone number (unless voluntarily provided in the clinical inquiry form). This is the minimum data needed to provide the educational service.
The Shareable Report Feature
The blood pressure tracker includes a feature that allows the educator to generate a shareable HTML report for a specific client. The report includes the trend chart, a summary of recent readings, and educational context.
The report is generated as a static HTML file with the chart data embedded as JSON. It can be shared via a secure link (time-limited, generated by a Supabase Edge Function) or downloaded as a file.
The report includes a prominent disclaimer: "This report is for educational purposes only. It does not constitute medical advice, diagnosis, or treatment. Consult your healthcare provider for clinical interpretation of these readings."
The Offline-First Architecture
The blood pressure log works offline. When a client logs a reading without an internet connection, the reading is stored in the browser's IndexedDB and synced to Supabase when the connection is restored. This is implemented as a Progressive Web App service worker.
The offline-first architecture is important for a daily logging feature. Clients check their blood pressure at home, often in the morning before they are fully engaged with their devices. If the app requires an internet connection to log a reading, the friction is high enough that many clients will skip it.
The Takeaway
The blood pressure tracker is a case study in building a clinically adjacent feature while staying firmly in educator territory. The data model enforces reasonable ranges. The chart uses educational reference points rather than diagnostic thresholds. The UI framing provides educational context rather than diagnostic labels. The shareable report includes a prominent disclaimer.
Every decision in the architecture was made with the question: does this look like education or does this look like clinical practice? The answer should always be education.