refactor(person-mention): hoist LoadState + HoverData into shared types module

Markus flagged the LoadState export from PersonHoverCard.svelte as a
view-vs-orchestrator boundary smell — both files own the same shape, and a
third caller (admin previews, briefwechsel cards) would create a circular
import. Move the types into src/lib/types/personHoverCard.ts so the contract
is module-stable.

Also harden .prettierignore + eslint.config.js so a stray .svelte-kit.old/
backup directory (rotated by SvelteKit during dev) doesn't break the lint
hook — matches the existing .svelte-kit-backup/ convention.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-29 08:46:42 +02:00
parent ae868f4110
commit 6a6967d841
5 changed files with 28 additions and 10 deletions

View File

@@ -11,6 +11,7 @@ bun.lockb
# Build artifacts
/.svelte-kit/
/.svelte-kit-backup/
/.svelte-kit.old/
# Generated files
/.svelte-kit-backup/

View File

@@ -12,7 +12,7 @@ const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
export default defineConfig(
includeIgnoreFile(gitignorePath),
{ ignores: ['src/paraglide/**'] },
{ ignores: ['src/paraglide/**', '.svelte-kit.old/**'] },
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,

View File

@@ -2,15 +2,10 @@
import { m } from '$lib/paraglide/messages.js';
import { formatLifeDateRange } from '$lib/utils/personLifeDates';
import type { components } from '$lib/generated/api';
import type { LoadState } from '$lib/types/personHoverCard';
type Person = components['schemas']['Person'];
type RelationshipDTO = components['schemas']['RelationshipDTO'];
export type LoadState =
| { status: 'loading' }
| { status: 'error' }
| { status: 'loaded'; person: Person; relationships: RelationshipDTO[] };
type Props = {
personId: string;
cardId: string;

View File

@@ -3,15 +3,14 @@ import type { TranscriptionBlockData } from '$lib/types';
import type { components } from '$lib/generated/api';
import { splitByMarkers } from '$lib/utils/transcriptionMarkers';
import { renderTranscriptionBody } from '$lib/utils/mention';
import PersonHoverCard, { type LoadState } from './PersonHoverCard.svelte';
import PersonHoverCard from './PersonHoverCard.svelte';
import type { HoverData, LoadState } from '$lib/types/personHoverCard';
import { goto } from '$app/navigation';
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
type Person = components['schemas']['Person'];
type RelationshipDTO = components['schemas']['RelationshipDTO'];
type HoverData = { person: Person; relationships: RelationshipDTO[] };
interface Props {
blocks: TranscriptionBlockData[];
onParagraphClick: (annotationId: string) => void;

View File

@@ -0,0 +1,23 @@
import type { components } from '$lib/generated/api';
type Person = components['schemas']['Person'];
type RelationshipDTO = components['schemas']['RelationshipDTO'];
/**
* Data the PersonHoverCard needs to render its loaded state.
* Bundled here so the orchestrator (TranscriptionReadView) and the view
* (PersonHoverCard) share one canonical shape.
*/
export type HoverData = { person: Person; relationships: RelationshipDTO[] };
/**
* The hover card's three visible states.
*
* `loading` — initial fetch in flight; skeleton is shown
* `error` — fetch failed (non-404, non-OK); generic error message + footer link
* `loaded` — fetch succeeded; person + relationships available
*/
export type LoadState =
| { status: 'loading' }
| { status: 'error' }
| { status: 'loaded'; person: Person; relationships: RelationshipDTO[] };