Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
546b9b2
feat(cycle): choose how the calendar feed draws a forecast (#1350)
Nov 9, 2026
d53eb1e
test: show why a pre-migration dump failed in the retention test
Nov 10, 2026
2dfcadb
feat(mental-health): crisis contacts for South Korea
Nov 10, 2026
157809c
fix(labs): drop a lab's calculated-value note from the unit (#1313)
Nov 10, 2026
928ade5
feat(labs): let a person order the lab categories (#1349)
Nov 10, 2026
6fb0d18
fix(sync): hold a drained cursor a minute back so late commits arrive
Nov 10, 2026
befbace
fix(cycle): keep a feed turned off during a rotation off
Nov 10, 2026
89c8503
Merge remote-tracking branch 'origin/main' into feat/cycle-feed-forec…
Nov 10, 2026
f75337e
feat(measurements): record blood ketones and show the glucose-ketone …
Nov 10, 2026
62f4578
Merge branch 'feat/v1472-ketones' into feat/cycle-feed-forecast-style
Nov 10, 2026
c62abad
fix(sync): give every drained domain a fresh watermark two minutes back
Nov 10, 2026
c14cc9a
fix(cycle): turning the feed off wins against a rotation in either order
Nov 10, 2026
69ba8be
fix(measurements): read the GKI's glucose from the ketone side
Nov 10, 2026
4dcb041
fix(labs): review a unit that was only a calc note, keep unseen categ…
Nov 10, 2026
d110f04
chore(bundle): baseline the ketones page
Nov 10, 2026
b4ac67e
feat(labs): add biomarker filtering and sorting
ferges123 Nov 10, 2026
ea3fcce
fix(checkups): keep a missed rolling reminder due until it is measured
Nov 10, 2026
a486c3c
Merge remote-tracking branch 'origin/release/v1.47.2' into takeover/1370
Nov 10, 2026
2f4da62
refactor(labs): drop the sort pill from the filter rail
Nov 10, 2026
b3e2226
revert(labs): keep the shared list-preference precedence unchanged
Nov 10, 2026
2e2a0ac
fix(labs): keep groups with a match open while filtering
Nov 10, 2026
82ad1e2
fix(labs): call the date filter "Last measured"
Nov 10, 2026
fbbcaf4
docs(api): keep the labs category status rule in the contract
Nov 10, 2026
2c63bf7
chore(labs): tidy the filter rail follow-ups
Nov 10, 2026
04a4353
fix(labs): put the search field beside the filter rail, not in it
Nov 10, 2026
bcf411f
chore(deps): move node-forge to 1.4.3
Nov 10, 2026
7446418
fix(labs): keep what is typed in the search field when the URL catche…
Nov 10, 2026
a40c9e4
fix(labs): keep keyboard focus where it belongs around the search field
Nov 10, 2026
cc9cbc4
fix(labs): read odd filter links kindly and match names without accents
Nov 10, 2026
142307a
fix(i18n): put the Korean biomarker count after the noun
Nov 10, 2026
c59f4d7
docs(changelog): describe the labs search and filters
Nov 10, 2026
ba3ee96
style(labs): format the filter rail files
Nov 10, 2026
f20efca
Merge PR #1370: biomarker filtering and search in the labs list
Nov 10, 2026
f521cdb
docs(changelog): correct the checkup repeat wording and note the zlib…
Nov 10, 2026
6c8458d
fix(reminders): keep a course window's end through every reschedule
Nov 10, 2026
c8b32cc
fix(documents): judge the review flag on the unit as stored
Nov 10, 2026
5ebfac1
fix(gki): build the index from the glucose shown beside it
Nov 10, 2026
a7e98b9
fix(cycle): audit the feeds a revoke actually turned off
Nov 10, 2026
128cf55
fix(day): fit the GKI tile's pair line in its column
Nov 10, 2026
ee1eb92
fix(ui): announce a filter bar's result count
Nov 10, 2026
b4a5442
fix(labs): leave "/" to the browser when no search field is on screen
Nov 10, 2026
0b3c013
fix(i18n): name the period in the forecast style hints
Nov 10, 2026
35b4e75
refactor(reminders): share the satisfiable select with the Telegram b…
Nov 10, 2026
8aa8379
fix(gki): draw the index chart in a chart token
Nov 10, 2026
8b607ab
test: drive the revoke race against Postgres and type the new fixtures
Nov 11, 2026
3745a02
test(gki): check the chart's series colour without a browser
Nov 11, 2026
13fd7ed
docs(changelog): do not promise a unit change on a (calc) marker
Nov 11, 2026
a1cfb57
test(browser): wait for the file's own iframe before the first command
Nov 11, 2026
9ef3331
test(pwa): give the sw-version script tests time to start node
Nov 11, 2026
0a0df49
chore(release): v1.47.2
Nov 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,138 @@

## [Unreleased]

## [1.47.2] — 2026-11-11

### Added

- **Search and filter the labs list.** Once the list ran past a
screenful, finding one marker meant scrolling. The labs page now has a
search field (press / to jump to it) that matches a marker's name or
panel, and filters for the newest reading's status (out of range, in
range, below or above), the category, and when a marker was last
measured. While a filter is active every category with a match is
open, and its header counts only the matches. The filters are part of
the page address, so a filtered view survives a reload and
back/forward and can be shared as a link. The list keeps the sort
order set under Settings > Arrangement > Labs. (#1370)
- **Choose how the calendar subscription draws a forecast.** A logged
period of a few days next to a forecast spanning more than a week was
hard to read, because the forecast event covered every day the period
might fall on. The calendar subscription card now offers three styles
under "How forecasts look": just the expected days; the expected days
with the days the period may start earlier or run on later as separate
"possible" events (an open dot in discreet mode); or the single event
covering the whole range, as before. A subscription turned on from now
on starts with the expected days and their margin; one that is already
on keeps the single range until you change it, and rotating the link
keeps whichever style it has. `PATCH /api/cycle/feed-subscription`
accepts `forecastStyle` (`EXACT`, `MARGIN` or `BAND`) and the status
carries it. Migration `0495_cycle_feed_forecast_style`. (#1350)
- **Crisis contacts for South Korea.** A questionnaire answer that shows
the crisis card now gives a Korean reader, or anyone whose locale names
South Korea, the emergency number 119 and the national suicide
prevention line 109, which answers around the clock. Before, Korean
fell through to the international set with 112, which reaches the
police there, not an ambulance.
- **Set the order of the lab categories.** With the labs list grouped
by category you could reorder the markers but not the categories, and
nothing said how they were ordered. Settings > Arrangement > Labs now
has a "Category order" card while categories are on: move a category
with the handle or the arrows, and the card explains the default
(built-in categories in a fixed order, your own panels alphabetically,
Other last). A category that turns up later joins the end of your
order, and Other stays last if you left it there. The order is saved
with your account and applied by the server, so every device that
groups the list shows the same order. The labs list layout accepts
`categoryOrder`, and
`GET /api/labs/overview` answers `categories` in that order. (#1349)
- **Blood ketones, and the glucose-ketone index worked out for you.**
Ketones (beta-hydroxybutyrate, mmol/L) are a measurement of their own
now, so a ketogenic diet no longer has to live in a custom metric with
the index typed in by hand beside it. Choose "Blood ketones" when you
add a measurement and, if the meter gave one, type the glucose from the
same fingerstick into the field below: both readings are saved together
with one time, or neither is. The glucose-ketone index is glucose in
mmol/L divided by ketones, for every ketone reading above zero, taken
from the glucose reading at the same time or, failing that, the nearest
one within 15 minutes. It is never stored, so it
follows any reading you edit or delete. It shows under the chart on the
new Ketones page, in the day view, and beside the ketones in the doctor
report and the clinician share; the FHIR export carries the ketone
readings under LOINC 104816-4. Values are shown as recorded, with no
band and no verdict. `GET /api/measurements/series` takes
`kind=ketones` and `kind=glucoseKetoneIndex`, and `GET /api/day/{date}`
carries `glucoseKetoneIndex`. Migration `0496_blood_ketones`. (#1367)

### Fixed

- **A missed "every N days" checkup now stays due until it is measured.**
A checkup on a cycle of a week or less, such as blood pressure every
two days, moved its next due date on by its cycle the moment its
reminder went out, measured or not. The card then read "in 2 days"
every evening and never "today" or "overdue", and the start page
dropped it. Such a checkup now counts from its last reading: once its
reminder is sent it stays due, then overdue, until a reading lands or
it is marked done, skipped or snoozed, and while it stays open it is
reminded again every N days, and never more than a week apart, at its
usual hour. A first due date in the past stays overdue past its first
reminder instead of jumping ahead. A checkup that already moved on
corrects itself at its next reminder.
Calendar schedules that repeat within a week, such as a twice-daily
measurement course, still move on to their next time. (#1369)
- **A lab's "(calc)" note no longer becomes part of the unit.** Some
reports print "(calc)" beside a calculated value, and a document read
could copy it into the unit, so a marker was created in "g/dL (calc)"
or just "(calc)" and the next report's plain "g/dL" was refused as a
different unit. The read now drops that note (also "calculated",
"computed" and the German "berechnet"), a marker already saved in
"g/dL (calc)" accepts the plain "g/dL", and a unit that was only the
note counts as no unit and goes to review, so a person decides whether
the value really has none. A marker already saved in just "(calc)"
keeps that unit. Any other text in brackets still counts as part of
the unit. (#1313)
- **The sync feed no longer loses a reading written during a long
import, and no longer starts over for a quiet account.** A Garmin or
Withings import writes a batch in one transaction and stamps its
readings before it commits them. When a reading logged by hand
committed in between and the app synced right then, the feed's position
moved past the import's readings, and they never reached the app or
Apple Health. Separately, a kind of data that had not changed for more
than 75 days (mood, say, for someone who stopped logging it) kept its
old position in the feed, and from then on every sync was answered as
expired and the app started over from scratch, each time. Now every
kind of data that `GET /api/sync/changes` has fully caught up takes a
position two minutes behind the present, like `start=now` (which moves
from one minute to two): what changed in those two minutes is read
once more, so anything that committed late still arrives, and a quiet
kind of data never ages out.
- **Changing the calendar subscription while its link is being renewed.**
A subscription turned off at the same moment its link was renewed could
come back under the new link, and an option changed at that moment
could be lost to the new link. Turning it off now wins whichever comes
first, and the change lands on the link that stays live.
- **A seven-day blood pressure course now ends after seven days.** A
course suggested by the Coach knew its last day only until its first
reminder went out. From then on every sent reminder, every reading and
every skip planned the next one without that end, so the morning and
evening reminders went on for good. The end now holds through every
reschedule, and once the last slot is past the course is cleared from
the list as intended. A course that already ran past its end sends the
one reminder it has planned and then stops.

### Security

- `node-forge` moves to 1.4.3, which fixes five advisories in certificate
chain checks, signatures and TLS handling. It arrives only under the APNs
library, and HealthLog signs push requests with a token key, so none of
that code runs; the update keeps the dependency audit clean.
- The image carries Debian's zlib security update (DSA-6613-1, zlib1g
`1:1.3.dfsg+really1.3.1-1+deb13u1`), which fixes CVE-2026-85091,
CVE-2026-27171 and CVE-2026-76844. The 1.47.1 image was built before
that update and ships the earlier zlib. The refreshed `node:22-trixie-slim`
base does not include it yet either; the build-time `apt-get upgrade`
brings it in.

## [1.47.1] — 2026-11-07

### Added
Expand Down
1 change: 1 addition & 0 deletions bundle-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"/insights/headphone-audio/page": 336,
"/insights/health-score/page": 315,
"/insights/hrv/page": 337,
"/insights/ketones/page": 339,
"/insights/lean-body-mass/page": 336,
"/insights/medications/page": 338,
"/insights/mood/page": 337,
Expand Down
Loading
Loading