3546 Commits
Author SHA1 Message Date
Marc-André Bombeck 023dc4ee4c Merge pull request #439 from MBombeck/release/v1.27.29
Release v1.27.29 — automatic document indexing and AI reading
v1.27.29
2026-07-09 00:49:17 +02:00
Marc-André Bombeck 40c46f6f5b test(e2e): scope the AI-read card-marker assertion to desktop
The vault timeline is virtualized; on the narrow mobile viewport the seeded
Radiology-note card renders outside the initial virtual window (not in the
DOM), so the card-level attribute read waited out the full test timeout on a
non-existent node. The provenance contract is asserted on every project via
the detail status pill; the card marker (viewport-independent render logic,
also covered by the SSR card test) is asserted on desktop where the card is
reliably in view.
2026-07-09 00:39:24 +02:00
Marc-André Bombeck 50e630bf2d test(e2e): lift expect timeout to 10s and CI retries to 2 for loaded-runner headroom
A rotating single e2e test failed each CI run (wizard step transition,
list-refetch card provenance, disclosure toggle) while 211 passed — DOM-
settle-gated assertions sampling a mid-transition frame on a starved shared
runner. Raise the global expect timeout 5s→10s (suite-wide settle headroom)
and CI retries 1→2 (absorb the transient without masking a real break, which
fails all attempts). Also scroll the provenance card into view before reading
its attribute, since the mobile timeline can render it off-viewport.
2026-07-08 23:04:22 +02:00
Marc-André Bombeck e48f9859c8 test(e2e): widen step-transition and provenance assertion timeouts
The wizard step-advance and the AI-read card marker are gated on async
settles (per-step validation; list invalidate→refetch); on a loaded CI
runner those exceed the default 5s expect timeout, so the assertion samples
a mid-transition frame. Widen just those two assertions to 20s — orthogonal
to test.slow() (which extends the test, not the expect, timeout).
2026-07-08 22:50:00 +02:00
Marc-André Bombeck 1dd9b92b7d test(e2e): mark the medication-wizard variants and AI-flow group slow
The wizard-variant specs (rolling/weekdays/compose/monthly/biweekly/oneshot)
and the document-AI flow group are legitimately long multi-step flows; under
a loaded CI runner they race the default 30s and flake green paths — a
different one fails each run. Give them the tripled timeout, matching the
already-slow daily wizard.
2026-07-08 22:38:30 +02:00
Marc-André Bombeck 76277ca31d chore(release): v1.27.29 — automatic document indexing and AI reading 2026-07-08 22:16:12 +02:00
Marc-André Bombeck e261985a48 test(documents): pin contentIndexSource provenance through list/detail/PATCH
Cover the new DTO provenance end-to-end against a real Postgres: the index
source threads through the list and detail reads, and — the regression the
UI wave flagged — survives a metadata PATCH, which now reads the index row
rather than returning a stale null source.
2026-07-08 22:05:05 +02:00
Marc-André Bombeck ecebe796ef test(documents): cover the Read with AI action and AI-read provenance in e2e
Add two acceptance tests to the vault AI suite: the prominent Read with AI
action maps to the vision index endpoint (empty body, no text-mode misroute)
and confirms with a toast; a vision-sourced document surfaces the AI-read
provenance on both the detail status pill and the timeline card marker.
2026-07-08 22:03:13 +02:00
Marc-André Bombeck eed705be7b fix(documents): make auto-index enqueue never fail a stored upload
The upload route awaited an unguarded enqueueDocumentIndex after the
document was already committed. A transient boss.send rejection (a DB
hiccup) would then surface as a 500 for an upload that in fact stored the
file. Guard the send inside the enqueue (a failure annotates and no-ops,
matching the missing-boss path) and drop the await at the call site so the
response never blocks on or fails because of background indexing.
2026-07-08 21:56:17 +02:00
Marc-André Bombeck 0b973f4f76 test(documents): mock content-index lookup and pair new animations with motion-reduce
The PATCH detail route now reads the content-index provenance, so its route
test mocks documentContentIndex.findUnique; the searchable status spinner and
the Read-with-AI pulse pair with motion-reduce:animate-none per the coverage
guard.
2026-07-08 21:41:49 +02:00
Marc-André Bombeck 11fd48cc0e feat(documents): reframe indexing as automatic and make Read with AI prominent
Auto-index on upload means content search is silent-by-default, so the old
per-document index chore no longer reads as a task. Consolidate every AI
reading action into one inviting block on the detail sheet, led by a
prominent Read with AI action, and show each document's searchable status as
a pill that distinguishes an AI-read document from a locally-indexed one.

- New Read-with-AI block: prominent read/re-read action plus suggest and
  session-only summary, gated on provider availability; the calm settings
  pointer replaces the actions (never an error) when no provider is set up.
- Searchable status pill reflects the auto-index: Read by AI (provider read
  the original, highlighted), Searchable (local), or a quiet not-yet state.
- Card searchable marker distinguishes an AI-read document with a Sparkles
  glyph from a locally-indexed one; both carry an accessible label.
- Drop the manual index/re-index chore copy; keep the corpus baseline
  affordance in the filter bar for older un-indexed documents.
2026-07-08 21:25:15 +02:00
Marc-André Bombeck bb0ebb1dce feat(documents): expose content-index provenance on the document DTO
Surface the content-search index's source (vision vs local extraction) on
the list + detail DTO so the vault UI can tell an AI-read document from a
locally-indexed one. Threads the source through both read paths and the
serialisers, regenerates the OpenAPI contract, and adds a narrowing helper
for the free-String column.
2026-07-08 21:15:52 +02:00
Marc-André Bombeck d7ff74bb2e Merge branch 'feat/docai-backend' into feat/docai-integrated 2026-07-08 21:04:40 +02:00
Marc-André Bombeck 2ecf39c772 chore(documents): format index modules and drop unused helper 2026-07-08 21:02:02 +02:00
Marc-André Bombeck 5e253313fc feat(documents): auto-index uploads for content search, provider-first with local fallback
Index a document for content search automatically the moment it is stored,
instead of requiring a manual index action. A fire-and-forget per-document
job runs an AI-first decision tree: when a vision-capable provider is
configured and consented, transcribe the stored original (rich, handles
scanned PDFs and images), budget-reserved exactly like the interactive index
route; otherwise fall back to server-side text-layer extraction via pdf-parse
(no provider, no egress, milliseconds) so content search works at a baseline
even with no AI. Budget exhaustion, a provider that cannot read the file
(a text-layer PDF on a non-Anthropic account), and provider errors all fall
through to the free local path rather than leave a document unsearchable.

Both paths write the same blind, encrypted content index (AES-256-GCM text +
opaque HMAC token tags) — nothing readable at rest. The local path adds the
'local-pdf' / 'local-ocr' source values (free String column, no migration).
Server-side OCR for scanned images and scanned PDFs is left as a documented
seam. Pin pdf-parse + pdfjs-dist into the standalone trace so the wasm text
extractor ships in the runtime image.
2026-07-08 20:50:30 +02:00
Marc-André Bombeck 6ad2dc858a Merge pull request #438 from MBombeck/release/v1.27.28
Release v1.27.28 — share a document from the document
v1.27.28
2026-07-08 20:48:50 +02:00
Marc-André Bombeck 3829b80aca chore(release): v1.27.28 — share a document from the document 2026-07-08 20:38:27 +02:00
Marc-André Bombeck a887a03c01 Merge branch 'feat/document-share-entrypoint' into release/v1.27.28 2026-07-08 20:34:45 +02:00
Marc-André Bombeck a3276dcfeb Merge pull request #437 from MBombeck/release/v1.27.27
Release v1.27.27 — reorderable hero rings
v1.27.27
2026-07-08 20:33:17 +02:00
Marc-André Bombeck 1305e8d4bc docs(documents): correct the detail-sheet header comment for the Share action 2026-07-08 09:56:15 +02:00
Marc-André Bombeck 46c85e8671 test(documents): share entry point seeds the create flow with the document
Unit: the shared ShareLinkCreateForm mounts bare (Settings default) and
seeded (document flow) — a pre-attached document rides in as a chip with
the label pre-filled. e2e: the document detail Share action opens the
create flow with that document pre-attached and reaches the one-time QR
reveal; marked slow (two stacked sheets + a real create).
2026-07-08 09:50:26 +02:00
Marc-André Bombeck d4009a3587 feat(documents): share action on the document detail sheet
Extract the clinician share-link create flow (create form, document
picker mount, one-time QR + passphrase reveal) from the Settings sharing
section into a reusable ShareLinkCreateForm. Settings mounts it unchanged
alongside the active/revoked lists; the document detail sheet adds a
Share action beside Download that opens the same flow in a bottom sheet
with the current document pre-attached and its title pre-filled as the
label. The one-time QR reveal lands in that sheet, scannable on mobile.

No backend change: the shared POST /api/share-links handles the attached
document set as before.
2026-07-08 09:41:47 +02:00
Marc-André Bombeck 99f3824794 chore(release): v1.27.27 — reorderable hero rings 2026-07-08 09:40:58 +02:00
Marc-André Bombeck abb2db37ee test(dashboard-hero): cover hero-ring-order default + reorder; i18n hint
Add resolveHeroRingOrder unit coverage (default health-score-first,
reconcile against selected set, drop/append, dedupe) plus resolver/serializer
round-trip; hero SSR tests for the default lead + a persisted custom order +
dropped-when-unrendered; Settings picker tests for the pinned health-score
anchor row, its locked-on switch, drag/arrow reorder, and a persisted
non-leading order. Extend the score-rings picker description across six
locales.
2026-07-08 01:23:58 +02:00
Marc-André Bombeck abe688caba feat(dashboard-hero): health-score-first default + reorderable hero rings
Add a persisted hero ring ORDER over the health-score anchor ring plus the
selected score rings. Defaults to the health-score ring on the leading edge;
the user can reorder the full set (health score included) from Settings →
Darstellung with the existing drag-handle + arrow-button pair.

The order rides the dashboard-layout blob (dashboardWidgetsJson) — no
migration. resolveHeroRingOrder reconciles a stored order against the current
ring set on every read/serialize, so a deselected ring drops and a
newly-selected ring appends; the hero orders only the rings it actually
renders.
2026-07-08 01:18:00 +02:00
Marc-André Bombeck b00a2206c5 Merge pull request #436 from MBombeck/release/v1.27.26
Release v1.27.26 — hero and wellbeing card polish
v1.27.26
2026-07-08 00:57:18 +02:00
Marc-André Bombeck 53d8d30bd2 chore(release): v1.27.26 — hero and wellbeing card polish 2026-07-08 00:46:34 +02:00
Marc-André Bombeck 50b628abb8 Merge branch 'feat/hero-and-wellbeing-polish' into release/v1.27.26 2026-07-08 00:42:33 +02:00
Marc-André Bombeck 052ead6bf3 Merge pull request #435 from MBombeck/release/v1.27.25
Release v1.27.25 — documents filter dropdowns
v1.27.25
2026-07-08 00:33:08 +02:00
Marc-André Bombeck 5238fa9923 chore(release): v1.27.25 — documents filter dropdowns 2026-07-08 00:23:23 +02:00
Marc-André Bombeck 96860c69ab Merge branch 'feat/documents-filter-dropdown' into release/v1.27.25 2026-07-08 00:19:29 +02:00
Marc-André Bombeck 4b50ac8b6a feat(documents): make filter dropdowns responsive and update the e2e flows
Give each facet trigger a leading icon and show the text label from sm up
(and on phones only while the facet is active, truncated), so three facets
plus the search never overflow a 360-430px row — the bar stays one line
without a horizontal scroller. Drop the now-dead filter.groupLabel key and
point the vault e2e flows at the dropdown menu items instead of the removed
inline chips.
2026-07-08 00:03:04 +02:00
Marc-André Bombeck 56ca9094c0 Merge pull request #434 from MBombeck/release/v1.27.24
Release v1.27.24 — share documents
v1.27.24
2026-07-07 23:48:48 +02:00
Marc-André Bombeck 7cd317f1a5 feat(dashboard,mental-health): tighten hero gap, link hero rings, move wellbeing attribution to a header info popover
- Dashboard hero: pull the briefing closer to the ring row (md:gap-3 -> md:gap-2); mobile spacing unchanged.
- Each hero ring is now a focusable link to its natural detail: readiness/recovery/sleep -> their score-anatomy page, doses -> the medications surface, health score -> the Insights overview. Real anchors keep tap-vs-drag native on the mobile carousel.
- Mental-wellbeing: shorten the page title to the short noun form (matches the nav/module label) across all six locales.
- Instrument cards: move the required attribution/licence line off the space under the Start button to a discreet info control at the top-right of the header; a popover carries the verbatim citation. Start now stands alone.
2026-07-07 23:34:58 +02:00
Marc-André Bombeck f3a93b3439 test(e2e): mark the heavy share-lifecycle and med-wizard flows slow
Both are legitimately long end-to-end flows — the share test spans two
browser contexts (owner create + picker, recipient unlock, multiple
document serves, revoke), and the med wizard gates its Next button on
per-step validation. On a loaded CI runner the default 30s timeout races
the settle; test.slow() triples it so transient runner contention stops
flaking green flows.
2026-07-07 23:30:19 +02:00
Marc-André Bombeck 71698f3248 feat(documents): replace inline type-chip row with compact dropdown filters
The vault filter bar rendered the type/condition/year facets as a
horizontally-scrolling chip set beside the search field, which wrapped to a
second line on phones. Replace it with three compact dropdown facets — type
(multi-select), condition and year (single-select) — that share one
non-wrapping row with the flexing search and the clear control at every
width. The content-search hint keeps its own helper line below.
2026-07-07 23:29:24 +02:00
Marc-André Bombeck 97163d1e24 chore(release): v1.27.24 — share documents 2026-07-07 23:08:19 +02:00
Marc-André Bombeck 77f7caf4bf Merge branch 'feat/vault-p3-qa' into release/v1.27.24 2026-07-07 23:04:20 +02:00
Marc-André Bombeck 33c383b6b9 Merge pull request #433 from MBombeck/release/v1.27.23
Release v1.27.23 — dashboard hero polish
v1.27.23
2026-07-07 22:09:06 +02:00
Marc-André Bombeck 1face234cc test(share-links): end-to-end document share, serve, and revoke lifecycle
Adds a Playwright spec that drives the public sharing surface against the
production server and a real Postgres: the owner picks documents into a new
link through the Settings picker, a recipient unlocks it with the passphrase
and pulls each blob through the token-scoped serve route, and a revoke closes
it. Pins the load-bearing guarantees end to end — frozen-set confinement (an
owned but un-attached document 404s), the serving posture (Class A inline with
true type + nosniff + no-store, Class B opaque octet-stream attachment), the
EXIF/GPS strip on the shared image, revocation enforced at serve time, and the
scannable QR promotion at the mobile width.

Seeds a fixed share trio (inline PDF, Exif-bearing JPEG, download-only text)
through the same Postgres transport the vault fixture already uses.
2026-07-07 22:00:27 +02:00
Marc-André Bombeck 788996b934 test(share-links): drop the unused owner binding in the ownership guard
The foreign-document ownership test only needs owner A's upload to exist;
it seeded the user into a discarded local. Call it for its effect instead
so lint stays clean.
2026-07-07 22:00:14 +02:00
Marc-André Bombeck d2048fa171 chore(release): v1.27.23 — dashboard hero polish 2026-07-07 21:59:48 +02:00
Marc-André Bombeck 9298e7ca9f Merge branch 'feat/hero-ring-carousel' into release/v1.27.23 2026-07-07 21:56:00 +02:00
Marc-André Bombeck 829345a57b fix(sharing): keep the document cap literal client-side (no DB import leak) 2026-07-07 21:25:17 +02:00
Marc-André Bombeck e734c161f4 test(documents): clinician doc list + share picker/QR + i18n x6 2026-07-07 21:19:58 +02:00
Marc-André Bombeck fdc0f83a47 feat(documents): share document picker, clinician document list, mobile QR 2026-07-07 21:15:19 +02:00
Marc-André Bombeck 9ff39b5846 Merge branch 'feat/vault-p3-backend' into feat/vault-p3-integrated
# Conflicts:
#	prisma/schema.prisma
2026-07-07 21:03:04 +02:00
Marc-André Bombeck ee98a0c738 feat(dashboard): swipeable one-ring carousel on mobile hero, tighter desktop drop
Below md the hero wellness rings no longer wrap into a multi-row grid;
a dependency-free CSS scroll-snap track shows one ring centred at a time
with dot indicators, native touch/keyboard swipe, and reduced-motion
respected. At md and up the same nodes revert to the inline
right-aligned row unchanged. Desktop tightens the greeting/ring-row drop
to the briefing one step (md:gap-3).
2026-07-07 20:53:40 +02:00
Marc-André Bombeck 945e8b8df4 Merge pull request #432 from MBombeck/release/v1.27.22
Release v1.27.22 — document assist and content search
v1.27.22
2026-07-07 20:48:59 +02:00
Marc-André Bombeck 1545f3ec00 test(e2e): wait for the settled sidebar width on the iPad-portrait guard
The tablet icon-rail collapse is mounted-gated (SSR and the hydration
frame paint the expanded 256px shell to avoid a React #418 mismatch),
so the resolved layout lands on the first client render after hydration
settles. On a loaded runner that can arrive just after networkidle,
letting the guard measure a mid-hydration frame (main=512 instead of
~704). Wait for the content column to reach its settled width before
measuring; a real regression still fails via the wait timing out.
2026-07-07 20:38:32 +02:00