Blockers (14):
- B1: fix senderName/receiverName to use $derived instead of $state + sync $effect
- B2: migrate all korrespondenz components from messages-extra shim to paraglide m.*
- B3: i18n CorrespondenzEmptyState (heading, subtext, search placeholder)
- B4: add response.ok checks to admin layout server load
- B5: add response.ok checks to korrespondenz page server load
- B6: add page.server.spec.ts with 5 test suites for korrespondenz load function
- B7: add axe-core accessibility checks to all e2e korrespondenz tests
- B8: add Testcontainers JPQL tests for findSinglePersonCorrespondence (DISTINCT + sender)
- B9: hide auth reset-token endpoint from OpenAPI spec; remove from generated api.ts
- B11: replace amber hardcoded hex colors in SinglePersonHintBar with brand tokens
- B12: replace clipboard emoji with Heroicons SVG in SinglePersonHintBar
- B13: create DateInput component (German dd.mm.yyyy); use it in CorrespondenzFilterControls
- B14: add Paraglide compile step to CI workflow before lint/test
Suggestions (11):
- S1: make CorrespondentSuggestionsDropdown a pure display component; lift fetch to PersonBar
- S2: fix leftover messages-extra import in ConversationTimeline; use brand tokens for status dots
- S3: add intent comment to EntityNav openFlyout behavior
- S4: rename canManageGroups → canManagePermissions throughout admin
- S6: remove domFlush helper from DateInput spec; use expect.poll instead
- S7: replace test.skip with throw new Error in bilateral e2e tests
- S8: add inverse aria-disabled test for filter strip
- S9: remove sm:min-h-0 from sort button to preserve 44px touch target
- S10: add title attributes to tablet trigger buttons in EntityNav
- S11: delete messages-extra.ts shim entirely
Also: fix admin pages revealing blank strip at bottom (-mb-6 on admin layout)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /forgot-password: email form → sends POST /api/auth/forgot-password → success banner
- /reset-password: password form reads token from URL → sends POST /api/auth/reset-password
- Login page: add "Passwort vergessen?" link
- hooks.server.ts: add /forgot-password and /reset-password to PUBLIC_PATHS; skip auth
injection for public auth API endpoints
- errors.ts: add INVALID_RESET_TOKEN error code
- i18n: add all new message keys in de/en/es
- playwright.config.ts: use E2E_BASE_URL for webServer check URL (allows reusing docker
dev server at port 5173 locally)
- ci.yml: pass E2E_BACKEND_URL=http://localhost:8080 to E2E test step
- e2e/password-reset.spec.ts: 5 tests (4 pass locally, full flow requires e2e profile in CI)
- Regenerated OpenAPI types including new /api/auth/* endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Pre-commit hook
- Add .husky/pre-commit at repo root: runs `cd frontend && npm run lint`
- Update prepare script in package.json to auto-configure git hooks path
on npm install (git -C .. config core.hooksPath .husky)
- Add lint step to CI unit-tests job so it catches issues before tests run
- Add generated dirs to .prettierignore (paraglide_bak*, test-results, .auth)
- Add src/lib/paraglide_bak* to .gitignore so ESLint can ignore them
## ESLint fixes (all pre-existing)
- Disable svelte/no-navigation-without-resolve: false positive in SvelteKit
(rule targets Svelte 5 standalone routing, not SvelteKit <a href>)
- Fix svelte/require-each-key: add (item.id)/(item) keys to all {#each} blocks
across 10 files — improves Svelte reconciliation performance
- Fix svelte/prefer-writable-derived in PersonTypeahead: $state+$effect → $derived
- Fix svelte/prefer-svelte-reactivity: URLSearchParams → SvelteURLSearchParams,
Map → SvelteMap (enables Svelte reactive tracking)
- Fix @typescript-eslint/no-unused-vars: remove dead imports/variables
## Prettier
- Run npm run format to bring all source files in line with .prettierrc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch unit-tests job to mcr.microsoft.com/playwright:v1.58.2-noble
container; Chromium and all system deps are pre-installed so the
browser install/cache dance is eliminated entirely (closes#13)
- Downgrade upload-artifact@v4 → v3 in both unit-tests and e2e-tests
jobs; v4 is not supported on Gitea (GHES) and was causing jobs to
report failure even when all tests passed, and prevented the
Playwright browser cache from ever being saved (closes#14)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The runner's Docker client negotiates API 1.53 but the daemon on the
NAS only supports up to 1.43. Pin the version for all docker commands
in the e2e job, including the new network connect step.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The act_runner job runs inside a Docker container. Docker Compose port
mappings bind to the Docker host, not the job container's localhost —
so localhost:5433 was always refused.
Fix: after compose starts, connect the job container (identified by
/etc/hostname) to the archive-net compose network. Then switch the
backend startup args to use service names db:5432 and minio:9000
instead of host-mapped ports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The e2e job was calling plain `docker compose up` without the CI
override file, so it used the base compose bind-mount for MinIO
(./data/minio) which doesn't exist on the runner. The CI override
replaces bind mounts with ephemeral named volumes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The built-in cache: maven in setup-java@v4 does not reliably work
on self-hosted act runners. Replace with an explicit actions/cache@v4
on ~/.m2/repository keyed on pom.xml hash.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
node_modules and the Playwright Chromium binary were downloaded fresh
on every run, making setup account for ~99% of pipeline runtime.
- Cache frontend/node_modules keyed on package-lock.json hash
- Cache ~/.cache/ms-playwright keyed on package-lock.json hash
- On cache hit: skip npm ci and browser download, only reinstall
system deps (install-deps) which is much faster than a full install
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avoids conflicts with any system services (PostgreSQL, MinIO) that
may already occupy 5432/9000/9001 on the runner host.
DB: 5433, MinIO API: 9100, MinIO console: 9101.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Port 5432 was already in use after docker compose cleanup because a
system-level PostgreSQL service on the runner host holds the port.
Also kill any stray containers binding to 5432/9000/9001.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs ./mvnw clean test in a dedicated job — no DB or S3 needed
since all tests use Mockito or WebMvcTest slices.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Port 5432 was already bound by a zombie container from a previous
failed run, preventing docker compose from starting the DB.
Add a cleanup step at the top of the e2e job to ensure a clean state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The act runner does not have the standalone docker-compose binary.
Replace both occurrences with the v2 plugin syntax (space instead of hyphen).
Closes#3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>