A local-only health tracking application for patients navigating complex diagnostic journeys.
Built for people who need to see patterns in their own data when the medical system isn't connecting the dots yet.
(Well, built for one person who needed to see patterns, but she figured she couldn't be the only nut out there.)
Biotracking helps you:
- Track daily symptoms, biometrics, and environmental factors (including UV exposure, in fact especially UV exposure)
- Visualize correlations over time (does UV exposure predict your symptom flares? does low HRV precede bad days?)
- Generate clinical reports to bring to appointments (when you know damn well your brain is not going to remember everything, plus it has graphs!)
- Keep a longitudinal record of labs, medications, & clinical events, as well a list of your clinicians
- Run flare forecasting based on your own historical patterns
- Visualize trends pre/post medical interventions such as hydroxychloriquine or steroids or biologics or what have you.
- Keep all your data local -- nothing leaves your computer, if you don't want it to.
This is not a medical product. This is a tool for veracity: for people who need to make their invisible patterns visible.
It's easy to gaslight yourself into thinking you're having panic attacks and are lazy. And sometimes people have panic attacks and are lazy, and that's entirely normal.
But when the shortness of breath is uncoupled from emotion, when the "laziness" is less sloth and more that you're stuck in a quagmire of quicksand despite wanting to do so much -- there's something making your body react that way.
The sun was making me sick.
At least that was my intuition, but that seemed insane. I had low vitamin D for years and was told to get more sun. But like clockwork, high UV index days would leave me sick the next day, or two, or three. A sunburn put me in bed for a week with what felt like the flu.
I figured I was just getting older. Also I'm hella pale, maybe this was a white people thing no one had mentioned to me.
But coupled with a family history sprinkled with, and a genetic profile loaded for, SARDs and connective tissue disease associated alleles -- I decided to quantify it. It became painfully clear to me by the data, that unfortunatley, The sun is making me sick.
That's why I started a spreadsheet. But it was useless in clinic -- rows upon rows of entries with no succinct way to visually communicate what they meant in a 15-minute appointment ,while exhausted and in pain and anxious about being dismissed again. After 90+ days I gave up. I got depressed. I kept getting sick. My sick leave was running dry at work, and with out a diagnosis I didn't feel confident that I could get FMLA protection.
Then I picked it back up. I can't remember exactly what the impetus was -- probably another rheumatologist doubting me while ER doctors were writing "I believe her condition to be rheumatic in nature", meanwhile my dermatologist was doing her damnedest to get the best biopsy shave for DIF this side of the Mississippi. Damn near the size of a mercury dime.
Claude Sonnet helped me build it. I'm not a strong coder -- I can get around, and I know how to make infinity while loops, but I'm far from skilled. The LLM assisted me in building the stack, troubleshooting bugs, and providing the kind of cognitive support I could direct, debug, and reiterate. And if Claude can be annoyed, I most certainly annoyed that poor tireless machine.
Meanwhile, I was in and out of doctors appointments and a few ER visits, and eventually arrived at a shiny new "cool, I was right" / "fuck, why do I have to be right about this?" diagnosis. Eight months from when I started aggressively seeking treatment to confirmed diagnosis. I beat the odds -- the average diagnostic delay is four to seven years. I'm lucky. A lot of people aren't.
My current diagnosis is acute cutaneous lupus erythematosus with systemic involvement, confirmed by biopsy and with woefully unremarkable serology. But autoimmune disease evolves, & we are constantly learning new things about the human body. The differential will shift. The ICD codes may change. Whether we end up calling it lupus or the Hokey Pokey Disease, getting that process started -- having longitudinal evidence, having dates, having correlations -- matters enormously for health outcomes down the road.
This tool isn't a lupus tracker, necessarily, though it is designed around an evolving case of predictably photosensitive lupus. It's a you tracker, the intent is you can change it to fit your case. Whatever you've got going on.
- Symptom logging: Track 9 symptom categories with detailed notes (neurological, cognitive, musculature, migraine, pulmonary, dermatological, mucosal, rheumatic, gastrointestinal)
- Environmental factors: UV exposure (pulled from Open-Meteo and Visual Crossing), temperature, sleep quality
- Physical metrics: Steps, basal body temperature, pain/fatigue scales (1-10)
- Flare documentation: Mark flare days and track what actually happened
- Quick entry mode: Stripped-down form (
?mode=quick) showing only the fields that feed the prediction model — for days when filling a full form is too much
Enabled via track_cycle: true in setup. Designed for patients where steroids, biologics, or disease activity disrupt menstrual regularity.
- Month-grid calendar: Color-coded period flow (heavy/medium/light/spotting) with phase overlays
- BBT-anchored phase detection: Uses basal body temperature biphasic shift (rule of three: 3 consecutive days ≥ 0.1°F above follicular average) to detect actual ovulation rather than relying on fixed calendar math — critical when steroids compress or extend cycle length unpredictably
- Cycle phase overlays: Luteal and PMS windows calculated from detected ovulation, not assumed 14-day countdown
- BBT heat visualization: Per-day colored border on calendar cells indicating BBT elevation, colored SVG wave graph per month
- Flare/phase correlation: Patterns card showing flare distribution by cycle phase across all historical data
- Intervention effects on cycle: Before/after average cycle length for each medication intervention
- Apple Health import:
import_cycle.pyimports Menstrual Flow and Intermenstrual Bleeding records from Apple Health export CSV
- Timeline view: Multi-axis chart showing symptoms, sleep, temperature, and UV exposure over time
- UV lag analysis: Statistical analysis of UV exposure patterns and flare correlation with configurable lag periods (same-day, 24h, 48h, 72h)
- HRV tracking: Heart rate variability trends with intervention markers
- Intervention tracking: Mark primary and secondary medical interventions, visualize pre/post effects
- Transparent statistical model: See exactly how predictions are calculated
- Real-time risk assessment: Daily flare risk score (0-25) with color-coded risk levels
- 7-day trend visualization: Track risk patterns over the past week
- Contributing factors breakdown: See what's adding to your current risk score
- Personalized recommendations: Context-aware suggestions based on current risk level
- Interactive weight adjustment: Tune symptom weights using real-time sliders
- Live simulation: See how weight changes affect model accuracy, recall, and precision
- Prediction flip analysis: Identify which dates would change prediction with new weights
- Apply and revert: Save custom weights or reset to factory defaults
- Built-in manual: Complete documentation accessible via terminal interface (
?command) - Model transparency: View the actual Python calculation code in the app
- Accuracy analysis: Track model performance over 60/90/120/all day windows
- Confusion matrix: See true positives, false positives, true negatives, false negatives
- Performance metrics: Accuracy, recall (sensitivity), precision, F1 score
- Historical validation: Compare predictions against actual flare outcomes
- Weight optimization: Data-driven suggestions for improving model performance
- Lab results: Track test results with numeric values, qualitative results, reference ranges, and flags
- Medications: Full medication history with doses, frequencies, start/end dates, and intervention markers
- Clinical events: Document appointments, procedures, hospitalizations with provider and facility info
- Clinician directory: Maintain contact info for your care team (specialty, clinic, network, notes)
- ANA tracking: Specialized tracking for ANA titers, patterns, and screen results
- CSV export: Export labs, medications, events, or clinician data for external analysis or records requests
- Steroid taper wizard: Pre-filled 6-day Medrol dose pack schedule with adjustable times and doses; schedules push notifications for each dose via ntfy
- Dose checklist: Today's scheduled doses appear on the daily entry page with one-tap "mark taken" tracking
- Full-text search: Search across all daily entries, clinical notes, medications, and events
- Keyword shortcuts: Type "help", "manual", "lab", "cli" in search to access Forecast Lab
- Recent note reference: Access previous notes and events by keyword
- Quick filters: Jump to specific symptom categories or date ranges
- Local-first: All data stored in local SQLite database on your machine
- No cloud sync: Data never leaves your computer by default
- Optional passcode lock: Require a PIN to access the app — useful on shared networks, with roommates, or in any situation where you need your health data to stay private from people in your physical space. Enable by adding one line to
config.json. See Optional Passcode below. - Optional remote access: Raspberry Pi + Tailscale + Oracle Cloud setup for secure mobile access (see REMOTE_ACCESS.md)
- Version control safe: Comprehensive
.gitignoreprotects health data from accidental commits - Export control: You decide what data leaves your system and when
- UV auto-backfill: Automatically fetch historical UV data from Open-Meteo and Visual Crossing based on GPS coordinates
- Responsive design: Works on desktop and mobile browsers
- Dark mode: Easy on the eyes, just toggle the moon/sun in the header.
- Light mode: Good for when you can't make out dark mode.
If you want to peek at what it looks like see screenshots here.
This application is a data tracking and visualization tool only. It is not:
- A diagnostic tool
- Medical advice
- A replacement for professional medical care
- Approved, endorsed, or reviewed by any medical authority
Always consult qualified healthcare providers for medical decisions. This app helps you organize your own observations -- what you do with that information is between you and your clinicians.
- Your data never leaves your computer. No cloud storage, no third-party APIs for health data, no analytics, no tracking.
- UV data comes from public weather APIs (Open-Meteo and Visual Crossing) using only your coordinates —- no personal health information is transmitted.
- You own your data. The database is a standard SQLite file you can back up, export, or delete at any time.
- This is a single-user, local application. One instance per person, one database per instance.
- Do not use this application to track anyone's health data without their informed consent. Don't be creepy.
- macOS, Linux, or Windows (tested primarily on macOS and Linux... actually not tested on Windows. Sorry.)
- Python 3.9 or later (earlier veersions work, but watch your D's and d's)
- A web browser (Brave, Firefox, Safari, Edge, Opera, Tor...)
- Optional: iPhone with Apple Health for biometric import (I have an apple watch, because access to raw data for free and it's also a watch)
macOS/Linux: Python 3 is likely already installed. Open Terminal and check:
python3 --versionIf you see Python 3.9 or higher, you're good. If not, download from python.org.
Windows: Download Python from python.org and make sure to check "Add Python to PATH" during installation.
Option A: Download ZIP (easiest if you're not familiar with git)
- Go to the GitHub repository page
- Click the green Code button
- Click Download ZIP
- Unzip the file to a folder you can find (like
Documents/biotracking)
Option B: Clone with git
git clone https://github.com/alaricmoore/biotracking.git
cd biotrackingOpen Terminal (Mac/Linux) or Command Prompt (Windows), navigate to the biotracking folder, and run:
# Create a virtual environment (recommended)
python3 -m venv .venv
# Activate it
# Mac/Linux:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run first-time setup
python setup.pyThe setup script will ask you for:
- Your name (for reports)
- Location coordinates (for UV data — you can find these by Googling "my coordinates" or using latlong.net)
- Timezone (e.g.,
America/Chicago,America/New_York,Europe/London) - Baseline body temperature in Fahrenheit (your normal resting temp, usually around 97-99°F)
Important for coordinates: If you're in North America, your longitude should be negative. For example, Oklahoma City is
35.4676, -97.5164(note the minus sign on longitude). The setup script will warn you if you forget.
python app.pyYou should see:
biotracking
===========
Patient: Your Name
Starting server...
Local: http://localhost:5000
Phone: connect to same wifi, visit http://<your-ip>:5000
Open your browser and go to http://localhost:5000. Try adding today's entry to make sure everything works.
If you want to enter data from your phone while on the same WiFi network:
Find your computer's IP address:
- macOS: System Settings > Network > click your connection > look for IP Address
- Windows: Open Command Prompt, type
ipconfig, look for "IPv4 Address" - Linux: Run
hostname -I
Then on your phone (same WiFi network), open a browser and go to http://YOUR-IP-ADDRESS:5000.
Bookmark it for easy access.
Biotracking can import HRV, sleep hours, wrist temperature, and daylight exposure from Apple Health, or whatever else you are tracking. Which provides free-of-cost raw data downloads.
Export from Apple Health:
- Open the Health app on your iPhone
- Tap your profile picture in the top right
- Scroll down and tap Export All Health Data
- AirDrop the export to your Mac, or save to Files and transfer via iCloud
- The file is going to be huge, just a warning.
Recommended: Use the Health Export app (free tier is fine)
- Download Health Export from the App Store
- Select: Heart Rate Variability, Sleep Analysis, Apple Sleeping Wrist Temperature, Time in Daylight
- Set your date range, export as CSV daily average
- Transfer the CSV to your computer
- Also download Menstrual Cycle data if you're using cycle tracking — see below.
Import:
python import_apple_health.py path/to/your_export.csv
# Preview without writing:
python import_apple_health.py ~/Downloads/health_export.csv --dry-run
# Create new rows for dates that don't exist yet:
python import_apple_health.py ~/Downloads/health_export.csv --create-newIf you enabled cycle tracking during setup, import your cycle history from an Apple Health XML export:
- Export from Health app (see above)
- Use the Health Export app — select Menstrual Flow and Intermenstrual Bleeding, export as CSV
- Import:
# Preview first:
python import_cycle.py --csv your_cycle_export.csv --dry-run
# Import:
python import_cycle.py --csv your_cycle_export.csvFlow priority when multiple records exist for the same day: heavy > medium > light > spotting. Intermenstrual Bleeding is imported as spotting. Sexual Activity and Persistent Menstrual Bleeding records are skipped.
If you've been tracking in a spreadsheet, you can import it. Required column: Date (in YYYY-MM-DD, MM/DD/YYYY, or "Jul 22, 2025" format). Optional columns are mapped automatically for symptom flags, pain/fatigue scales, sleep hours, and notes.
python import_tracker.py path/to/your_tracker.csv --dry-run
python import_tracker.py path/to/your_tracker.csvDate,Test,Value,Units,Lab,Doctor
2021-04-16,C4,28,mg/dL,LabCorp,Dr. Smithpython import_labs.py path/to/labs.csv --dry-run
python import_labs.py path/to/labs.csvThe script auto-detects reference ranges and flags common tests (C3, C4, CRP, ESR, anti-dsDNA, etc.).
After importing historical data, fetch UV values for those dates:
python backfill_uv.pyYou'll need a free Visual Crossing API key. Add it to config.json:
"visual_crossing_key": "YOUR_KEY_HERE"The free tier allows 1000 records/day. Historical UV uses ~24 records per day, so you can backfill about 40 days for free. Beyond that, the metered plan is $0.0001/record.
- Open biotracking at
http://localhost:5000 - Click "Daily Entry" to log today's data
- Fill in symptoms, environmental factors, and notes
- Check "Flare occurred today" if applicable
- Submit to save
- Navigate to "Forecast" from the main menu
- View your current risk score and 7-day trend
- Review contributing factors and recommendations
- Click "View History" to see past predictions vs. actuals
- Click "Model Accuracy" to see performance metrics
- Go to forecast page and click the green
>>button (bottom-right)- Or search for "lab", "help", or "manual"
- Type
?for the user manual - Type
2to adjust symptom weights - Move sliders to customize weights
- Click "Run Simulation" to preview changes
- Review accuracy/recall/precision impact
- Click "Apply These Changes" to save (or "Reset to Defaults" to revert)
- Navigate to "Clinical" from the main menu
- Add lab results, medications, events, or clinician contacts
- Use the tabs to switch between record types
- Click "Export" to download CSV files for specific date ranges
- Edit or delete records using the action buttons
- Use the search bar in search tab
- Type any keyword to search across all entries
- Results are grouped by type (daily, labs, events, medications)
- Click any result to view full details
See REMOTE_ACCESS.md for detailed instructions on setting up remote access via Raspberry Pi + Tailscale.
Biotracking uses ntfy for two kinds of phone notifications:
- Medication dose reminders — fires at the scheduled time for each dose in your taper
- Proactive flare risk alerts — fires once daily (default 8am) when your weighted risk score crosses the moderate threshold (≥ 5.0) or when you're about to enter a PMS/luteal phase. The alert includes your score, top contributing factors, and current cycle phase if relevant. High-risk alerts (≥ 8.0) use higher priority and a different tag so they stand out.
ntfy is a dead-simple open-source notification service. No account required. The Pi sends an HTTP POST; your phone receives a push notification. That's it.
- Install the ntfy app on your phone (App Store or Google Play, free, by Philipp Heckel)
- Open the app and tap Subscribe
- Enter a topic name — make it long and unguessable, like
biotracking-k7x9qm3p(ntfy topics are public: anyone who knows the name can read and send to it, so don't use your name, your pet's name, or anything else obvious) - Add two keys to your
config.jsonon the machine running biotracking:
"ntfy_topic": "biotracking-k7x9qm3p",
"ntfy_server": "https://ntfy.sh"- Test it from your terminal before trusting your medication schedule to it:
curl -d "test notification" https://ntfy.sh/biotracking-k7x9qm3pYour phone should buzz within a few seconds. If it doesn't, check that the topic name matches exactly and that notifications are enabled for the ntfy app in your phone's settings.
- Go to Clinical → Medications tab
- Add your steroid (e.g. methylprednisolone 4mg)
- Click set reminders on that medication's row
- The wizard pre-fills a standard 6-day Medrol dose pack schedule (18 doses, tapering from 6 tablets on day 1 to 1 tablet on day 6). Adjust the start date, times, and amounts as needed.
- Click activate reminders — doses are saved and notifications will fire at the scheduled times as long as the app is running
- Today's pending doses appear in a checklist on the Daily Entry page. Mark them taken as you go.
The flare risk alert fires at 8am by default. To change the hour, add this to your config.json:
"flare_alert_hour": 7Then restart the app. The scheduler will pick it up. The alert rate-limits itself to once per calendar day — if risk drops below threshold later in the day, no second alert fires. If it fires and you want to reset it manually (e.g. to test), delete config/flare_alert_state.json and restart.
To disable flare alerts entirely without removing ntfy, just don't add flare_alert_hour — it won't suppress them. Instead, you can set ntfy_topic to an empty string in config.json, which disables all notifications.
- Notifications only fire if the app is running. If you're on the Raspberry Pi setup described in
REMOTE_ACCESS.md, the service runs continuously and this works reliably. - Running locally on a Mac that sleeps? The scheduler pauses when the machine sleeps and resumes when it wakes. You may miss a dose notification or morning alert if the lid was closed.
- ntfy.sh is a public service run by one person. For higher reliability or privacy, you can self-host ntfy — change
ntfy_serverinconfig.jsonto your self-hosted URL. - The taper wizard defaults to a standard Medrol 4mg dose pack. For other tapers, adjust the times and quantities in place or clear them and enter your own schedule.
Health data can be sensitive in ways that go beyond the abstract. If you share a living space, use your laptop in shared areas, or are in any situation where you need your data visible only to you, the optional passcode adds a simple lock screen to the app.
To enable:
Open config.json (in your biotracking folder) in any text editor and add one line:
"passcode": "yourpin"For example, if your config currently ends with:
"debug": false,
"secret_key": "abc123..."
}Make it:
"debug": false,
"secret_key": "abc123...",
"passcode": "yourpin"
}Restart the app. From now on, anyone visiting the app URL will see a passcode prompt before they can access any data.
A lock button will appear in the navigation bar. Clicking it ends your session immediately.
To disable: remove the "passcode" line from config.json and restart.
Notes:
- The passcode can be any string — a word, a number, a phrase. It's stored in your local
config.jsonfile, which is already gitignored and never committed to GitHub. - This is a "lock the door" measure, not a cryptographic security system. It protects against casual access (someone picking up your laptop, a roommate, a family member) on a trusted home network. It is not a substitute for full-disk encryption if your threat model involves physical device seizure.
- If you forget your passcode, open
config.jsonin a text editor and either read it there or remove the line. - Sessions expire when you close the browser tab or click lock. There is no persistent "remember me."
"Port 5000 is already in use" (common on macOS which uses 5000 for AirPlay)
Edit app.py and change port=5000 to port=5001, then visit http://localhost:5001.
UV data shows all zeros
Check your longitude sign. North America longitudes should be negative (e.g., Oklahoma City: 35.4676, -97.5164). Edit config.json and run python backfill_uv.py --force.
Can't access from phone
Make sure phone and computer are on the same WiFi. Verify the app is running. Try http:// not https://. Check there's no firewall blocking port 5000.
"No module named 'pandas'"
You're not in the virtual environment. Run source .venv/bin/activate (Mac/Linux) or .venv\Scripts\activate (Windows) first.
Your data lives in two files:
biotracking.db— the SQLite databaseconfig.json— your settings and API keys
Back them up:
cp biotracking.db biotracking_backup_$(date +%Y%m%d).dbExport options:
- In-app: export buttons for labs, medications, events, clinician list (CSV)
- In-app UI delete function on search page
- DB Browser for SQLite (GUI tool, free)
- Command line:
sqlite3 biotracking.db .dump > backup.sql
Reset everything:
rm biotracking.db config.json
python setup.pyThis deletes all your data. Back up first.
The flare prediction model is a transparent, statistical approach based on weighted symptom scoring. You can see exactly how it works and modify all you want.
Each day receives a score (0-25) based on:
- Symptoms (weighted 0.25-2.0 based on severity and flare correlation)
- UV exposure (exponential weighting by UV Index score, 24-hour lag has shown strongest correlation)
- Physical overexertion (steps per hour slept ratio)
- Temperature elevation (basal body temperature delta)
- Fatigue and pain scales
- Emotional state
Threshold: Score ≥ 8.0 = flare risk
Adjusted based on accuracy analysis of 60 days of data:
- Neurological: 1.5 (appeared in 51 missed flares)
- Cognitive: 1.0 (appeared in 34 missed flares)
- Musculature: 1.5 (appeared in 44 missed flares)
- Migraine: 1.0
- Pulmonary: 1.0
- Dermatological: 0.75
- Mucosal: 0.25
- Rheumatic: 0.5 (base), 2.0 (major joints), 1.0 (minor joints)
- Cycle phase (PMS/Luteal): 1.0 — only active when
track_cycle: true
The cycle phase weight was added after observing that across 11 cycles of real data (69 total flares), PMS and luteal phases carried roughly double the flare rate of other phases: PMS 38%, Luteal 39% vs. Follicular 19%, Period 19%. Adding the default +1.0 weight for these phases improved recall from 36.7% to 45.5% and reduced false positives from 20% to 16.7%. The weight is adjustable in the Forecast Lab like all others, and has no effect if cycle tracking is disabled.
Current model accuracy: 85.8% overall
- Recall: 45.5% with cycle phase weighting (was 36.7% without)
- Precision: 79.2% (4/5 predictions are correct)
- False positives: 16.7% (was 20% before cycle phase weighting)
- Improved from initial 76% accuracy / 20.9% recall
Use the Forecast Lab (/forecast/lab) to:
- Adjust weights based on your personal patterns
- Run simulations to see impact on accuracy
- Apply changes or reset to defaults
- View the actual Python calculation code inside the app
This project welcomes contributions, especially from people with lived experience of diagnostic complexity. Whether as patients, clinicians, loved ones, or those for whom this is their special interest.
Areas where help is needed:
- Additional data import formats (Fitbit, Garmin, etc.)
- More correlation analysis methods
- PDF export improvements
- Accessibility improvements
- Documentation and tutorials
- Translations
- New designs to include other evolving hard-to-diagnose disease that isn't my flavor of lupus.
Please open an issue before starting work on a major feature.
Also reach out to me at alaric.moore@pm.me
biotracking/
├── app.py # Flask routes only
├── db.py # All database operations
├── uv_fetcher.py # UV API integration
├── setup.py # First-run configuration
├── requirements.txt # Python dependencies
├── .gitignore # Keeps sensitive data out of git
├── config.json # User settings (gitignored)
├── import_labs.py
├── import_tracker.py
├── import_apple_health.py
├── import_cycle.py # Apple Health menstrual cycle CSV import
├── migrate_symptoms.py
├── backfill_uv.py
├── biotracking.db # SQLite database (gitignored)
├── config/
│ ├── custom_weights.json # Forecast Lab overrides (gitignored)
│ └── flare_alert_state.json # Daily alert rate-limit state (gitignored)
├── templates/ # HTML templates
│ ├── base.html
│ ├── daily_entry.html
│ ├── timeline.html
│ ├── uv_lag.html
│ ├── hrv.html
│ ├── cycle.html
│ ├── forecast_history.html
│ ├── forecast_accuracy.html
│ ├── forecast_lab.html
│ ├── forecast.html
│ ├── daily_confirm.html
│ ├── clinical_record.html
│ ├── search.html
│ ├── report.html
│ └── login.html
└── import_*.py # Data import scripts
Patients are the experts on their own bodies. You know when something is wrong, even when tests are "normal." You also probably, for the most part, know the difference between normal and "oh no this is no good now." Trust that instinct.
Correlation is worth investigating, even when causation isn't proven. If UV exposure consistently precedes your symptoms, that pattern matters -- regardless of whether a doctor believes you yet. Or hell, you don't believe you yet.
Your data is yours. No surveillance, no selling, no cloud lock-in. You can delete everything and walk away at any time.
Invisible illness deserves visible evidence. When your symptoms are dismissed as anxiety or "borderline," a longitudinal graph can shift the conversation.
Diagnostic complexity is real. Some conditions take years to name. The average diagnostic delay for lupus alone is four to seven years, and it isn't even a particularly rare disease, merely uncommon. Tools like this exist to help you survive that journey and shorten it where and when possible.
Built by C. Alaric Moore, a USPS technician and mechanic and patient who got tired of being told her labs were normal.
Assisted by Claude Sonnet (Anthropic) for development support, h/t to Github's copilot for closing parentheses and other surprisningly convenient features.
Inspired by every patient who was told "your labs are fine" when they knew something was deeply wrong. Dedicated to the ones still waiting for someone to believe them.
Also inspired by the rheumatologist who fired me for being right about a lab interpretation. I might be sick, but I'm still a stubborn Okie.
GNU Affero General Public License v3.0 (AGPL-3.0)
This software is free for individuals and non-profits with attribution. Commercial entities wishing to use, modify, or deploy this software must obtain a separate commercial license.
The AGPL-3.0 requires that if you modify and deploy this software (including as a web service), you must make your modified source code available under the same license.
See the LICENSE file for full terms. For commercial licensing inquiries, contact the author.
For bugs, feature requests, or questions, open an issue on GitHub. Check existing issues first -- your question might already be answered.
This is currently a one-person project built between doctor appointments and fixing machines and building terrariums. Response times may vary.
Take care of yourself. Trust your observations. Keep asking questions.