Adds count (required) and happenedAtUntil (optional) to the TypeScript DTO so
Chronik + DashboardActivityFeed can consume rollup rows type-safely.
Part of #285.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ProgressRing renders SVG + percentage label as a flex column (~52px
total). With items-center, the contributor circles aligned to the middle
of the full block, placing them 8px below the ring center. Changed to
items-start on the container and wrapped ContributorStack in h-9 (36px =
SVG height) flex items-center so both circles center at the same 18px.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolved 9 conflicts:
- AuditLogQueryRepository/Service: keep HEAD (findRecentContributorsForDocuments)
- ContributorStack: merge main key fix + text-[10px] with HEAD safeColor + aria
- DashboardResumeStrip: merge main text-[10px] with HEAD safeColor
- +page.server/svelte + tests: keep HEAD (pure dashboard, no isDashboard)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace (actor.name ?? actor.initials + i) with (actor.initials + '-' + actor.color)
to fix operator-precedence bug that made keys order-dependent when name is null
- Add role="img" + aria-label={actor.name ?? actor.initials} so screen readers
and touch users can access contributor names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- +layout.svelte: Upload button in header (authenticated users only)
- +page.server.ts: call /api/dashboard/resume, /pulse, /activity;
remove deprecated /api/documents/incomplete and /recent-activity
- +page.svelte: 2-col grid layout (main + 320px sidebar), greeting,
DashboardFamilyPulse + DashboardActivityFeed in sidebar
- DashboardResumeStrip: refactored to use server data (resumeDoc prop),
SVG thumbnail, progress bar with aria-*, empty state, CTA
- DashboardFamilyPulse: new component — weekly stats from audit_log
- DashboardActivityFeed: new component — activity feed with "für dich" badge
- Update specs for new data shapes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds DashboardResumeDTO, DashboardPulseDTO, ActivityFeedItemDTO,
ActivityActorDTO and the three /api/dashboard/* paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DashboardResumeStrip: text-[10px] → text-xs on collaborator initials (WCAG 1.4.4)
- documents/+page.server.ts: use !result.response.ok per CLAUDE.md; keep narrow try/catch for network-level failures only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ContributorStack: text-xs for WCAG 1.4.4 (was text-[10px]), safeColor()
validation to block CSS injection via actor.color, role="img" aria-label
on empty placeholder, {#each} keyed by index
- ContributorStack spec: update empty-state assertion to getByRole('img')
- DocumentRow spec: add stopPropagation regression test for tag click
- documents/page.svelte.spec.ts: new — debounce, URL building, initial state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace (actor.name ?? actor.initials + i) with (actor.initials + '-' + actor.color)
to fix operator-precedence bug that made keys order-dependent when name is null
- Add role="img" + aria-label={actor.name ?? actor.initials} so screen readers
and touch users can access contributor names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- +layout.svelte: Upload button in header (authenticated users only)
- +page.server.ts: call /api/dashboard/resume, /pulse, /activity;
remove deprecated /api/documents/incomplete and /recent-activity
- +page.svelte: 2-col grid layout (main + 320px sidebar), greeting,
DashboardFamilyPulse + DashboardActivityFeed in sidebar
- DashboardResumeStrip: refactored to use server data (resumeDoc prop),
SVG thumbnail, progress bar with aria-*, empty state, CTA
- DashboardFamilyPulse: new component — weekly stats from audit_log
- DashboardActivityFeed: new component — activity feed with "für dich" badge
- Update specs for new data shapes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds DashboardResumeDTO, DashboardPulseDTO, ActivityFeedItemDTO,
ActivityActorDTO and the three /api/dashboard/* paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add * to Datum and Absender labels (both are required fields)
- Add required prop to PersonTypeahead to show * in its label
- Move "Optional" divider in DescriptionSection to after Titel (the only
required field), so Tags and Inhalt appear below the divider where they belong
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds label_required_fields to all three locales. Fixes "Datei ersetzen"
toolbar colors to use semantic ink tokens (readable in both light and dark
pdf-bg themes).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract DocumentEditLayout shared component for the PDF+form split-panel
UI, replacing the old scrolling layout on /documents/[id]/edit with the
same fixed-panel structure used by /enrich/[id]. Removes TranscriptionSection
and FileSectionEdit from the edit page; file upload/replace is now handled
by the shared layout. Delete SaveBar and FileSectionEdit as dead code.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- error_file_upload_failed key used in enrich upload handler
- label_optional key added (de/en/es) and used in DescriptionSection divider
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- text-[9px]/text-[10px] in required-fields bar raised to text-xs (12px),
meeting the project minimum for the 60+ audience (WCAG 1.4.4)
- Upload animation now uses motion-safe: prefix so it stops for users
with prefers-reduced-motion set (WCAG 2.1 SC 2.3.3)
- Strengthened UploadZone tests: onCancel uses [role=status] button
selector instead of first-button heuristic; added positive file
selection test (valid PDF calls onFile), file-too-large test, and
MIME rejection now also asserts the error message is visible
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Field order: Titel → Schlagworte → Kurzinhalt → [Optional divider] → Aufbewahrungsort.
currentTitle is now bindable so the enrich page can derive the required-fields progress bar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Required fields (Datum, Absender) move to row 1; optional fields (Empfänger, Ort)
to row 2. dateIso is now bindable for the progress bar. Autofocus lands on the
first empty required field on page load.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>