Commit Graph

12 Commits

Author SHA1 Message Date
Marcel
63acb5417f feat(ui): add sheet surface token between canvas and white cards
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m56s
CI / OCR Service Tests (pull_request) Successful in 26s
CI / Backend Unit Tests (pull_request) Successful in 4m8s
CI / fail2ban Regex (pull_request) Successful in 44s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m10s
The reading sheet used bg-surface (white), so the document cards inside
the article had the same background as the sheet itself. The spec's
three-level hierarchy is canvas → article panel (#FAFAF7) → white cards;
introduce --color-sheet (mode-aware) and use it on the article. Also
move JourneyItemCard from bg-white to bg-surface so dark mode remaps it,
and tint the curator annotation with bg-muted so it stands off the card.

Refs #797
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 22:32:10 +02:00
Marcel
b926bdefde feat(geschichte-detail): render article on a reading-sheet surface card
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m59s
CI / OCR Service Tests (pull_request) Successful in 23s
CI / Backend Unit Tests (pull_request) Successful in 4m12s
CI / fail2ban Regex (pull_request) Successful in 43s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m11s
The R-2 mockup shows the article on a distinct light panel, but the
impl-ref table only specified the centered container, so the page
rendered flat on the canvas. Wrap the <article> in the standard card
pattern (BackButton stays outside on the canvas) and record the sheet
in both spec impl-ref tables so mockup and impl-ref agree.

Closes #797
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 22:24:37 +02:00
Marcel
07ed9719e7 feat(geschichte-detail): avatar metabar + doc reference cards per spec R-2/LR-2
Detail header gains the author avatar with a two-line author block;
journeys say 'zusammengestellt am' instead of 'veröffentlicht am'.
Bearbeiten/Löschen move into the metabar for stories too (were at the
article bottom). StoryReader renders real document reference cards
(icon, title, date · von X an Y) instead of a placeholder link, person
chips get avatar initials, and journey items lose the doubled spacing.
Shared formatDocumentMetaLine() in geschichte/utils feeds both readers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 21:59:56 +02:00
Marcel
90a1bd4082 feat(journey-reader): match spec LR-2 — card layout, interlude, badge, actions; inline note in editor row
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3m3s
CI / OCR Service Tests (pull_request) Successful in 24s
CI / Backend Unit Tests (pull_request) Successful in 4m11s
CI / fail2ban Regex (pull_request) Successful in 45s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m5s
JourneyItemCard: restructure from full-<a> to div+card with meta line
(date · von X an Y) and explicit "Brief öffnen →" link; note renders as
mint-border annotation inside the card.

JourneyInterlude: remove ❦ ornament; orange-400 left-border spec classes.

JourneyReader: fix intro classes (dashed border-b); remove bottom author
actions (moved to +page.svelte metabar).

+page.svelte geschichten/[id]: badge above title with spec orange-50 classes;
Bearbeiten/Löschen in metabar right side for isJourney + canBlogWrite.

JourneyItemRow: items-center on main row; drag handle self-center; note
textarea inline in content column (removes border-t section below).

i18n: add journey_item_open, journey_item_meta_from_to to de/en/es.

Tests: update JourneyItemCard + JourneyReader specs to match new structure;
fix datePrecision 'FULL'→'DAY', add receiverCount: 0 to all test fixtures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 19:59:32 +02:00
Marcel
e077dba595 fix(geschichte): stop exposing author email in the list projection
GET /api/geschichten shipped every author's AppUser email to all readers via
GeschichteSummary.AuthorSummary — contradicting the documented rule that
author projections never expose email or group memberships. The frontend
only used it as a display-name fallback; it now falls back to [Unbekannt],
matching the server-side rule in GeschichteService.toView.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 07:25:11 +02:00
Marcel
9be24f2613 fix(tests): resolve 43 regressions caused by layout.css import in test-setup
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m25s
CI / OCR Service Tests (pull_request) Successful in 22s
CI / Backend Unit Tests (pull_request) Successful in 3m46s
CI / fail2ban Regex (pull_request) Successful in 44s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m7s
Importing layout.css in test-setup.ts activated Tailwind's responsive
breakpoint classes (hidden lg:flex, hidden md:block, etc.), making
42 elements invisible at the default narrow Playwright test viewport.

Revert the CSS import. Instead, add inline style attributes to the three
components whose tests measure computed properties (min-height, font-size)
— these values match what the Tailwind classes produce, so the real app
appearance is unchanged.

Also fix goto mock leakage in the geschichten/[id] delete-failure test:
the delete-success test's goto('/geschichten') call was not cleared before
the failure test ran. Add beforeEach(vi.clearAllMocks) to reset mock state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:53:20 +02:00
Marcel
d5441d3e55 fix(tests): resolve 10 failing browser-mode tests
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 6m5s
CI / OCR Service Tests (pull_request) Successful in 22s
CI / Backend Unit Tests (pull_request) Successful in 3m55s
CI / fail2ban Regex (pull_request) Successful in 45s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m4s
- Import layout.css in test-setup so Tailwind utilities (text-xs,
  min-h-[44px]) apply in vitest-browser — fixes computed-style assertions
  for badge font-size and touch-target height
- radioGroupNav: write aria-checked directly on radio buttons on arrow-key
  navigation, not only via the optional onChangeFn callback
- DashboardNeedsMetadata spec: tighten footer-link matcher from /50/ to
  /Alle 50/ — avoids strict-mode collision with row link whose relative
  time text also contains "50" (uploadedAt is exactly 50 days ago today)
- geschichten/[id] page spec: add missing await on userEvent.click before
  confirmService.settle() in both delete tests
- TypeSelector spec: replace storyCard.focus() (not on vitest-browser
  Locator) with userEvent.click(); force-dispatch aria-disabled Weiter
  click via element.click() to bypass Playwright actionability check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:36:56 +02:00
Marcel
7a5c2d0ba3 fix(geschichte): handle DELETE failure — show inline error on non-ok response
Adds deleteError $state to [id]/+page.svelte, parses backend error via
parseBackendError/getErrorMessage on !res.ok, and displays a role=alert
paragraph. Adds two browser-tier tests: success path (goto called) and
error path (alert visible, goto not called).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 08:03:04 +02:00
Marcel
8fea94cb61 test(lesereisen): TDD red — tighten factories, add journey/selector/ssr tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 22:57:28 +02:00
Marcel
df5d880e09 fix(review): GeschichtenCard uses GeschichteSummary type; focus-visible on journey links; fix stale tests
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m17s
CI / OCR Service Tests (pull_request) Successful in 23s
CI / Backend Unit Tests (pull_request) Successful in 3m42s
CI / fail2ban Regex (pull_request) Successful in 47s
CI / Semgrep Security Scan (pull_request) Successful in 22s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m4s
- GeschichtenCard.svelte: use GeschichteSummary instead of Geschichte
  (list endpoint returns summaries; no items/createdAt/updatedAt needed)
- GeschichtenCard.svelte.test.ts: factory returns GeschichteSummary with
  lean author shape; drop Geschichte-only fields (createdAt, groups, etc.)
- geschichten/[id]/+page.svelte: add focus:outline-none focus-visible:ring-2
  focus-visible:ring-focus-ring to journey item document links (WCAG 2.4.7)
- page.svelte.test.ts ([id]): replace stale documents[] factory field with
  items[]; test now checks placeholder text + note caption
- page.svelte.test.ts (new): remove removed initialDocuments from baseData;
  rename test to reflect that only initialPersons is passed through

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 16:01:50 +02:00
Marcel
29015ee864 test: inject real ConfirmService via context (batch 2/2)
Completes Phase 2a: geschichten/[id], persons/[id]/edit and admin/tags/[id]
page specs now provide a real createConfirmService() via render context
instead of mocking confirm.svelte. Zero confirm.svelte vi.mocks remain
across the client suite (AC#4). Part of #560.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 11:38:22 +02:00
Marcel
e5256c89a1 test: cover users/[id], admin/ocr/global, geschichten/[id] page branches
users/[id]: full-name derivation across all four branches
(both/firstName-only/lastName-only/email fallback), avatar initials
matrix, email/contact row visibility tied to data presence.

admin/ocr/global: heading + back link, runs prop pass-through,
defensive default for missing history fields.

geschichten/[id]: title rendering, author full-name vs email fallback
vs null, publishedAt suffix conditional, persons and documents sections
gated on array length, edit/delete actions gated on canBlogWrite. Mocks
the confirm service since it requires a ConfirmDialog mounted in layout.

26 tests across three files.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00