12 Commits

Author SHA1 Message Date
Marcel
7fc1295dc0 build(patch-package): backport vitest PR #10267 for browser-playwright birpc race
Installs patch-package (^8.0.0) and a postinstall script, then applies
the diff from vitest PR #10267 against @vitest/browser-playwright@4.1.0.

What the patch changes (in dist/index.js):

- createPredicate(sessionId, url) → createPredicate(url): factory becomes
  pure, returns { url, predicate } instead of mutating sessionIds /
  idPreficates as a side-effect.
- sessionIds value type: array → Set (deduplicates resolved URLs).
- register handler now looks up any existing predicate for the
  (sessionId, resolvedUrl) pair and unroutes it BEFORE installing the
  new route. This is the actual race fix: without it, the second
  vi.mock for a duplicate-id leaks an orphan Playwright route that
  fires after birpc closes.
- clear handler iterates the Set via spread.

Why this matters even though Layer 1 normalised the only known duplicate
in our suite: every future vi.mock call is a class of race we shouldn't
have to think about. The patch closes the upstream gap at the
route-handler level, so a contributor reintroducing the duplicate-id
pattern can't reopen the race.

When to remove: when @vitest/browser-playwright ships a release
containing PR #10267. Delete patches/@vitest+browser-playwright+4.1.0.patch
and the postinstall hook (or keep the hook if other patches accumulate).

Refs: #553 · vitest-dev/vitest#9957 · vitest-dev/vitest#10267

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 08:08:28 +02:00
Marcel
1a28e3114d build(deps): add @vitest/coverage-istanbul for browser-project coverage
Istanbul instruments code at transpile time and works inside Chromium's
sandbox; v8 coverage is silently a no-op in browser mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 17:21:00 +02:00
Marcel
f26a0f4336 chore(deps): install eslint-plugin-boundaries and add boundary lint scripts
Adds eslint-plugin-boundaries@6.0.2 and eslint-import-resolver-typescript@4.4.4
as pinned devDependencies. Also adds the lint:boundary-demo script for running
the ESLint boundaries rule against the fixture file, and updates the lint script
to exclude __fixtures__ directories.

Refs #410
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 18:09:01 +02:00
Marcel
9e7861fa03 feat(geschichten): frontend foundation — canBlogWrite, sanitize util, nav, i18n
- Derives canBlogWrite in +layout.server.ts the same way as canAnnotate.
- Adds Geschichten link to AppNav (desktop + mobile, between Stammbaum and Admin).
- Adds error_geschichte_not_found mapping to errors.ts and translation keys
  for the Geschichten index, detail, editor, and confirmation copy in
  de/en/es.
- Adds isomorphic-dompurify-backed safeHtml() helper with allow-list
  matching the backend OWASP policy (p/br/strong/em/h2/h3/ul/ol/li),
  plus Vitest spec.
- Updates legacy spec test data so the new required canBlogWrite layout
  prop type-checks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 17:43:29 +02:00
Marcel
f662bd870e chore(deps): add HTML sanitizers for Geschichten rich-text body
Adds OWASP Java HTML Sanitizer on the backend and DOMPurify on the frontend.
Together with Tiptap on the writer side they form a defense-in-depth chain
against XSS in the new Geschichte body field (issue #381).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 17:21:58 +02:00
Marcel
5591f95871 chore(deps): install Tiptap 3.22.5 (core, starter-kit, extension-mention)
Exact version pins — all three packages share ProseMirror peer deps and must
stay in sync. Renovate grouping in renovate.json ensures they bump together.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 15:01:19 +02:00
Marcel
f9236cc575 test(#118): add axe-core wcag2a/wcag2aa accessibility checks to E2E suite
Installs @axe-core/playwright and adds e2e/accessibility.spec.ts covering:
- home, persons, admin (authenticated via stored admin session)
- login (unauthenticated context)

Uses wcag2a + wcag2aa tags. Violations are logged with impact level and
node count before the assertion fails, so the first run against the live
stack will produce a clear inventory of any issues to fix or exclude.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:37:52 +01:00
Marcel
e27af75e21 test(#121): add @vitest/coverage-v8 with 80% branch coverage gate
Installs @vitest/coverage-v8 and configures coverage measurement over
src/lib/utils/** and src/lib/server/** — the utility and server-side
logic that is meaningful to measure in the Node test project.

Svelte component files and generated code (api/**, paraglide/**) are
excluded; those run in the browser project.

Baseline: 87.87% branch coverage — already above the 80% threshold.
Adds test:coverage script for local runs; produces lcov report for CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:36:08 +01:00
Marcel
5fb6a1eec0 feat(frontend): replace iframe with PDF.js viewer (#39)
- Install pdfjs-dist v5 and add optimizeDeps pre-bundle config
- New PdfViewer.svelte component: renders each page on a <canvas> with
  correct device-pixel-ratio scaling, overlays a text layer (enables
  text selection; foundation for annotations in #40), prev/next
  navigation, zoom controls, and lazy page rendering (only current ±1
  pre-fetched — avoids freezing on multi-page documents)
- Replace the <iframe> in documents/[id]/+page.svelte with PdfViewer;
  image attachments continue to use <img>; detection now uses
  doc.contentType instead of filename extension
- Unit tests for navigation controls and page counter (pdfjs mocked)
- E2E tests: PDF renders as canvas (not iframe), nav controls visible,
  image fallback stays as <img>; minimal.pdf fixture for upload tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 19:10:02 +01:00
Marcel
d4b1a709d7 feat(frontend): add document history panel with diff and compare mode
Adds a collapsible history section to the document detail view, showing
all saved versions with changed-field labels, word-level diff between
adjacent versions, and a compare mode for any two arbitrary versions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 11:57:33 +01:00
Marcel
7cb20dec50 test: add e2e tests 2026-03-17 13:34:05 +00:00
Marcel
e63adb964d restructure: flatten workspace nesting, move devcontainer to root
- backend/workspaces/backend/ → backend/
- backend/workspaces/frontend/ → frontend/
- backend/.devcontainer/ + .vscode/ → repo root (where VS Code expects them)
- loose scripts/SQL files → scripts/
- replace nested git repo with single repo at project root
- update docker-compose.yml build context and devcontainer.json path
- add root .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 11:47:58 +01:00