Commit Graph
3192 Commits
Author SHA1 Message Date
Marc-André Bombeck 7c2e11369c chore(release): v1.25.1 2026-06-29 01:07:42 +02:00
Marc-André Bombeck a58fc2e0e2 Merge v1.25.1: final cleanup (surface confirm failures, German term unification, upload reveal, list error state) 2026-06-29 01:04:18 +02:00
Marc-André Bombeck 679f8a05c9 fix(documents): surface confirm failures and harden the library edges
Close the gaps the final verification pass flagged on the documents surface:

- Confirm no longer claims success when the route rejects a fact into its
  `failed[]` array (HTTP 200). A unit-mismatch fact left silently PENDING with
  a green toast now raises a warning naming how many couldn't be saved and why.
- Unify the German documents copy on "Angaben": the discard-confirm body, the
  provider-unsupported note, and the module description still said "Fakten".
- After upload, sort by date-added rather than document date so a back-dated
  upload always lands on the first page where its detail panel can open.
- Give the list its own load-error state with a retry instead of rendering the
  "no documents yet" empty state on a failed fetch.
- Classify the local-OCR-disabled extract error to a clear message.
- Drop the orphaned settings.sections.notifications.inboxLink key (no call site).
2026-06-29 01:03:44 +02:00
Marc-André Bombeck 2ec4828c1f Merge v1.25.1: deep data/cross-cut (cadence-aware alert compliance, lab-unit guard, signals in briefing, biomarker fallback, cleanups) 2026-06-29 00:38:45 +02:00
Marc-André Bombeck 2a66e81031 Merge v1.25.1: settings deep-round IA (sign-in consolidation, sub-tab relabels, account-delete relocation, a11y id, ES labels) 2026-06-29 00:38:38 +02:00
Marc-André Bombeck 86d1d5b726 Merge v1.25.1: documents deep-round QoL (store-framed copy, error classification, recoverability, date format, overflow) 2026-06-29 00:38:25 +02:00
Marc-André Bombeck 2321ce29db fix(insights): route alert-card compliance through the cadence-aware engine + deep data cleanups
The insights alert cards computed medication compliance with the naive
`schedules.length × days` denominator, so a fully-adherent weekly
injectable read ~14% and fired a false low-compliance alert (and a paused
medication mis-fired the same way). Route the alert path through the
canonical `calculateCompliance` engine like every other compliance
surface — pause eras, schedule revisions and dose windows honoured.

Document confirm: committing a numeric observation against an existing
biomarker silently replaced the stated unit with the catalog's, with no
conversion — a stated "6.1 mmol/L" against a mg/dL marker committed
"6.1 mg/dL". Reject on a unit mismatch (fail closed) so the user
reconciles on the review screen, the same posture as the unit-required
guard.

Wire grip strength, waist (with waist-to-height) and pain into the
briefing feature set and the grounding allow-set so the clinical-depth
signals reach the daily narrative; the mental-health screeners stay
excluded by construction.

Biomarker detail: fall back to a generic description for catalog-less
markers, and keep the heading + description with a retry on the error
state. Collapse the medication External-API and Lifecycle groups by
default. Re-enable the insights scroll-to-top regression and assert the
shipped main-content reset.

Align the EN haemoglobin/haematocrit display names to British spelling.

Drop the redundant `(userId, deletedAt)` index on inbound documents — a
strict prefix of the new three-column index. Trim the dead
MedicalDisclaimer variants to the one live `dataPosture`. Move the
crisis-resources card off the retired amber tint to a calm
destructive-subtle border. Add a registry invariant asserting every
biomarker signal key resolves to a real catalog slug.
2026-06-29 00:37:39 +02:00
Marc-André Bombeck aa432244ce fix(settings): consolidate sign-in management and tidy the settings IA
Follow-ups on the v1.25.1 settings group consolidation.

- Sign-in security is no longer split across two top-level groups. Active
  sessions, trusted devices, and the login-activity feed move into Account
  > Security alongside the second-factor and passkey controls, so every
  "who can sign in as me" control sits in one place. The Data & Privacy
  pane keeps the data / retention / encryption story and cross-links to
  the security home. Sessions and activity are no longer duplicated on the
  Profile tab.
- First-child sub-tabs no longer repeat their group name: the section
  titles become "Profile & preferences", "Connections", and
  "Privacy & retention" across all six locales.
- Account deletion moves out of Advanced into the Account group as a
  standalone card; research mode and the data reset stay in Advanced.
- Disambiguate the Spanish labels for the health record vs medical
  history (they both read "Historial médico"); medical history becomes
  "Antecedentes médicos".
- The section heading carries its id on a single breakpoint instance to
  clear a duplicate-id-aria violation; the focus hook keeps targeting
  both instances and picks the visible one.
- The in-page sub-tab strip scrolls its active tab into view on a narrow
  viewport, matching the group strip.
- Redirect /settings/layout to the Display landing now that nothing links
  to the old personalisation hub.
- Note in code that delivery channels deliberately stay under
  Integrations (a channel is a delivery provider).
2026-06-29 00:34:24 +02:00
Marc-André Bombeck e7683c9f54 fix(documents): reconcile library quality-of-life passes
- Reword the upload toasts to the store-only reality ("stored", not "read"),
  so the success message no longer claims AI ran and the panel it opens no
  longer contradicts it.
- Classify upload failures (too large / wrong type / rate-limited / invalid
  metadata) into specific messages; add a client-side 12 MB pre-check and show
  the accepted formats and size ceiling beside the file field.
- Clear filters, search, and sort on a successful upload so the new document is
  in the list the detail panel opens against, and add a "Clear filters" action
  on the no-results state.
- List approved facts read-only after review so the link between a document and
  the records it contributed stays visible instead of "Nothing left to review".
- Format date-group headers through the app's own date formatter, so they honour
  the user's date-format preference instead of a textual medium style.
- Stack the toolbar until md and let it wrap; wrap the fact badge row on narrow
  screens.
- Tie the disabled Approve to a plain-language reason, label the confidence
  percentage, and render it through the locale percent formatter.
- Treat a fully-confirmed re-extract (422) as the calm already-reviewed note,
  matching the partly-confirmed case.
- German: unify on "Angaben" for the extracted items and drop the anglicism.
2026-06-29 00:33:30 +02:00
Marc-André Bombeck 4702546cdb test(insights): freeze the clock in the freshness-caption tests to fix the midnight-boundary flake 2026-06-29 00:04:59 +02:00
Marc-André Bombeck f4919e9634 Merge v1.25.1: expand the biomarker reference descriptions across six locales 2026-06-28 23:59:45 +02:00
Marc-André Bombeck 92b963382e feat(labs): expand the biomarker reference descriptions
Replace the terse one-line catalog descriptions with richer three-to-four
sentence explainers for all 30 biomarkers shown on the lab detail page:
what each marker measures, its physiological role, and what it relates to
clinically. The text stays static, factual, and non-diagnostic, with no
reference ranges baked into the prose. Updated across all six locales
(de/en/es/fr/it/pl) at exact key parity.
2026-06-28 23:59:06 +02:00
Marc-André Bombeck ae9ac13213 fix(documents): align the re-extraction guard error code between client and server 2026-06-28 23:50:21 +02:00
Marc-André Bombeck 21d1cdd458 Merge v1.25.1: documents backend QA reconcile (effective date, re-extraction guard, rate limits, count efficiency, index) 2026-06-28 23:49:25 +02:00
Marc-André Bombeck eb1779d5c1 fix(documents): close v1.25.1 library QA findings (backend)
Default documentDate at store time. A store-only upload no longer lands
with a NULL filing date: when the client omits one, default it to the
upload day so the column is always set on a stored row. The library list
sorts, groups, and range-filters on the same effective date the UI shows,
so undated uploads no longer mis-sort under nulls-last, break date-group
headers, or fall through the range filter. The date stays user-editable
and may be cleared back to NULL via PATCH.

Block re-extraction once any fact is APPROVED. A partially-confirmed
document stays EXTRACTED, which the CONFIRMED guard does not catch;
re-extracting would delete the approved facts (severing the committed
record's provenance) and re-stage them as PENDING, letting a second
approval duplicate the committed lab / condition / medication. The
extract route now refuses with 409 (documents.inbound.alreadyPartlyConfirmed)
when approved facts exist; the user must finish reviewing or discard first.

RFC 5987-encode the original-download filename. The Content-Disposition
now carries both an ASCII filename= fallback and a filename*=UTF-8'' value
so a non-ASCII name survives intact; the stored set is inline-safe by
construction, so the dead attachment branch is removed.

Add a light per-user rate-limit backstop to the original-read, PATCH, and
DELETE routes (generous; self-DoS only — the routes are owner-scoped).

Lean the list counts: tally facts for the whole page in one grouped count
instead of materialising fact-id rows, and exclude REJECTED facts from
factCount. Extend the documentDate index with deleted_at to cover the
list scan. Document the deliberate plaintext-title PHI tradeoff at the
column and the store site.
2026-06-28 23:48:43 +02:00
Marc-André Bombeck 0a965f2454 Merge v1.25.1: documents UI a11y + QoL reconcile (live region, detail order, discard confirm, date-range filter, extract gate) 2026-06-28 23:48:06 +02:00
Marc-André Bombeck 884323d787 fix(documents): accessibility and review-flow polish for the library UI
Tighten the documents library review surface after a QA pass:

- Surface the provider-unsupported and already-confirmed notes as polite
  live regions (role=status / aria-live) so keyboard and screen-reader
  users hear them when the suppressed-toast paths fire.
- Render a document's detail panel directly after the row that opened it,
  and tie the row's aria-controls to the panel id, fixing reading and
  tab order.
- Gate Discard behind a confirm dialog and toast on failure.
- Disable Upload until a file is chosen, with an inline hint.
- Namespace per-fact editor field ids so simultaneously-open editors no
  longer share DOM ids (label-for associations stay correct).
- Hide Extract once any fact is approved, mirroring the server guard, and
  treat the already-confirmed response as a calm inline note.
- Add a document-date range filter, a kind fallback for the detail title,
  and a screen-reader hint on the new-tab original link.
- Calmer, neutral needs-review badge and more legible row badges.

Adds the new strings across all six locales.
2026-06-28 23:47:23 +02:00
Marc-André Bombeck 014e7879bf Merge v1.25.1: clear offline caches on login + settings focus/contrast a11y 2026-06-28 23:42:51 +02:00
Marc-André Bombeck 7214b95982 fix(auth,settings): clear offline caches on login and tighten settings a11y
Login only wiped the in-memory query cache; the IndexedDB query snapshot
and the service-worker data/page caches from the previous account stayed
on disk. Logout and the 401/expiry redirect already drop all three. Run
the same offline-cache wipe on a successful login too, before the new
user's dashboard prefetch warms, so a fresh sign-in on a shared browser
inherits nothing from the prior session. The per-account restore guard
still stands; this removes the stale data at the source.

Settings shell: move focus to the section heading when the active section
changes within the mounted shell, so keyboard and screen-reader users are
placed in the new content instead of being left on the nav link they
activated. The first mount is skipped to avoid an unexpected focus move on
a deep link. Raise the inactive sub-tab text from muted-foreground to
foreground/70 so it clears the WCAG AA contrast floor over the tinted
sub-tab strip.
2026-06-28 23:42:17 +02:00
Marc-André Bombeck 84543ad540 Merge v1.25.1: documents library UI, metadata editing, optional extraction, rename to Documents 2026-06-28 23:26:42 +02:00
Marc-André Bombeck c6a7de8f2a feat(documents): build the Documents library UI
Evolve the inbound-documents screen into a real document library on top of
the store-first backend.

- Upload stays store-only and always works: the form now files a document
  with an optional title, category, and document date in one step. Extraction
  is a separate, explicit action.
- List becomes an organized library: documents grouped by date, with a title
  (filename fallback), category and status badges, and pending/fact counts. A
  toolbar adds title/filename search, a category filter, and a sort control
  (document date / date added / title, asc/desc). Keyset pagination loads more
  via the returned cursor through useInfiniteQuery.
- Detail panel: view or download the original, edit metadata (rename,
  recategorise, set the document date), optionally run extraction, then the
  existing review-then-confirm flow. When no scan provider is configured,
  extraction surfaces a calm inline note instead of a hard error; the stored
  document is untouched. Discard stays.
- Add a parameterised list key to the query-key factory so each filter/sort
  combination keeps its own cache bucket while staying under the documents
  prefix for invalidation.
- Rename the surface to "Documents" across all six locales (title, subtitle,
  module label/description) and add the new toolbar, edit, extract, and
  date-group strings. Route, model, and module key stay internal.

Add component and unit coverage for the grouped list, the detail/review
surface, the metadata edit form, the provider-unsupported note, and the
search-param/grouping/error-classification helpers.
2026-06-28 23:26:01 +02:00
Marc-André Bombeck 02df0d1f0e test(documents): satisfy strict null checks on mocked Prisma call args 2026-06-28 23:11:02 +02:00
Marc-André Bombeck cdd66b6620 Merge v1.25.1: documents library backend — store-without-AI, optional extract, edit, list
# Conflicts:
#	docs/api/openapi.yaml
#	src/lib/documents/store.ts
#	src/lib/openapi/routes/documents.ts
2026-06-28 23:08:54 +02:00
Marc-André Bombeck 05465a35a5 feat(documents): store-first library with optional extraction
Invert the inbound-documents surface from an OCR inbox into a document
library: a file can be stored without any AI provider, and extraction
becomes an opt-in action on top.

- Migration 0222: add `title` + `document_date` columns, a
  `(user_id, document_date)` index, the richer kind taxonomy
  (lab/imaging/prescription/insurance/vaccination), and a STORED status
  made the column default. The status enum is recreated so the new value
  can be set as the default within the migration transaction; kind values
  use ADD VALUE. Nullable columns, no backfill.
- POST /api/documents/inbound is now store-only: bounded multipart read,
  magic-byte MIME sniff, AES-256-GCM at rest, persisted as STORED with no
  provider/consent/budget call and no egress.
- POST /api/documents/inbound/[id]/extract carries the relocated
  extraction gauntlet (resolve provider, consent, rate-limit, budget, run,
  reconcile, stage facts) against an already-stored row; absent a provider
  it 422s the enhancement only and leaves the stored document intact.
- PATCH /api/documents/inbound/[id] edits title/kind/documentDate
  field-by-field, owner-scoped by session userId.
- GET /api/documents/inbound gains search, kind filter, documentDate
  range, sort, and keyset pagination via the parameter-bound query builder.
- Extend the validation schemas + DTO, regenerate the OpenAPI contract,
  and add route tests for the store/extract/edit/list paths.
2026-06-28 23:04:19 +02:00
Marc-André Bombeck 174bee298e Merge v1.25.1: consolidate Settings into nine groups with in-page sub-tabs 2026-06-28 23:01:14 +02:00
Marc-André Bombeck 18c737d620 feat(settings): consolidate the settings nav into nine groups
The settings left rail rendered one entry per section — 26 visible — which
read as a long flat list on desktop and a 26-chip scroll strip on mobile.
Group the sections into nine top-level entries and surface each group's
children as in-page sub-tabs, keeping the rail one level deep and the second
level inside the page.

Every section route stays live at its own URL. The rail is now driven by a
SETTINGS_GROUPS model; a reverse index maps each child slug onto its group so
deep links and the per-page settings links keep resolving and highlight the
right group, with the active child marked on the sub-tab strip. This
generalises the existing hidden-child highlight mechanism rather than moving
routes, so bookmarks and the contract surface are untouched.

Groups: Account (profile, sign-in), Tracking (areas, the per-domain pages,
targets), Display (dashboard, insights), Integrations (connections, channels,
source priority), Notifications, AI & Coach, API & Access, Data & Privacy
(export, health record, sharing, privacy, advanced), About. Per-domain
settings keep their view and data together inside one sub-tab — only the nav
groups, never a single concept.

Rename the Display group title away from "Dashboard" so it no longer collides
with its own Dashboard child. Add the nine group labels and the sub-section
nav label across all six locales. Drop the now-unused hub back-link.
2026-06-28 23:00:35 +02:00
Marc-André Bombeck 4af13a24e4 Merge v1.25.1: fold the inbound-document disclaimer into the page subtitle
# Conflicts:
#	src/components/documents/inbound-documents-view.tsx
2026-06-28 21:48:48 +02:00
Marc-André Bombeck d7fd3ea9b4 Merge v1.25.1: drop the repeated inline disclaimers from medication, insights, and labs 2026-06-28 21:48:21 +02:00
Marc-André Bombeck 9c1c0d86a9 Merge v1.25.1: clear the in-memory query cache at every session boundary 2026-06-28 21:48:16 +02:00
Marc-André Bombeck adb7892b97 fix(ui): drop the repeated inline disclaimers from medication, insights, and labs
The layered self-description standard already carries the canonical
intended-purpose line, the Coach standing note, the emergency note and
the data-posture note. The medication, insights and labs surfaces each
repeated a further context-specific disclaimer footer that added noise
without adding meaning.

Remove the three rendered footers and retire the now-unused
`insights` / `labs` / `medications` disclaimer variants from the shared
component (type, key map and doc). Drop the orphaned selfDescription
keys from all six locale bundles so call-site and reverse i18n coverage
stay in parity.
2026-06-28 21:39:40 +02:00
Marc-André Bombeck ea380d6f68 fix(auth): clear the in-memory query cache at every session boundary
The root QueryClient is created once and survives every client-side
navigation, so logout then login on the same browser left the previous
account's non-user-scoped health-data queries in memory and the next
account read them before any refetch landed. Wipe the entire in-memory
cache on logout, on session expiry, and at the start of a fresh login,
alongside the existing IndexedDB and service-worker cache wipe, so no
session ever inherits another account's data.
2026-06-28 21:37:55 +02:00
Marc-André Bombeck c10eae2c4e fix(documents): fold the inbound-document disclaimer into the page subtitle
Remove the standalone amber disclaimer card from the inbound-documents
review screen. The non-diagnostic essence now reads as the plain muted
subtitle line under the page title: upload a clinical document and review
the extracted details. Drop the now-unused disclaimer.title /
disclaimer.body keys across all six locales and the AlertTriangle /
CardDescription imports left orphaned by the removal.
2026-06-28 21:35:30 +02:00
Marc-André Bombeck dda75abf38 Merge v1.25.1: reset scroll to top on forward navigation app-wide 2026-06-28 21:31:00 +02:00
Marc-André Bombeck 6b7e6f3332 Merge v1.25.1: wellbeing check-in as a standalone module page 2026-06-28 21:30:53 +02:00
Marc-André Bombeck 0109fbbc4c Merge v1.25.1: biomarker detail mirrors the Insights metric sub-page 2026-06-28 21:30:48 +02:00
Marc-André Bombeck 883b6bb5e6 Merge v1.25.1: inbound original-document view/download + age-stratified grip/waist bands 2026-06-28 21:28:23 +02:00
Marc-André Bombeck fc25a8a304 Merge v1.25.1: Coach-hero disclaimer drop + collapse sessions/activity + Anamnese conditions 2026-06-28 21:27:47 +02:00
Marc-André Bombeck 37c977e3a4 feat(mental-health): make the wellbeing check-in a standalone module page
Move the PHQ-9 / GAD-7 screener off `/insights/mental-wellbeing` to a
top-level `/mental-wellbeing` route so it no longer borrows the Insights
tab strip and layout shell. The page now uses the standard module-page
frame at the wider content width the other module pages use.

Replace the standing screening disclaimer block and the opt-in/private
line in the header with an info icon after the page heading whose
hover/focus tooltip carries the screening-not-a-diagnosis note. Drop the
now-orphaned `disclaimer` / `optInNote` strings across all six locales
and add the `infoTooltip` string in their place.

The questionnaire, scoring, severity result, PHQ-9 item-9 crisis-resource
handling, focus-on-submit, and 44px touch targets are unchanged. Repoint
the module nav entry and the registry comments at the new route.
2026-06-28 20:48:39 +02:00
Marc-André Bombeck 65daf11be5 fix(ui): reset scroll to top on forward navigation app-wide
The authenticated shell keeps a single <main id="main-content"> mounted
across every route change, so its scroll offset persisted between routes:
scrolling down in one section (e.g. Settings) and navigating to another
opened the next view already scrolled.

Reset the scroll container to the top on each pathname change, with a
window.scrollTo fallback for the body-scrolled shells. Back/forward
navigation skips the reset so the browser's own scroll restoration stands:
popstate arms a one-shot skip cleared on a macrotask so it can never stick.
2026-06-28 20:40:23 +02:00
Marc-André Bombeck ad43eaeff0 Mirror the metric sub-page layout on the biomarker detail
Bring the lab biomarker detail in line with the Insights metric pages:

- Lead with the static catalog description directly beneath the heading,
  the explainer-caption position the metric pages use.
- Drop the early big-value + reference-badge block that did not match the
  assessment-card styling.
- Split numeric and qualitative markers: numeric keeps the stat strip and
  chart, qualitative shows only the latest result text (no strip, no chart,
  no range badge). The assessment card now renders for any marker with
  readings and self-suppresses for qualitative-only markers.
- Move the full reading history off the detail page onto a dedicated
  /labs/[biomarkerId]/values route, reached by a top-right list control,
  matching the metric pages' show-all-values affordance.
2026-06-28 20:37:01 +02:00
Marc-André Bombeck 08314c7c09 feat(documents): view and download the original inbound document
The inbound-document store keeps the uploaded doctor letter encrypted at
rest (InboundDocument.contentEncrypted, AES-256-GCM), but there was no way
to read the original back — the decrypt helper had been dropped as unused.

- Restore decryptDocumentFromBytes in the document store, fail-closed on a
  bad / missing key id.
- Add GET /api/documents/inbound/[id]/original: owner-scoped (userId-narrowed
  query), module-gated, returns the decrypted bytes with the stored MIME
  type. A PDF / image is served inline so the browser can render it; other
  types download as an attachment. The filename is sanitised before it
  reaches the Content-Disposition header. The bytes are PHI — never logged,
  never served cross-user, and a decrypt error fails closed (500) rather than
  returning ciphertext. Cache-Control is private, no-store.
- Surface a 'View original' action in the document review screen.
- Document the route in the OpenAPI registry and regenerate the spec.
- Cover the route with a test: owner-scoped success, attachment fallback,
  404 for another user's document, and fail-closed on decrypt error.

i18n: viewOriginal across all six locales.
2026-06-28 20:33:29 +02:00
Marc-André Bombeck d3967bcdd0 Surface pre-existing conditions in the medical-history section
The chronic-conditions and Coach-focus self-context read as foundational
medical history, so the Anamnese section now surfaces them as a read-only
shared view next to allergies and family history, with a link to their single
editing home in personal context. Personal context links back to the medical
history. The card is coach-gated and reads through the existing
/api/coach/about-me query key, so nothing is moved or duplicated and there is
no schema change.
2026-06-28 20:29:21 +02:00
Marc-André Bombeck cab0e50fff Collapse the active-sessions and security-activity lists by default
Both account-security lists now render behind a disclosure control and open
only on click. The trigger carries aria-expanded and aria-controls and is
keyboard-operable; the region is gated with hidden. State is UI-only and not
persisted.
2026-06-28 20:29:15 +02:00
Marc-André Bombeck d15dd26ebf Drop the Coach-hero medical disclaimer
The new-chat hero carried a standing self-description line. Remove that
instance; the greeting and composer stay. The MedicalDisclaimer component
and its insights/labs/medications placements are unchanged.
2026-06-28 20:29:10 +02:00
Marc-André Bombeck 6e204d054a feat(insights): age-stratify grip strength and waist reference bands
Grip strength and waist circumference resolved against a single sex-aware
bracket for every adult age. Replace each with age x sex norm bands:

- Grip strength: age x sex bands from Dodds et al. 2014 (PLOS ONE
  9(12):e113637) British normative data — band low is the 10th centile
  floored at the EWGSOP2 probable-sarcopenia cut-off (men 27 kg, women
  16 kg), band high is the 50th-centile median. Strength peaks in the 30s
  and declines from midlife, so the bands step down with age.
- Waist circumference: WHO increased-risk threshold (men 94 cm, women
  80 cm) held flat through midlife and raised for older adults toward the
  WHO substantially-increased-risk line, since the WHO cut-points derive
  from cohorts aged 20-74. The standard threshold is never lowered.

The norms resolver gains an age-independent clinical cut-off row per sex,
used only as the no-age fallback so a profile with a known sex but no date
of birth keeps the sex cut-off rather than the coarse registry anchor. The
signal registry structure is unchanged — only the resolver tables move.
2026-06-28 20:22:24 +02:00
Marc-André Bombeck 651b02bc1b fix(ci): gate the coach-eval live judge on env, not the secrets context 2026-06-28 20:15:52 +02:00
Marc-André Bombeck 0c583323e0 Merge pull request #381 from MBombeck/release/v1.25.0
Release v1.25.0 — Clinical depth
v1.25.0
2026-06-28 19:52:53 +02:00
Marc-André Bombeck 0f2b548138 style: apply prettier 3.9.1 formatting
Mechanical reflow from the prettier 3.9.1 bump; no behaviour change.
2026-06-28 19:26:16 +02:00
Marc-André Bombeck 6329540ade chore(deps): fold in the pending dependency updates
Bump prettier 3.8.4 → 3.9.1, @aws-sdk/client-s3 3.1048.0 → 3.1075.0,
@next/bundle-analyzer 16.2.6 → 16.2.9, @axe-core/playwright 4.11.3 →
4.12.1, and testcontainers 12.0.1 → 12.0.3; move the e2e cache step to
actions/cache v6.1.0.
2026-06-28 19:25:10 +02:00
Marc-André Bombeck 4ae783064d fix(ci): clear the v1.25 release-branch gate failures
- Reword two LOINC verification comments in the signals registry so they
  no longer trip the forbidden-marker grep, keeping the meaning intact.
- Resolve the dead-code gate: gate the seeded-question opener on the
  per-user ambient-suggestions opt-out (wiring the previously orphaned
  resolveCoachAmbientSuggestionsEnabled, server-authoritative), drop the
  unread decryptDocumentFromBytes helper and its now-unused import, and
  remove the unused SignalKind type alias.
- Delegate undici's fetch to the global stub in the provider-chain
  integration test so the egress-pinned client HTTP is mocked again.
- Defer the JSON example-download cleanup a tick so revoking the blob URL
  no longer races the browser download start (stabilises the e2e).
- Sync the service-worker version fallback to v1.25.0.
2026-06-28 19:23:57 +02:00