fix(stammbaum): drop inferred relationships that are already direct

A spouse listed as a direct PersonRelationship was also being
emitted as an inferred SPOUSE chip below, so the same person
appeared twice in the Beziehungen card.

Filter the inferred list against the IDs already shown as direct
edges before slicing the top 5. Added a component test that
renders red without the filter and green with it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-27 19:47:49 +02:00
parent c103aafa6d
commit 6f867e5548
2 changed files with 60 additions and 1 deletions

View File

@@ -14,7 +14,10 @@ interface Props {
let { personId, relationships, inferredRelationships }: Props = $props();
const topDerived = $derived(inferredRelationships.slice(0, 5));
const directOtherIds = $derived(new Set(relationships.map((rel) => otherId(rel))));
const topDerived = $derived(
inferredRelationships.filter((d) => !directOtherIds.has(d.person.id)).slice(0, 5)
);
function chipLabel(rel: RelationshipDTO): string {
const viewpointIsSubject = rel.personId === personId;

View File

@@ -0,0 +1,56 @@
import { describe, it, expect } from 'vitest';
import { render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import PersonRelationshipsCard from './PersonRelationshipsCard.svelte';
const PERSON_ID = '00000000-0000-0000-0000-000000000001';
const SPOUSE_ID = '00000000-0000-0000-0000-000000000002';
describe('PersonRelationshipsCard', () => {
it('hides an inferred relationship that is already a direct one', async () => {
render(PersonRelationshipsCard, {
personId: PERSON_ID,
relationships: [
{
id: 'r1',
personId: PERSON_ID,
relatedPersonId: SPOUSE_ID,
personDisplayName: 'Anna Müller',
relatedPersonDisplayName: 'Bertha Müller',
relationType: 'SPOUSE_OF'
}
],
inferredRelationships: [
{
person: {
id: SPOUSE_ID,
displayName: 'Bertha Müller',
familyMember: true
},
label: 'SPOUSE',
hops: 1
}
]
});
const matches = await page.getByText('Bertha Müller').all();
expect(matches).toHaveLength(1);
});
it('still renders inferred relationships that are not direct', async () => {
const COUSIN_ID = '00000000-0000-0000-0000-000000000003';
render(PersonRelationshipsCard, {
personId: PERSON_ID,
relationships: [],
inferredRelationships: [
{
person: { id: COUSIN_ID, displayName: 'Carla Cousine', familyMember: true },
label: 'COUSIN',
hops: 4
}
]
});
await expect.element(page.getByText('Carla Cousine')).toBeInTheDocument();
});
});