v1.39.1 — large accounts, restores in the background, and medications kept as a record
This release fixes medication history on the day a medication was added and gets large accounts through their nightly jobs, exports and restores. It also adds a procedure history and medications you keep as a record without logging doses.
All-time averages and counts are now correct. Since 1.37.19 the all-time figures could count some days twice, more of them the longer an account's history, because days that had aged past five years were read both from their stored daily summary and as raw readings. Every reading now counts once, so an all-time mean or count on an insights page or dashboard tile may change after the update.
Medication history no longer invents misses. If you added a medication at 4 pm and logged the 2 pm dose, "Last 90 days" called it off-schedule and listed a morning slot from before the medication existed. A day later that slot became a forgotten dose that broke your streak and counted as missed in the doctor report and the Coach. Now a dose counts for its own slot, and slots from before you added a medication appear only if you logged something for them. Adherence figures everywhere follow that rule, and the update puts misses already stamped that way back to pending. Thanks to @sreeramachandramurthy for the report and the screenshots (#1028).
A portable restore used to date every medication to the restore day, which dropped restored misses from your adherence rate. Backups from 1.39.1 on keep the real date; older ones get the earliest date the backup records for that medication.
Large accounts work again. On an account with more than a million readings, typical after years of Apple Health imports, the nightly clean-up and the backup failed with "job timed out". Both held everything in memory until the app ran out and restarted. The full export crashed it too, and the weekly backup could not be restored, although the admin page blamed decryption. The clean-up now works one day at a time and resumes where it stopped, and backups and exports are written piece by piece. On an account of 1.25 million readings in the standard 1 GB container, the nightly jobs finish in a few minutes, the export takes about 25 seconds, and a restore brings back exactly what the backup holds. An Apple Health import of 300,000 readings now needs 12 MB instead of 53. Thanks to @mills1975 for the report (#1031).
Keep a medication as a record. A new Track intake switch sits at the top of each medication's Schedule tab. With it off, the dose, the dates and the schedule stay stored and editable, but nothing is ever due: no reminders, no Taken and Skip, no place in any adherence figure. The list marks it "Record only". Switch it back on and tracking starts from that moment; the days it was off never count as missed. Thanks to @Cnote43 for asking in #1033.
Units per dose like 1½. One and a half tablets can now be saved: the medication form adds an Other field that reads 1.5, 1,5 or 1 1/2, and any value up to 100 with four decimal places works, so a measured dose like 0.8 mL does too. Thanks to @gesus14 (#1034).
A history of procedures and surgeries. A visit can now be a "Procedure or surgery", with a body site in your own words and an optional side. Checkups has a Procedures tab, searchable by body site, and the doctor report has a Surgical history section. Existing visits can be switched to it. Thanks to @Cnote43 for #1025.
Editing a vaccination dose removed its documents. Ever since documents could be linked to doses (1.37.3), a dose opened for editing did not know its linked documents, so saving any change to it, a batch number for example, quietly unlinked all of them. That was our bug, and documents now stay linked. Chips show their date and open the record on click; only the small x unlinks, with an undo. Thanks to @Cnote43 for writing up every step (#1024).
The cycle calendar marks intercourse with a small diamond, and a day with only a pregnancy or ovulation result, spotting, a temperature or a note shows a small ring instead of looking empty. Thanks to @Nazza01 for the report and the screenshot (#1032).
Readings from Home Assistant, Tasker and similar bridges are marked as external. Readings sent with the ingest token used to look typed by hand. They now carry an "External device" badge, can be filtered, and stay editable. A request that names a source is refused, because the server decides it from the token. Older readings stay manual. On a day with a typed and a bridged reading, daily totals count the typed one. Bridges can also send sleep stages by name (IN_BED, ASLEEP, AWAKE, CORE, DEEP, REM). Thanks to @Antiheld86 for the pull request (#892) and to @ocurero for #972.
If you run a server, take a database backup before upgrading. Migrations 0346, 0347, 0349 and 0351 only add things. 0350 repairs data: it returns misses wrongly stamped on slots before a medication's creation to pending. A restore now runs in the background, so a reverse proxy's 60-second timeout no longer shows an error halfway through; the backups page shows the step and the progress, even after a reload. If the server restarts before the data is written, the restore starts again once by itself. A failure after the data is written is never re-run: the data is restored and the charts catch up by the next night. Long jobs log their progress, and backup uploads take compressed files up to 512 MB.
For the iPhone app and API clients, everything is additive for 1.0.3 and 1.0.4. Only the admin restore route changes: it answers 202 with a jobId. The batch validation error carries meta.errorCode: "measurement.batch.invalid", a value_out_of_range entry includes convertedValue and range, upsert_failed in the nutrient and cycle uploads means "send it again", and /api/user/profile reports the time zone the server actually uses. Medications gain trackIntake, and unitsPerDose accepts any value above 0 and up to 100 with four decimal places (the app shows 1½ as 1 until its next version but never overwrites it). The shipped iPhone app stops reminding for a record-only medication, but a schedule change made there is not applied, so change it on the web for now.