chore(stammbaum): regenerate TS API types for relationship endpoints
Some checks failed
CI / Unit & Component Tests (push) Failing after 3m8s
CI / OCR Service Tests (push) Successful in 32s
CI / Backend Unit Tests (push) Has been cancelled

openapi-typescript pulled the Stammbaum schemas: Person now has
familyMember (required), plus PersonNodeDTO, NetworkDTO, RelationshipDTO,
InferredRelationshipDTO, InferredRelationshipWithPersonDTO,
CreateRelationshipRequest, FamilyMemberPatchDTO. Routes:
/api/network, /api/persons/{id}/relationships,
/api/persons/{id}/inferred-relationships,
/api/persons/{aId}/relationship-to/{bId}, and the family-member PATCH.

Test fixtures in PersonMultiSelect, briefwechsel page, and DocumentList
specs gained familyMember: false where they otherwise typed Person
end-to-end. Pre-existing "missing lastName/personType" fixture errors
in DocumentRow.spec are out of scope.

Refs #358.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-27 14:36:11 +02:00
parent c4a050da86
commit 0e23b49b7a
4 changed files with 394 additions and 26 deletions

View File

@@ -12,16 +12,25 @@ const PERSONS = [
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
},
{
id: '2',
firstName: 'Anna',
lastName: 'Musterfrau',
displayName: 'Anna Musterfrau',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
},
{ id: '3', firstName: 'Karl', lastName: 'König', displayName: 'Karl König', personType: 'PERSON' }
{
id: '3',
firstName: 'Karl',
lastName: 'König',
displayName: 'Karl König',
personType: 'PERSON',
familyMember: false
}
];
function mockFetch(persons = PERSONS) {
@@ -62,14 +71,16 @@ describe('PersonMultiSelect rendering', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
},
{
id: '2',
firstName: 'Anna',
lastName: 'Musterfrau',
displayName: 'Anna Musterfrau',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]
});
@@ -86,14 +97,16 @@ describe('PersonMultiSelect rendering', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
},
{
id: '2',
firstName: 'Anna',
lastName: 'Musterfrau',
displayName: 'Anna Musterfrau',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]
});
@@ -112,7 +125,8 @@ describe('PersonMultiSelect rendering', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]
});
@@ -166,7 +180,8 @@ describe('PersonMultiSelect selecting persons', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]
});
@@ -187,7 +202,8 @@ describe('PersonMultiSelect selecting persons', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]);
render(PersonMultiSelect, { selectedPersons: [] });
@@ -210,14 +226,16 @@ describe('PersonMultiSelect removing persons', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
},
{
id: '2',
firstName: 'Anna',
lastName: 'Musterfrau',
displayName: 'Anna Musterfrau',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]
});
@@ -236,14 +254,16 @@ describe('PersonMultiSelect removing persons', () => {
firstName: 'Max',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
},
{
id: '2',
firstName: 'Anna',
lastName: 'Musterfrau',
displayName: 'Anna Musterfrau',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
]
});

View File

@@ -212,6 +212,22 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/persons/{id}/relationships": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: operations["getRelationships"];
put?: never;
post: operations["addRelationship"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/persons/{id}/merge": {
parameters: {
query?: never;
@@ -612,6 +628,22 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/persons/{id}/family-member": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch: operations["patchFamilyMember"];
trace?: never;
};
"/api/notifications/{id}/read": {
parameters: {
query?: never;
@@ -852,6 +884,22 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/persons/{id}/inferred-relationships": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: operations["getInferredRelationships"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/persons/{id}/documents": {
parameters: {
query?: never;
@@ -884,6 +932,22 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/persons/{aId}/relationship-to/{bId}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: operations["getRelationshipBetween"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/ocr/training-info": {
parameters: {
query?: never;
@@ -1044,6 +1108,22 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/network": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: operations["getNetwork"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/documents/{id}/versions": {
parameters: {
query?: never;
@@ -1332,6 +1412,22 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/persons/{id}/relationships/{relId}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
delete: operations["deleteRelationship"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/persons/{id}/aliases/{aliasId}": {
parameters: {
query?: never;
@@ -1430,6 +1526,8 @@ export interface components {
color?: string;
};
PersonUpdateDTO: {
/** @enum {string} */
personType: "PERSON" | "INSTITUTION" | "GROUP" | "UNKNOWN" | "SKIP";
title?: string;
firstName?: string;
lastName?: string;
@@ -1454,6 +1552,7 @@ export interface components {
birthYear?: number;
/** Format: int32 */
deathYear?: number;
familyMember: boolean;
readonly displayName: string;
};
DocumentUpdateDTO: {
@@ -1462,6 +1561,8 @@ export interface components {
documentDate?: string;
location?: string;
documentLocation?: string;
archiveBox?: string;
archiveFolder?: string;
transcription?: string;
summary?: string;
/** Format: uuid */
@@ -1561,6 +1662,41 @@ export interface components {
/** Format: uuid */
targetId: string;
};
CreateRelationshipRequest: {
/** Format: uuid */
relatedPersonId: string;
relationType: string;
/** Format: int32 */
fromYear?: number;
/** Format: int32 */
toYear?: number;
notes?: string;
};
RelationshipDTO: {
/** Format: uuid */
id: string;
/** Format: uuid */
personId: string;
/** Format: uuid */
relatedPersonId: string;
personDisplayName: string;
/** Format: int32 */
personBirthYear?: number;
/** Format: int32 */
personDeathYear?: number;
relatedPersonDisplayName: string;
/** Format: int32 */
relatedPersonBirthYear?: number;
/** Format: int32 */
relatedPersonDeathYear?: number;
/** @enum {string} */
relationType: "PARENT_OF" | "SPOUSE_OF" | "SIBLING_OF" | "FRIEND" | "COLLEAGUE" | "EMPLOYER" | "DOCTOR" | "NEIGHBOR" | "OTHER";
/** Format: int32 */
fromYear?: number;
/** Format: int32 */
toYear?: number;
notes?: string;
};
PersonNameAliasDTO: {
lastName: string;
firstName?: string;
@@ -1808,6 +1944,9 @@ export interface components {
/** Format: int32 */
count: number;
};
FamilyMemberPatchDTO: {
familyMember?: boolean;
};
NotificationDTO: {
/** Format: uuid */
id: string;
@@ -1912,15 +2051,38 @@ export interface components {
displayName?: string;
firstName?: string;
lastName?: string;
/** Format: int64 */
documentCount?: number;
personType?: string;
/** Format: int32 */
birthYear?: number;
/** Format: int32 */
deathYear?: number;
alias?: string;
familyMember?: boolean;
notes?: string;
personType?: string;
/** Format: int64 */
documentCount?: number;
alias?: string;
};
InferredRelationshipWithPersonDTO: {
person: components["schemas"]["PersonNodeDTO"];
label: string;
/** Format: int32 */
hops: number;
};
PersonNodeDTO: {
/** Format: uuid */
id: string;
displayName: string;
/** Format: int32 */
birthYear?: number;
/** Format: int32 */
deathYear?: number;
familyMember: boolean;
};
InferredRelationshipDTO: {
labelFromA: string;
labelFromB: string;
/** Format: int32 */
hops: number;
};
SenderModel: {
/** Format: uuid */
@@ -2021,6 +2183,10 @@ export interface components {
empty?: boolean;
unsorted?: boolean;
};
NetworkDTO: {
nodes: components["schemas"]["PersonNodeDTO"][];
edges: components["schemas"]["RelationshipDTO"][];
};
DocumentVersionSummary: {
/** Format: uuid */
id: string;
@@ -2131,7 +2297,7 @@ export interface components {
};
ActivityFeedItemDTO: {
/** @enum {string} */
kind: "FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED";
kind: "FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED" | "USER_CREATED" | "USER_DELETED" | "GROUP_MEMBERSHIP_CHANGED";
actor?: components["schemas"]["ActivityActorDTO"];
/** Format: uuid */
documentId: string;
@@ -2745,6 +2911,54 @@ export interface operations {
};
};
};
getRelationships: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"*/*": components["schemas"]["RelationshipDTO"][];
};
};
};
};
addRelationship: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["CreateRelationshipRequest"];
};
};
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"*/*": components["schemas"]["RelationshipDTO"];
};
};
};
};
mergePerson: {
parameters: {
query?: never;
@@ -3491,6 +3705,32 @@ export interface operations {
};
};
};
patchFamilyMember: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["FamilyMemberPatchDTO"];
};
};
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"*/*": components["schemas"]["Person"];
};
};
};
};
markOneRead: {
parameters: {
query?: never;
@@ -3889,6 +4129,28 @@ export interface operations {
};
};
};
getInferredRelationships: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"*/*": components["schemas"]["InferredRelationshipWithPersonDTO"][];
};
};
};
};
getPersonDocuments: {
parameters: {
query?: never;
@@ -3935,6 +4197,29 @@ export interface operations {
};
};
};
getRelationshipBetween: {
parameters: {
query?: never;
header?: never;
path: {
aId: string;
bId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"*/*": components["schemas"]["InferredRelationshipDTO"];
};
};
};
};
getTrainingInfo: {
parameters: {
query?: never;
@@ -4150,6 +4435,26 @@ export interface operations {
};
};
};
getNetwork: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description OK */
200: {
headers: {
[name: string]: unknown;
};
content: {
"*/*": components["schemas"]["NetworkDTO"];
};
};
};
};
getVersions: {
parameters: {
query?: never;
@@ -4470,7 +4775,7 @@ export interface operations {
query?: {
limit?: number;
/** @description Filter by audit kinds; omit for all rollup-eligible kinds */
kinds?: ("FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED")[];
kinds?: ("FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED" | "USER_CREATED" | "USER_DELETED" | "GROUP_MEMBERSHIP_CHANGED")[];
};
header?: never;
path?: never;
@@ -4571,6 +4876,27 @@ export interface operations {
};
};
};
deleteRelationship: {
parameters: {
query?: never;
header?: never;
path: {
id: string;
relId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description No Content */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
removeAlias: {
parameters: {
query?: never;

View File

@@ -131,7 +131,8 @@ describe('DocumentList sender grouping', () => {
id: 's1',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
}
}),
@@ -143,7 +144,8 @@ describe('DocumentList sender grouping', () => {
id: 's2',
lastName: 'Musterfrau',
displayName: 'Anna Musterfrau',
personType: 'PERSON'
personType: 'PERSON',
familyMember: false
}
}
})
@@ -162,7 +164,8 @@ describe('DocumentList sender grouping', () => {
id: 's1',
lastName: 'Mustermann',
displayName: 'Max Mustermann',
personType: 'PERSON' as const
personType: 'PERSON' as const,
familyMember: false
};
const items = [
makeItem({ document: { ...makeItem().document, id: '1', sender } }),
@@ -191,7 +194,13 @@ describe('DocumentList receiver grouping', () => {
...makeItem().document,
id: '1',
receivers: [
{ id: 'r1', lastName: 'Brandt', displayName: 'Felix Brandt', personType: 'PERSON' }
{
id: 'r1',
lastName: 'Brandt',
displayName: 'Felix Brandt',
personType: 'PERSON',
familyMember: false
}
]
}
})
@@ -210,8 +219,20 @@ describe('DocumentList receiver grouping', () => {
id: '1',
title: 'Rundbriefchen',
receivers: [
{ id: 'r1', lastName: 'Brandt', displayName: 'Felix Brandt', personType: 'PERSON' },
{ id: 'r2', lastName: 'Meier', displayName: 'Hans Meier', personType: 'PERSON' }
{
id: 'r1',
lastName: 'Brandt',
displayName: 'Felix Brandt',
personType: 'PERSON',
familyMember: false
},
{
id: 'r2',
lastName: 'Meier',
displayName: 'Hans Meier',
personType: 'PERSON',
familyMember: false
}
]
}
})

View File

@@ -35,6 +35,7 @@ const makePerson = (overrides: Record<string, unknown> = {}) => ({
firstName: 'Hans',
lastName: 'Müller',
personType: 'PERSON' as const,
familyMember: false,
displayName: 'Hans Müller',
...overrides
});