Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b46550d
fix(settings): correct the MCP token scope note to match the write to…
MBombeck Aug 9, 2026
338e9bc
fix(settings): render AI consent copy as foreground content
MBombeck Aug 9, 2026
6d67e84
fix(dashboard): localize the respiratory-rate unit label
MBombeck Aug 9, 2026
6e39651
fix(settings): honest address, greeting comma, and managed-record err…
MBombeck Aug 9, 2026
53a463f
fix(settings): show a read failure on the share-link list, not an emp…
MBombeck Aug 9, 2026
ab2c5cb
fix(settings): show a read failure on the API-token list, not an empt…
MBombeck Aug 9, 2026
48e4882
fix(settings): show read failures on the MCP connector lists, not emp…
MBombeck Aug 9, 2026
51c40c6
fix(dashboard): show a read failure on the Vorsorge tile, not an empt…
MBombeck Aug 9, 2026
22d5c01
fix(settings): surface AI settings-read failures instead of a default…
MBombeck Aug 9, 2026
1229d54
fix(insights): recoverable read failures on the ECG detail and list page
MBombeck Aug 9, 2026
6485aae
fix(insights): surface mood-insights read failures instead of silent …
MBombeck Aug 9, 2026
f63fdb3
fix(cycle): use the shared query-error primitives on failed cycle reads
MBombeck Aug 9, 2026
4458200
fix(settings): make settings read failures foreground and recoverable
MBombeck Aug 9, 2026
f6a0ee4
fix(checkups): use the shared query-error primitive on the Vorsorge list
MBombeck Aug 9, 2026
ba42354
fix(admin): replace hand-rolled read-error boxes with the shared prim…
MBombeck Aug 9, 2026
c8500dd
docs(changelog): record the honest-error and MCP scope-note fixes und…
MBombeck Aug 9, 2026
edaa5bf
style: wrap a long assertion in the api-section error test
MBombeck Aug 9, 2026
73b82f4
test: use render thunks in the read-error family suites for the jsx-k…
MBombeck Aug 9, 2026
9ae42ae
chore(bundle): raise the aggregate cap for the honest-error-state code
MBombeck Aug 9, 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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## [Unreleased]

### Fixed

- The connector-token note in Settings no longer claims a token is read-only in every case, which the write toggle right below it disproved. It now states the real model: read-only by default, write access an opt-in you turn on per token, and no token ever reaches admin functions.
- A failed load of your share links now says so, with a way to retry, instead of quietly showing "no active share links" as if you had never shared anything. The same held for the API and connector token lists on the security screens.
- A read that fails now shows a clear, recoverable error across the app instead of an empty list or a silent gap. The sharing and token screens, the ECG detail and list, the cycle and mood insights, the dashboard preventive-care tile, the checkups list, and the admin console all say when a read failed and offer a retry, rather than reading as "nothing here".
- The AI consent and connector notes in Settings render as normal text now, not faint fine print, so the copy you are meant to read before turning a feature on is legible.
- The respiratory-rate tile on the dashboard shows its unit in your own language instead of a fixed English label, and the personalized greeting carries its comma.

## [1.37.3] — 2026-08-09

### Added
Expand Down
4 changes: 2 additions & 2 deletions bundle-budget.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"$comment": "Client-bundle budgets, enforced by scripts/check-bundle-budget.mjs (--check) after `next build` in CI. Values are KB gzip and include every emitted lazy route and locale chunk, while route budgets include the shared rootMainFiles baseline. Re-measured at v1.37.2: / 455, /insights 443, /measurements 441, /insights/mood 453, total 3328, baseline 130, lazy catalogs 849. Every per-route ceiling is unchanged. The /insights overview crept a kilobyte over its 445 ceiling when the ECG teaser began importing its overview cap from the classification module, dragging that module's label map and helpers into the eager page; the cap now lives in its own value-only module, and the Health Score's single provenance entry is split out of the full metric-provenance map, so the overview imports the bare number and citation it renders rather than every metric's label map behind them. Both are back under 445 with room to spare. The 42 KB aggregate rise from 3286 (v1.35.0) is all locale-catalog strings: v1.36 and v1.37 added the encounter, mood-context, mood-prognosis, practitioner, workout-batch and account-sharing surfaces, and their copy lands across the six locale catalogs the whole-build sum counts independently (804 to 849 KB). The non-catalog client chunks are flat against v1.35.0, so nothing a person downloads on a given route grew beyond its own ceiling. The aggregate cap therefore moves from 3310 to 3352 (24 KB headroom, matching the previous margin); per-route ceilings, the static-catalog guard and the one-Recharts-chunk guard remain unchanged.",
"$comment": "Client-bundle budgets, enforced by scripts/check-bundle-budget.mjs (--check) after `next build` in CI. Values are KB gzip and include every emitted lazy route and locale chunk, while route budgets include the shared rootMainFiles baseline. Re-measured at v1.37.2: / 455, /insights 443, /measurements 441, /insights/mood 453, total 3328, baseline 130, lazy catalogs 849. Every per-route ceiling is unchanged. The /insights overview crept a kilobyte over its 445 ceiling when the ECG teaser began importing its overview cap from the classification module, dragging that module's label map and helpers into the eager page; the cap now lives in its own value-only module, and the Health Score's single provenance entry is split out of the full metric-provenance map, so the overview imports the bare number and citation it renders rather than every metric's label map behind them. Both are back under 445 with room to spare. The 42 KB aggregate rise from 3286 (v1.35.0) is all locale-catalog strings: v1.36 and v1.37 added the encounter, mood-context, mood-prognosis, practitioner, workout-batch and account-sharing surfaces, and their copy lands across the six locale catalogs the whole-build sum counts independently (804 to 849 KB). The non-catalog client chunks are flat against v1.35.0, so nothing a person downloads on a given route grew beyond its own ceiling. The aggregate cap therefore moves from 3310 to 3352 (24 KB headroom, matching the previous margin); per-route ceilings, the static-catalog guard and the one-Recharts-chunk guard remain unchanged. v1.37.4's honest-error-state charge then added recoverable read-failure handling to thirteen surfaces (the shared QueryErrorCard and QueryErrorRow primitives plus an isError branch per surface) and rewrote the MCP scope note and the managed-record error copy across the six locales; the measured total rose to 3404 while every per-route ceiling stayed met (/page 457, /insights 445, /measurements 443, /insights/mood 455). The aggregate cap moves from 3352 to 3428, keeping the same margin; nothing a person downloads on a given route grew beyond its ceiling.",
"routesKbGz": {
"/page": 460,
"/insights/page": 445,
"/measurements/page": 445,
"/insights/mood/page": 460
},
"totalClientKbGz": 3352,
"totalClientKbGz": 3428,
"maxRechartsChunks": 1
}
12 changes: 7 additions & 5 deletions messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
"evening": "Guten Abend"
},
"welcomeBack": "{greeting}, willkommen zurück.",
"welcomeBackWithName": "{greeting} {name}, willkommen zurück.",
"welcomeBackWithName": "{greeting}, {name}, willkommen zurück.",
"greetingSalutation": "Hallo, {name}",
"streakLabel": "Tage in Folge",
"weight": "Gewicht",
Expand Down Expand Up @@ -4615,6 +4615,8 @@
},
"sharedRecord": {
"managedSettings": {
"saveError": "Speichern fehlgeschlagen. Bitte erneut versuchen.",
"validationError": "Bitte prüfe deine Eingaben.",
"profile": {
"title": "Profil",
"displayName": "Anzeigename",
Expand Down Expand Up @@ -6024,7 +6026,7 @@
"scopeTitle": "Was dieser Link enthält",
"scopeInsuranceExcluded": "Versichertendaten werden über einen Link nie geteilt.",
"statusNeedsReselect": "Inhalt neu wählen",
"reselectReason": "Dieser Link lieferte einen Umfang, den niemand gewählt hatte, und wurde deshalb geschlossen. Legen Sie einen neuen an und wählen Sie den Inhalt.",
"reselectReason": "Dieser Link lieferte einen Umfang, den niemand gewählt hatte, und wurde deshalb geschlossen. Lege einen neuen an und wähle den Inhalt.",
"reselectAction": "Ersatz anlegen",
"createDetail": "Der Token wird nur einmal bei der Erstellung angezeigt — sichere ihn dann; er lässt sich nicht wiederherstellen."
},
Expand Down Expand Up @@ -6283,7 +6285,7 @@
"connectDescription": "Füge diese URL in die Einrichtung des eigenen Connectors deines Assistenten ein und autorisiere dich mit dem Token unten oder melde dich bei Aufforderung an.",
"tokensTitle": "Connector-Tokens",
"tokensDescription": "Erzeuge ein schreibgeschütztes Token, um einen Assistenten zu verbinden.",
"scopeNote": "Tokens sind auf health:read beschränkt — nur Lesezugriff auf deine eigenen Daten. Sie können niemals Admin-Funktionen erreichen.",
"scopeNote": "Tokens haben standardmäßig nur Lesezugriff auf deine eigenen Daten. Schreibzugriff ist optional und wird pro Token über den Schalter unten aktiviert. Die Tokens erreichen niemals Admin-Funktionen.",
"writeScopeToggleLabel": "Eintragen erlauben (health:write)",
"writeScopeNote": "Fügt den Scope health:write hinzu, damit der Assistent neue Messwerte und Stimmungseinträge in dein Konto eintragen kann. Jeder Schreibvorgang wird zuvor bestätigt. Das Token kann weiterhin keine vorhandenen Einträge löschen oder ändern, keine Medikamente bearbeiten und keine REST- oder Admin-Funktionen erreichen. Für reinen Lesezugriff ausgeschaltet lassen.",
"connectionsTitle": "Verbundene Assistenten",
Expand Down Expand Up @@ -9836,8 +9838,8 @@
"standardHint": "Ein Klick füllt aus, was ein normaler Arztbesuch meist braucht. Jeder Eintrag bleibt änderbar.",
"groupCount": "{on}/{total}",
"groupDisclosure": "Einträge in {group} anzeigen",
"sensitiveHint": "Hier ist nie etwas vorausgewählt. Wählen Sie jeden Eintrag selbst.",
"scopeNone": "Noch nichts ausgewählt. Wählen Sie aus, was enthalten sein soll, oder übernehmen Sie den Standardbericht.",
"sensitiveHint": "Hier ist nie etwas vorausgewählt. Wähle jeden Eintrag selbst.",
"scopeNone": "Noch nichts ausgewählt. Wähle aus, was enthalten sein soll, oder übernimm den Standardbericht.",
"scopeCount": "{count} Einträge aus {groups} Bereichen",
"scopeSensitive": "inkl. {names}",
"leafVisits": "Arztbesuche",
Expand Down
6 changes: 4 additions & 2 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
"evening": "Good evening"
},
"welcomeBack": "{greeting}, welcome back.",
"welcomeBackWithName": "{greeting} {name}, welcome back.",
"welcomeBackWithName": "{greeting}, {name}, welcome back.",
"greetingSalutation": "Hi, {name}",
"streakLabel": "days in a row",
"weight": "Weight",
Expand Down Expand Up @@ -4615,6 +4615,8 @@
},
"sharedRecord": {
"managedSettings": {
"saveError": "Couldn't save. Please try again.",
"validationError": "Please check your entries.",
"profile": {
"title": "Profile",
"displayName": "Display name",
Expand Down Expand Up @@ -6283,7 +6285,7 @@
"connectDescription": "Paste this URL into your assistant's custom-connector setup, then authorize with the token below or sign in when prompted.",
"tokensTitle": "Connector tokens",
"tokensDescription": "Mint a read-only token to connect an assistant.",
"scopeNote": "Tokens are scoped to health:read — read-only access to your own records. They can never reach admin functions.",
"scopeNote": "Tokens grant read-only access to your own records by default. Write access is optional and enabled per token with the toggle below. The tokens can never reach admin functions.",
"writeScopeToggleLabel": "Allow logging (health:write)",
"writeScopeNote": "Adds the health:write scope so the assistant can log new measurements and mood entries to your account. Every write is confirmed first. The token still can't delete or edit existing entries, change medications, or reach REST or admin functions. Leave off for read-only access.",
"connectionsTitle": "Connected assistants",
Expand Down
12 changes: 7 additions & 5 deletions messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
"evening": "Buenas tardes"
},
"welcomeBack": "{greeting}, te damos la bienvenida de nuevo.",
"welcomeBackWithName": "{greeting} {name}, te damos la bienvenida de nuevo.",
"welcomeBackWithName": "{greeting}, {name}, te damos la bienvenida de nuevo.",
"greetingSalutation": "Hola, {name}",
"streakLabel": "días seguidos",
"weight": "Peso",
Expand Down Expand Up @@ -4615,6 +4615,8 @@
},
"sharedRecord": {
"managedSettings": {
"saveError": "No se pudo guardar. Inténtalo de nuevo.",
"validationError": "Revisa tus datos.",
"profile": {
"title": "Perfil",
"displayName": "Nombre visible",
Expand Down Expand Up @@ -6024,7 +6026,7 @@
"scopeTitle": "Qué contiene este enlace",
"scopeInsuranceExcluded": "Los datos del seguro nunca se comparten por enlace.",
"statusNeedsReselect": "Elegir contenido de nuevo",
"reselectReason": "Este enlace mostraba un alcance que nadie eligió, por eso se cerró. Cree uno nuevo y elija su contenido.",
"reselectReason": "Este enlace mostraba un alcance que nadie eligió, por eso se cerró. Crea uno nuevo y elige su contenido.",
"reselectAction": "Crear un reemplazo",
"createDetail": "El token se muestra una sola vez al crearlo — guárdalo entonces; no se puede recuperar."
},
Expand Down Expand Up @@ -6283,7 +6285,7 @@
"connectDescription": "Pega esta URL en la configuración del conector personalizado de tu asistente y autoriza con el token de abajo o inicia sesión cuando se te solicite.",
"tokensTitle": "Tokens del conector",
"tokensDescription": "Genera un token de solo lectura para conectar un asistente.",
"scopeNote": "Los tokens se limitan a health:read: acceso de solo lectura a tus propios registros. Nunca pueden acceder a funciones de administración.",
"scopeNote": "De forma predeterminada, los tokens solo tienen acceso de lectura a tus propios registros. El acceso de escritura es opcional y se activa por token con el interruptor de abajo. Los tokens nunca pueden acceder a funciones de administración.",
"writeScopeToggleLabel": "Permitir registro (health:write)",
"writeScopeNote": "Añade el ámbito health:write para que el asistente pueda registrar nuevas mediciones y entradas de estado de ánimo en tu cuenta. Cada escritura se confirma antes. El token sigue sin poder eliminar ni editar entradas existentes, cambiar medicamentos ni acceder a funciones REST o de administración. Déjalo desactivado para acceso de solo lectura.",
"connectionsTitle": "Asistentes conectados",
Expand Down Expand Up @@ -9836,8 +9838,8 @@
"standardHint": "Un clic rellena lo que suele necesitar una consulta general. Cada entrada sigue siendo editable.",
"groupCount": "{on}/{total}",
"groupDisclosure": "Mostrar las entradas de {group}",
"sensitiveHint": "Aquí nunca hay nada preseleccionado. Elija cada entrada usted mismo.",
"scopeNone": "Nada seleccionado todavía. Elija qué incluir o aplique el informe estándar.",
"sensitiveHint": "Aquí nunca hay nada preseleccionado. Elige cada entrada mismo.",
"scopeNone": "Nada seleccionado todavía. Elige qué incluir o aplica el informe estándar.",
"scopeCount": "{count} entradas de {groups} áreas",
"scopeSensitive": "incl. {names}",
"leafVisits": "Visitas médicas",
Expand Down
6 changes: 4 additions & 2 deletions messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
"evening": "Bonsoir"
},
"welcomeBack": "{greeting}, content de te revoir.",
"welcomeBackWithName": "{greeting} {name}, content de te revoir.",
"welcomeBackWithName": "{greeting}, {name}, content de te revoir.",
"greetingSalutation": "Bonjour, {name}",
"streakLabel": "jours d’affilée",
"weight": "Poids",
Expand Down Expand Up @@ -4615,6 +4615,8 @@
},
"sharedRecord": {
"managedSettings": {
"saveError": "Échec de l'enregistrement. Réessayez.",
"validationError": "Vérifiez vos saisies.",
"profile": {
"title": "Profil",
"displayName": "Nom affiché",
Expand Down Expand Up @@ -6283,7 +6285,7 @@
"connectDescription": "Collez cette URL dans la configuration du connecteur personnalisé de votre assistant, puis autorisez avec le jeton ci-dessous ou connectez-vous lorsque vous y êtes invité.",
"tokensTitle": "Jetons du connecteur",
"tokensDescription": "Générez un jeton en lecture seule pour connecter un assistant.",
"scopeNote": "Les jetons sont limités à health:read : accès en lecture seule à vos propres données. Ils ne peuvent jamais atteindre les fonctions d'administration.",
"scopeNote": "Par défaut, les jetons n'ont qu'un accès en lecture à vos propres données. L'accès en écriture est optionnel et s'active par jeton avec le commutateur ci-dessous. Les jetons ne peuvent jamais atteindre les fonctions d'administration.",
"writeScopeToggleLabel": "Autoriser l'enregistrement (health:write)",
"writeScopeNote": "Ajoute la portée health:write pour que l'assistant puisse enregistrer de nouvelles mesures et entrées d'humeur dans votre compte. Chaque écriture est d'abord confirmée. Le jeton ne peut toujours pas supprimer ni modifier des entrées existantes, changer les médicaments, ni atteindre les fonctions REST ou d'administration. Laissez désactivé pour un accès en lecture seule.",
"connectionsTitle": "Assistants connectés",
Expand Down
6 changes: 4 additions & 2 deletions messages/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
"evening": "Buonasera"
},
"welcomeBack": "{greeting}, bentornato.",
"welcomeBackWithName": "{greeting} {name}, bentornato.",
"welcomeBackWithName": "{greeting}, {name}, bentornato.",
"greetingSalutation": "Ciao, {name}",
"streakLabel": "giorni di fila",
"weight": "Peso",
Expand Down Expand Up @@ -4615,6 +4615,8 @@
},
"sharedRecord": {
"managedSettings": {
"saveError": "Salvataggio non riuscito. Riprova.",
"validationError": "Controlla i tuoi dati.",
"profile": {
"title": "Profilo",
"displayName": "Nome visualizzato",
Expand Down Expand Up @@ -6283,7 +6285,7 @@
"connectDescription": "Incolla questo URL nella configurazione del connettore personalizzato del tuo assistente e autorizza con il token qui sotto o accedi quando richiesto.",
"tokensTitle": "Token del connettore",
"tokensDescription": "Genera un token in sola lettura per collegare un assistente.",
"scopeNote": "I token sono limitati a health:read: accesso in sola lettura ai tuoi dati. Non possono mai raggiungere funzioni di amministrazione.",
"scopeNote": "Per impostazione predefinita, i token hanno accesso in sola lettura ai tuoi dati. L'accesso in scrittura è opzionale e si attiva per singolo token con l'interruttore qui sotto. I token non possono mai raggiungere funzioni di amministrazione.",
"writeScopeToggleLabel": "Consenti la registrazione (health:write)",
"writeScopeNote": "Aggiunge l'ambito health:write così l'assistente può registrare nuove misurazioni e voci dell'umore nel tuo account. Ogni scrittura viene prima confermata. Il token non può comunque eliminare o modificare voci esistenti, cambiare i farmaci o raggiungere funzioni REST o di amministrazione. Lascia disattivato per l'accesso in sola lettura.",
"connectionsTitle": "Assistenti collegati",
Expand Down
6 changes: 4 additions & 2 deletions messages/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
"evening": "Dobry wieczór"
},
"welcomeBack": "{greeting}, witaj ponownie.",
"welcomeBackWithName": "{greeting} {name}, witaj ponownie.",
"welcomeBackWithName": "{greeting}, {name}, witaj ponownie.",
"greetingSalutation": "Cześć, {name}",
"streakLabel": "dni z rzędu",
"weight": "Waga",
Expand Down Expand Up @@ -4615,6 +4615,8 @@
},
"sharedRecord": {
"managedSettings": {
"saveError": "Nie udało się zapisać. Spróbuj ponownie.",
"validationError": "Sprawdź wprowadzone dane.",
"profile": {
"title": "Profil",
"displayName": "Wyświetlana nazwa",
Expand Down Expand Up @@ -6283,7 +6285,7 @@
"connectDescription": "Wklej ten adres URL w konfiguracji własnego łącznika asystenta, a następnie autoryzuj za pomocą poniższego tokenu lub zaloguj się po wyświetleniu monitu.",
"tokensTitle": "Tokeny łącznika",
"tokensDescription": "Wygeneruj token tylko do odczytu, aby połączyć asystenta.",
"scopeNote": "Tokeny są ograniczone do health:read — dostęp tylko do odczytu własnych danych. Nigdy nie mogą uzyskać dostępu do funkcji administracyjnych.",
"scopeNote": "Domyślnie tokeny mają dostęp tylko do odczytu własnych danych. Dostęp do zapisu jest opcjonalny i włączany dla każdego tokena przełącznikiem poniżej. Tokeny nigdy nie mogą uzyskać dostępu do funkcji administracyjnych.",
"writeScopeToggleLabel": "Zezwól na zapis (health:write)",
"writeScopeNote": "Dodaje zakres health:write, aby asystent mógł zapisywać nowe pomiary i wpisy nastroju na Twoim koncie. Każdy zapis jest najpierw potwierdzany. Token nadal nie może usuwać ani edytować istniejących wpisów, zmieniać leków ani uzyskiwać dostępu do funkcji REST lub administracyjnych. Pozostaw wyłączone, aby uzyskać dostęp tylko do odczytu.",
"connectionsTitle": "Połączeni asystenci",
Expand Down
Loading
Loading