Skip to content

v1.1.0

Latest

Choose a tag to compare

@astrapi69 astrapi69 released this 02 May 10:36
· 97 commits to main since this release

First post-1.0.0 minor release. Closes Phases 4 (Documents), 4b (ePA
Import), 5 (Export), 6 (Backup), Phase ONB (Onboarding restructure),
Phase 2 manual-entry (O-10..O-20), DOC-01 Iteration 1, the AIP-01..05
Multi-AI-Provider series (ADR-0019), the bulk of Phase 7 polish, and a
toolchain refresh (React 19, TypeScript 6, Vite 7, Vitest 4, Tailwind 4,
Node 24).

The vault format is fully backward-compatible with v1.0.0: the
single-shape MetaPayload.aiConfig migrates automatically on read to
the new multi-shape MultiProviderAIConfig (see ADR-0019). No user
action required to upgrade.

Added

AI assistant

  • Multi-AI-Provider support (AIP-01..05): the AI assistant now talks to seven provider presets (Anthropic, OpenAI, Google, Mistral, LM Studio, Ollama, custom) through a multi-adapter LLMClient (Anthropic native + OpenAI-compatible). New aiStream helper at src/features/ai/aiCall.ts unifies streaming text across providers and replaces the deleted streamCompletion / anthropicClient.ts; useChat and requestCleanup migrate transparently. Storage-layer change: MetaPayload.aiConfig evolves from a single AIProviderConfig to MultiProviderAIConfig = { providers: AIProviderConfig[]; activeProviderId }; legacy single-shape vaults migrate automatically on read with a defence-in-depth parser (malformed entries dropped, duplicate ids deduplicated last-wins, activeProviderId repaired when it points outside the list). UI-layer change: AISettingsSection is now a 230-LOC summary view with provider label + masked API key + model + "Anbieter verwalten" / "KI deaktivieren" buttons; the new three-step AiSetupWizard mounts via React.lazy + Suspense fallback={null} so the wizard chunk only ships when the user clicks. CORS-blocked providers (OpenAI, Mistral) save with a clear amber warning on wizard step 2 explaining that browser-direct calls require a proxy Phylax does not yet provide. Decision A2 keeps requestCompletion + tool_use Anthropic-only because cross-provider tool-call protocols differ; a generic structured-output abstraction is a deliberate future task. Foundation reused: master-password-derived AES-GCM-256 key (ADR-0001), encrypted meta.payload blob, ADR-0018 P-06 reencryption pipeline (multi-provider AI config rides along, no TABLES_TO_REENCRYPT change). Architecture documented in ADR-0019; manual smoke at docs/manual-smoke/ai-multi-provider.md.

Documents and import

  • Phase 4 - Document management (D-01..D-10): encrypted attached-document storage (PDFs, images), inline viewer with image / PDF rendering paths, link / unlink to observations and lab values, persistent-storage banner and quota indicator, mobile-first list with pagination, delete with cascade warning.
  • Phase 4b - ePA / document import (IMP-01..06): user uploads a PDF, image, or insurer-app export; the AI classifies the document type, extracts structured entries (observations / lab values / supplements / open points) with per-field provenance back to the source document. Per-type review screen with merge / replace / skip toggles; commit transaction is atomic (ADR-0017 PDF stack). Source-document upload preserved alongside the extracted entries.
  • IM-04 auto-version-entry: the markdown importer now emits a profile-version entry automatically per import so the version history reflects the AI-assisted timeline without manual tracking.
  • IM-05 per-type replace toggles plus Option B merge dialog: import-replace dialog gained per-entity-type Add / Replace / Skip toggles; Option B merge UX rewrite landed 2026-05-01 (commit 8e93964) so the dialog reads "Import in bestehendes Profil" with each row gating the confirm button until a mode is chosen.

Export

  • Phase 5 - Multi-format export (X-01..X-08): Markdown export (X-01), PDF export with date-range filter (X-02 / X-03, ADR-0020 jspdf-autotable), theme whitelist (X-04), linked-documents appendix (X-05), CSV export of lab values (X-06), live preview before download (X-07), per-format save-as flow (X-08). All export paths run through the same useExportData hook so filters apply uniformly.

Backup and restore

  • Phase 6 - Encrypted backup round-trip (B-01..B-04, B-06, B-07): single-file .phylax backup encrypted under the current master key with vault-version metadata, manifest, and per-table ciphertext blocks; restore validates the manifest, decrypts every block under the typed password, and bulk-puts atomically into a fresh database via the same Dexie transaction primitive used for import. Source documents and provenance metadata round-trip.

Onboarding

  • Phase ONB - Onboarding UX restructure (ONB-01a..f): split the master-password setup into a paced multi-step flow with explicit consent boxes, masked API-key field, recovery-warning copy, and zxcvbn strength meter inline (ADR-0014). Replaces the original single-screen onboarding from F-12.

Phase 7 polish

  • Phase 2 manual-entry CRUD (O-10..O-19) and the shared modal primitive (O-20): every entity (observation, lab value, supplement, open point, document) now supports manual create / edit / delete via inline forms backed by the shared <Modal> and <ConfirmDialog> primitives at src/ui/Modal/.
  • Mobile-first viewport sweep (P-01) with manual-smoke artifact at docs/manual-smoke/p-01-mobile-sweep.md.
  • Auto-lock presets (P-05): Settings section gains 1 / 5 / 15 / 30-minute presets plus a "never" toggle (with a security warning); the configurable timeout from F-14 stays the source of truth.
  • Polish series P-07-a/b/c: focus-trap regressions, reduced-motion honour for scroll-into-view, and consistent button hit-targets at 360 px.
  • Time-to-interactive perf pass (P-08): trim setup-chunk imports, defer non-critical lazy chunks behind user intent.
  • Top-level error boundary (P-09): single React class component at src/ui/ErrorBoundary.tsx mounted in src/main.tsx between StrictMode and the theme provider. Catches render-phase errors from any descendant and shows a localized friendly fallback with two recovery actions (Reload + Go-Home) plus a collapsible <details> block carrying error message + stack + component stack so users can copy-paste the diagnostic into a manual bug report. console.error for dev visibility; no telemetry per CLAUDE.md (no Sentry, no auto-submission). Per-route boundaries deferred until a concrete failure mode justifies them. Manual smoke at docs/manual-smoke/p-09-error-boundary.md.
  • Change master password (P-06): re-encrypts the entire vault under a new key via a three-phase pipeline (decrypt-encrypt outside Dexie tx, atomic bulkPut + meta.put inside one transaction, in-memory keyStore swap). Settings section + confirmation modal + busy-state UI; sudo-pattern verification re-derives the candidate key from the typed current password and decrypts the meta verification token before any work begins. Auto-lock paused for the duration via a new reference-counted pause primitive (src/features/auto-lock/pauseStore.ts) reusable for backup-restore and other long-running operations. Same salt preserved (PBKDF2 does not need salt rotation per password). Manual smoke at docs/manual-smoke/p-06-change-password.md.
  • License footer (P-12): MIT-license link in the app footer.
  • Trigger criteria for deferred polish markers (P-13 / P-14 / P-15): each carries an explicit "ship when X happens" line in the ROADMAP.
  • Inline document-row delete (P-16): /documents list rows now carry a 44 x 44 trash-icon button as a sibling of the navigation <Link> (avoids the WCAG nested-interactive violation O-10 surfaced). Trigger opens the same destructive <ConfirmDialog> used on the viewer page, with cascade-warning copy for documents linked to observations or lab values. On confirm the row vanishes via an onDeleted callback that bumps the versionKey on DocumentList. Aria-label on the trigger names the filename so screen-reader users disambiguate across rows. Manual smoke at docs/manual-smoke/p-16-document-row-delete.md.
  • ResetDialog migration to the shared modal primitive (P-17).
  • Highlighted-match polish across search views (P-19).
  • Cross-feature search and row-level match navigation (P-22a/b/c/d): instant search across observations, lab values, supplements, open points, documents. P-22b/c/d adds Up / Down chevrons next to the match counter; Enter / Shift-Enter on the search input drives the same. Each rendered row / group carries a data-match-row attribute; clicking a chevron scrolls the next matched row into view via scrollIntoView({ block: 'center' }) honouring prefers-reduced-motion (P-07-c precedent). Counter switches to "{current} von {total} Treffer" while nav active (matches Observations UX). useActiveMatch lifted to src/lib/; MatchNavButton extracted to src/ui/ for reuse across all four search views. Manual smoke at docs/manual-smoke/p-22-b-c-d-match-nav.md.

Internationalisation

  • I18N-02 series (a..e): English translations of every namespace plus the runtime auto-detection switcher; v1.0.0's German UI is now bilingual at runtime with a manual override.

User documentation

Changed

  • Service-worker update mode flipped from autoUpdate (with a "New version available, reload" toast) to registerType: 'prompt' + skipWaiting: true + clientsClaim: false (BUG-01, third iteration). Users get the new version on the next reload silently; the regression-guard test at src/pwa/viteConfigPwa.test.ts locks the option set.
  • App-shell navigation replaced the bottom-nav with a hamburger drawer (BUG-02) so the navigation surface scales with screen height instead of competing with mobile keyboard insets.
  • Toolchain refresh (DEPS-01..03 + ADR-0021): React 18 -> 19.2.5 (ADR-0021), TypeScript -> 6, Vite 6 -> 7, Vitest 3 -> 4 (coverage thresholds recalibrated in ADR-0016), Tailwind 3.4 -> 4, Node 22.12 floor then bumped to Node 24 to match the runtime in CI. No source changes were required for the React major.
  • Locked dependency list in .claude/rules/coding-standards.md aligned with package.json: pdfjs-dist (ADR-0017), jspdf-autotable (ADR-0020), and the tooling shims (@eslint/js, ESLint plugins, type packages, Tailwind PostCSS bridge, @resvg/resvg-js) are now declared.
  • Bundle-budget table in .claude/rules/quality-checks.md now includes the pdf.js (130 KB) and jsPDF (140 KB) lazy-chunk slots that ship with Phase 4b and Phase 5.
  • Em-dash sweep across src/, docs/, and the user-facing locale strings: ~200 occurrences replaced per the no-em-dash rule in CLAUDE.md.

Fixed

  • BUG-01 silent service-worker updates (3 iterations): regressions caused by the original autoUpdate toast confused users; the prompt-mode silent-update model resolves them.
  • BUG-02 hamburger drawer: replaces the bottom-nav that broke on mobile keyboard.
  • BUG-03 / 04 / 05 / 06 documents fixes: linked-entity surfacing, delete-cascade visibility, viewer focus-trap, MIME-type detection edge cases.
  • BUG-07 / 08 / 09 / 10 ai-config fixes: API-key masking via CSS (BUG-10), dropdown timing on the wizard, settings refresh after save (BUG-08), webkit-on-CI smoke regressions, plus general resilience around config persistence.
  • E2E production-build regressions: webkit zxcvbn timing on Phylax einrichten button, import-confirm dialog heading rename, and the webkit driver bug on navigation while offline (skipped on webkit; chromium and firefox cover the offline-cache contract).

Security

  • Architecture decision: ADR-0019 documents the Multi-AI-Provider architecture: adapter pattern via LLMClient, Phylax crypto reuse (no parallel encryption pipeline), Decision A2 streaming-vs-structured-output split, single-shape -> multi-shape migration on read with idempotent defence-in-depth, lazy-load wizard, and the donor extraction lessons (two donor bugs caught and fixed during integration: verifyOpenAI AbortError swallow -> re-throw, LLMClient.postJson AbortError wrap -> re-throw). Multi-provider AI configurations ride on the existing encrypted meta.payload blob; the ADR-0018 P-06 reencryption pipeline handles them automatically without a TABLES_TO_REENCRYPT change.
  • Architecture decision: ADR-0018 documents the change-master-password three-phase pipeline, the sudo-pattern verification, the same-salt rationale, the reference-counted auto-lock pause, the no-cancellation policy, the Phase 2 commit + Phase 3 throw recovery path, and the deferred memory-streaming trigger.
  • Architecture decision: ADR-0017 introduces pdfjs-dist for client-side PDF parsing in the Phase 4b document-import pipeline; bundling the worker (no CDN fetch at runtime) preserves the no-third-party-network-call posture.
  • Architecture decision: ADR-0020 introduces jspdf-autotable for tabular sections of the PDF export; co-loaded with jsPDF in the same lazy chunk; no new external resources.

Technical-debt cleanups

  • TD-02 React 19 upgrade (now backfilled as ADR-0021).
  • TD-03 / 04 / 05 / 06 / 07 toolchain modernisation (DEPS-01..03 + Vitest 4 coverage recalibration via ADR-0016).
  • TD-12 modal sweep: seven dialog migrations onto the shared <Modal> / <ConfirmDialog> primitive (O-20) so all destructive flows share the same focus-trap and escape semantics.