Repository navigation
release: v1.47.2 - #1365
Merged
Merged
release: v1.47.2#1365
Conversation
A forecast period was one all-day event over every day it might fall on, so a period of a few days showed up as a week-long estimate next to the logged ones. Each feed now carries a forecast style: - EXACT: the calculated period only, from the most likely start for the predicted number of bleeding days. - MARGIN: that event, plus separate "possible" events for the days it may start earlier and the days it may still run on, each only where the band reaches that side. Discreet titles use an open dot for them. - BAND: the single range, unchanged. Migration 0495 adds the column with BAND as its default, so every live feed keeps the events it serves. A feed turned on from now on starts on MARGIN, set by the mint route. PATCH changes it, rotate copies it, the status and the audit diff carry it, and the settings card offers it with a one-line explanation of the chosen style. The horizon and its stop rule are the same in every style, and the period event keeps its UID across styles so a calendar updates it in place.
Korean, and any locale naming the region kr, resolves to 119 and the national suicide prevention line 109 instead of the international set.
A read that copied "(calc)" into the unit minted a marker in "g/dL (calc)" that refused the next report's "g/dL". The note is dropped at the read and ignored in the unit comparison; any other bracket still counts.
The labs list layout gains categoryOrder, a bounded allow-list of category keys (200 entries, 64 characters each, deduplicated, malformed values dropped on read). GET /api/labs/overview reads the caller's own layout and answers categories already in that order, so every client renders them as given. Listed categories come first; keys the data does not have are ignored; a category the order does not name follows in the default order (catalog panels, then the person's own by label, then other). Other left at the end of the order stays last, behind any category added later; moved anywhere else, it stays there. Settings > Arrangement > Labs shows a category order card while categories are on. It lists the overview's categories under their localised labels, sends the whole order after every move, moves the cached overview at once and refetches it. The card says how the default order works. The OpenAPI document carries the new field.
A page's watermark is its last row's stamp, and a long import stamps its rows before it commits them: a quick write committing in between carried the watermark past them, and the keyset never returned them. A caught-up page now hands out watermarks at most a minute before serverNow in every row domain, as start=now does, so the next pull reads that minute again. The mirror domain keeps its watermark.
Rotation revoked the feed it had read without checking it was still live, so a turn-off in between came back under the new link, and it copied options read before a concurrent change. The revoke is guarded and the options are read after it; PATCH writes only to the live feed and follows a rotation to its successor.
…index (#1367) Ketones had to live in a custom metric, with the glucose-ketone index typed in by hand beside it, where it drifted from the readings it came from. - Type: BLOOD_KETONES (beta-hydroxybutyrate, mmol/L, migration 0496), plausible from 0 to 10: the blood ketone meters read 0.0 to 8.0 and print HI above it, and a venous value off a lab sheet fits under 10. Zero is a real reading. No band, no direction, no personal record, off the Coach snapshot and the correlations; readable over MCP and owned by the glucose module like glucose. - Entry: choosing blood ketones in the measurement form also takes the glucose from the same fingerstick, in the account's glucose unit. Both rows go through the array arm of POST /api/measurements with one timestamp, so they land in one transaction or not at all. - Index: glucose (mg/dL / 18.0182, the tree's one factor) over ketones, computed at read time and never stored. Each ketone reading above zero pairs with the glucose reading at the same instant, else the nearest one within 15 minutes either side; a tie goes to the same source, then to the earlier reading. Nothing pairs across a wider gap. - Surfaces: GET /api/measurements/series takes kind=ketones and kind=glucoseKetoneIndex (each point names the paired readings), and the day carries glucoseKetoneIndex when both reading types are visible. The new Ketones page charts the readings with the index beneath; the day view shows the index beside the value tiles; the doctor report, its PDF and the clinician share print it in the glucose group when both leaves are chosen, since beside the ketones it gives the glucose back. - FHIR: ketone readings export under LOINC 104816-4 (Beta hydroxybutyrate [Moles/volume] in Blood). The index is left out: it has no LOINC term, and both readings it is built from are in the bundle. - The measurement form's action row moved into its own component to keep the form inside its size budget. OpenAPI regenerated; all ten locales; the import unit table lists the type.
# Conflicts: # CHANGELOG.md
A domain with no new rows kept its last row's stamp, so once that was older than the tombstone horizon every pull answered cursorExpired and the client resynced from scratch on every pull. A domain whose page runs dry now takes serverNow minus the overlap on every page where its watermark has not passed that line, and on the last page every row domain does, raising a quiet domain and holding back one that delivered rows in the stretch. A domain drained early in a long walk is covered as well. The overlap grows from 60 to 120 seconds, above the 60-second timeout of the longest transactions that write served rows.
DELETE revoked the one feed it had read, so a rotation committing while it waited left the successor live behind a 200. It now revokes every live feed of the record in two passes. A rotation that loses to a turn-off answers 404 cycle.feed.none instead of 409; PATCH documents its 409. The in-repo feed guide describes the three forecast styles.
The correlated EXISTS over a time range had no equality to drive it from the ketones, so a person with years of sensor glucose walked every glucose row in the window. Each ketone reading now reads its glucose through a LATERAL index range. A full tie between two glucose readings resolves by id, the day tile names the unit, and the empty text says a ketone reading above zero.
…ory places A document unit that held only "(calc)" read as no unit and went straight to the record; it now goes to review. Saving a category order keeps the saved keys not on screen after the shown ones. The changelog says what each fix does and no more.
A rolling reminder ("every N days") is anchored on its last reading, but
the reminder tick rolled any cycle of a week or less on after a delivered
reminder, re-anchoring it on the send. A missed every-two-days blood
pressure reading therefore moved two days ahead each evening, read "in 2
days" on the card, and never showed as today or overdue.
A rolling reminder now stays due after its reminder, whatever its
interval, until a reading lands or it is done, skipped or snoozed. While
it stays open the repeat follows its interval, capped at a week, still in
its notify hour and under the per-day claim. Calendar rules that recur
within a week (a twice-daily course) keep rolling on; appointments are
unchanged.
holdsOpenAfterReminder stays the one definition for the tick and the
edit route. The daily digest asks the narrower question underneath it,
hasLongCycle, so a short rhythm still waits for its time of day on the
start page and is not pinned under the rail cap.
Refs #1369
# Conflicts: # CHANGELOG.md # src/lib/module-list-prefs.ts
Settings > Labs already holds the list's sort order. The pill added a second, URL-only one that was lost on the next visit, and Reset cleared it while the rail counted it as no filter at all. The list now sorts the way Settings says, and a ?sort param is ignored.
The saved-entry check and the reordered legacy precedence in useModuleListPrefs reach the illness and checkup lists as well, and the filter rail does not need them now that the sort pill is gone. The hook is back to what the release line ships; the precedence question can be raised on its own.
With groups opening only when flagged, the open state was worked out from the filtered rows. Filtering to in-range markers, or searching for an unremarkable one, closed the header while the counter reported matches. A group's default now follows the server's status for the whole category again, and while any filter is active every group with a match is open. A group closed by hand during filtering stays closed while the filter changes, is not stored, and the saved state returns once the filter is cleared.
The filter compares only the day of a marker's newest reading, so a marker measured inside the range and again later drops out. "Date range" promised more than that. The pill now reads "Last measured" in every locale, and the from/to semantics are written down where the filter is defined.
The description of a labs category lost the status rule and the sentence that a client never rebuilds the category, the order or the status. Both are back as they were, with one line added: a client that shows only the members matching a filter may summarise that subset by the same rule.
Drop a local-only ignore line, end the search placeholder with the ellipsis character the other placeholders use, and put the UrlFilterSyncOptions interface above the hook's doc comment so that comment documents the hook.
Inside the rail, the full-width search field wrapped on phones and left the filter icon alone on a line above it, and the shared FilterBar grew a class override and a second layout rule to make room. The search field now sits next to the unchanged rail: above it on phones, where the pills keep the usual scroll row, and in one line with it from sm up. FilterBar and docs/ui-guidelines.md are back as they were, so the filter-bar grammar stays the one ui-standards.md defers to.
The override in pnpm-workspace.yaml now floors node-forge at 1.4.3, which clears the five advisories against 1.4.2 and leaves pnpm audit --prod clean. It arrives only under @parse/node-apn, which pins 1.4.2 exactly; the APNs sender uses token auth, so the certificate path never runs.
…s up The labs search writes its trimmed query to the URL after a short pause, and every change of the URL query replaced the field's text. The field's own write came back as well: a trailing space vanished, so "vitamin " followed by "d" searched for "vitamind", and a letter typed while the write landed was lost. A query the field wrote itself now leaves the field alone; one from back/forward, a link or Reset still replaces it.
Clearing the search with its button removed the button under the focus and dropped focus onto the page; it now stays in the field. The / shortcut no longer pulls focus out of an open dialog, menu or list, and ignores a key another handler already took or one typed while an input method is composing.
A link with the date bounds reversed showed an empty list; it now reads as the range it means. The search ignores accents as well as case, so "hamoglobin" finds "Hämoglobin". The category pill only appears when there are categories to choose between, or when a link already filters by the only one, so the filter can still be cleared where it shows.
"바이오마커 {count}개" reads as a count of biomarkers; the counter
before the noun read like a fragment.
added 20 commits
November 11, 2026 00:18
The first due slot of a Coach course honoured endsOn, but the tick's roll-on, satisfy and skip all built their schedule input without it, so a seven-day twice-daily course kept rolling on indefinitely and never reached the null nextDueAt the expired-course cleanup waits for. Carry endsOn on RollableReminder and SatisfiableReminder and select it wherever a caller narrows the row.
A "1 (calc)" unit is stored as "1", the explicit no-unit value, but the dimensionless check ran on the raw string and missed it, so the read went straight through instead of to review.
A reading entered in mmol/L is stored as whole mg/dL, and the index divided the unrounded conversion, so a 5.2 / 0.3 pair printed beside a 17.4 rather than 17.3. Round the glucose to the decimal it is shown with first and divide that. The tiles also printed a two-decimal ketone reading to one decimal; show it as recorded.
DELETE audited the feed it read before its two revoke passes. When a rotation committed in between, that feed was already revoked by the rotation and the second pass revoked its successor, so the trail showed the old feed revoked twice and the new one never. Read back the rows carrying this request's revokedAt stamp and audit each.
The single-reading line spelled out both readings with their names and units and was cut off after the glucose in every layout. Show the two numbers with one unit, which fits the tile, and keep the worded pair for assistive tech.
The count beside every filter bar was a plain span, so a screen reader heard nothing while a list narrowed, only the empty state once nothing was left. Make it a polite status region.
The shortcut called preventDefault before checking for the field, so on a labs or documents page still loading, in error, or with nothing recorded, "/" did nothing and the browser lost its own use of the key.
Only the selected style's hint is shown, so "it may start" and "they may fall" had no noun on screen to point back to. Name the period in every locale that left it implied, and put the Korean hints in the same register as the rest of the card.
…utton The select is checked against SatisfiableReminder, so a column the reschedule needs cannot be left out of a narrowed read again, and the handler is back under its size baseline.
The custom metric chart drew its line in --primary, which put the index in the action colour right under the ketone series drawn in a chart token. Give the chart an optional series colour, default primary so a custom metric looks as before, and draw the index in --chart-4.
The revoke audit is now asserted in the integration race test where a rotation commits while the turn-off waits, instead of a route test that mocked the handler and the client. The other new tests type their fixtures rather than casting them away.
In the full run the browser version made a neighbouring browser file fail with a detached frame, while each passed alone. Render the chart in Node with Recharts stubbed, as the coach result chart tests do.
Every browser test iframe is named "vitest-iframe" and the Playwright provider looks the frame up by that name. Once a page runs a second file, the first file's iframe can still be found until its detach event arrives, so the second file's first click lands in a frame that is going away and fails with "Frame was detached". With fifteen browser files and at most twelve pages, three pages now run two files each, and a full local run failed this way in four of five tries. The setup now waits until the frame found by name is its own.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Patch release v1.47.2.
Added
categoryOrderon the labs list layout (Add Categories to Bio Markers #1349)forecastStyleEXACT / MARGIN / BAND, migration 0495 (Menstrual Cycle data and forecast as ics #1350)BLOOD_KETONESmeasurement type and read-time glucose-ketone index,/insights/ketones, migration 0496 ([Feature] Blood ketones (BHB) measurement type with a derived GKI value #1367)Fixed
endsOnwhen they roll oncursorExpiredSecurity
Migrations: 0495, 0496.