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). NewaiStreamhelper atsrc/features/ai/aiCall.tsunifies streaming text across providers and replaces the deletedstreamCompletion/anthropicClient.ts;useChatandrequestCleanupmigrate transparently. Storage-layer change:MetaPayload.aiConfigevolves from a singleAIProviderConfigtoMultiProviderAIConfig = { 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,activeProviderIdrepaired 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-stepAiSetupWizardmounts viaReact.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 keepsrequestCompletion+tool_useAnthropic-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), encryptedmeta.payloadblob, ADR-0018 P-06 reencryption pipeline (multi-provider AI config rides along, noTABLES_TO_REENCRYPTchange). Architecture documented in ADR-0019; manual smoke atdocs/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
useExportDatahook so filters apply uniformly.
Backup and restore
- Phase 6 - Encrypted backup round-trip (B-01..B-04, B-06, B-07): single-file
.phylaxbackup 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 atsrc/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.tsxmounted insrc/main.tsxbetween 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.errorfor 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 atdocs/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 atdocs/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):
/documentslist 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 anonDeletedcallback that bumps theversionKeyonDocumentList. Aria-label on the trigger names the filename so screen-reader users disambiguate across rows. Manual smoke atdocs/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-rowattribute; clicking a chevron scrolls the next matched row into view viascrollIntoView({ block: 'center' })honouringprefers-reduced-motion(P-07-c precedent). Counter switches to "{current} von {total} Treffer" while nav active (matches Observations UX).useActiveMatchlifted tosrc/lib/;MatchNavButtonextracted tosrc/ui/for reuse across all four search views. Manual smoke atdocs/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
- DOC-01 Iteration 1 (e): user-facing documentation site at https://astrapi69.github.io/phylax-docs/ with parallel DE+EN content covering Getting Started, Daily Use, Backup, FAQ, and Background.
Changed
- Service-worker update mode flipped from
autoUpdate(with a "New version available, reload" toast) toregisterType: 'prompt'+skipWaiting: true+clientsClaim: false(BUG-01, third iteration). Users get the new version on the next reload silently; the regression-guard test atsrc/pwa/viteConfigPwa.test.tslocks 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.mdaligned withpackage.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.mdnow 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
autoUpdatetoast 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 einrichtenbutton, 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:verifyOpenAIAbortError swallow -> re-throw,LLMClient.postJsonAbortError wrap -> re-throw). Multi-provider AI configurations ride on the existing encryptedmeta.payloadblob; the ADR-0018 P-06 reencryption pipeline handles them automatically without aTABLES_TO_REENCRYPTchange. - 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-distfor 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-autotablefor 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.