diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index 226128e..6ecdcef 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -2638,38 +2638,69 @@ class FalukantService extends BaseService { if (!user) throw new Error('User not found'); const character = await FalukantCharacter.findOne({ where: { userId: user.id } }); if (!character) throw new Error('Character not found for this user'); - let relationships = await Relationship.findAll({ + // Load relationships without includes to avoid EagerLoadingError + const relRows = await Relationship.findAll({ where: { character1Id: character.id }, - attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress'], - include: [ - { - model: FalukantCharacter, as: 'character2', + attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress', 'character2Id', 'relationshipTypeId'] + }); + let relationships; + if (relRows.length === 0) { + relationships = []; + } else { + const typeIds = [...new Set(relRows.map(r => r.relationshipTypeId))]; + const char2Ids = relRows.map(r => r.character2Id); + const [types, character2s] = await Promise.all([ + RelationshipType.findAll({ where: { id: typeIds }, attributes: ['id', 'tr'] }), + FalukantCharacter.findAll({ + where: { id: char2Ids }, attributes: ['id', 'birthdate', 'gender', 'moodId'], include: [ { model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }, { model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] }, - { model: CharacterTrait, as: 'traits' }, - { model: Mood, as: 'mood' }, + { model: Mood, as: 'mood' } ] - }, - { model: RelationshipType, as: 'relationshipType', attributes: ['tr'] } - ] - }); - relationships = relationships.map(r => ({ - createdAt: r.createdAt, - widowFirstName2: r.widowFirstName2, - progress: r.nextStepProgress, - character2: { - id: r.character2.id, - age: calcAge(r.character2.birthdate), - gender: r.character2.gender, - firstName: r.character2.definedFirstName?.name || 'Unknown', - nobleTitle: r.character2.nobleTitle?.labelTr || '', - mood: r.character2.mood, - traits: r.character2.traits - }, - relationshipType: r.relationshipType.tr - })); + }) + ]); + const typeMap = Object.fromEntries(types.map(t => [t.id, t])); + const char2Map = Object.fromEntries(character2s.map(c => [c.id, c])); + const ctRows = await FalukantCharacterTrait.findAll({ + where: { characterId: char2Ids }, + attributes: ['characterId', 'traitId'] + }); + const allTraitIds = [...new Set(ctRows.map(r => r.traitId))]; + const traitsList = allTraitIds.length + ? await CharacterTrait.findAll({ where: { id: allTraitIds }, attributes: ['id', 'tr'] }) + : []; + const traitMap = Object.fromEntries(traitsList.map(t => [t.id, t])); + const traitsByChar = {}; + for (const row of ctRows) { + if (!traitsByChar[row.characterId]) traitsByChar[row.characterId] = []; + const t = traitMap[row.traitId]; + if (t) traitsByChar[row.characterId].push(t); + } + for (const c of character2s) { + c.setDataValue('traits', traitsByChar[c.id] || []); + } + const relationships = relRows.map(r => { + const c2 = char2Map[r.character2Id]; + const type = typeMap[r.relationshipTypeId]; + return { + createdAt: r.createdAt, + widowFirstName2: r.widowFirstName2, + progress: r.nextStepProgress, + character2: c2 ? { + id: c2.id, + age: calcAge(c2.birthdate), + gender: c2.gender, + firstName: c2.definedFirstName?.name || 'Unknown', + nobleTitle: c2.nobleTitle?.labelTr || '', + mood: c2.mood, + traits: c2.traits || [] + } : null, + relationshipType: type ? type.tr : '' + }; + }); + } const charsWithChildren = await FalukantCharacter.findAll({ where: { userId: user.id }, include: [ @@ -2927,7 +2958,7 @@ class FalukantService extends BaseService { const myChar = user.character; if (!myChar) throw new Error('Character not found'); - // 2) Beziehung finden und „anderen“ Character bestimmen + // 2) Beziehung finden und „anderen“ Character bestimmen (ohne Include, um EagerLoadingError zu vermeiden) const rel = await Relationship.findOne({ where: { [Op.or]: [ @@ -2935,14 +2966,25 @@ class FalukantService extends BaseService { { character2Id: myChar.id } ] }, - include: [ - { model: FalukantCharacter, as: 'character1', include: [{ model: CharacterTrait, as: 'traits' }] }, - { model: FalukantCharacter, as: 'character2', include: [{ model: CharacterTrait, as: 'traits' }] } - ] + attributes: ['character1Id', 'character2Id'] }); if (!rel) throw new Error('Beziehung nicht gefunden'); - const relatedChar = rel.character1.id === myChar.id ? rel.character2 : rel.character1; + const relatedCharId = rel.character1Id === myChar.id ? rel.character2Id : rel.character1Id; + const relatedChar = await FalukantCharacter.findOne({ + where: { id: relatedCharId }, + attributes: ['id', 'moodId'] + }); + if (!relatedChar) throw new Error('Related character not found'); + const ctRows = await FalukantCharacterTrait.findAll({ + where: { characterId: relatedCharId }, + attributes: ['traitId'] + }); + const traitIds = ctRows.map(r => r.traitId); + const traits = traitIds.length + ? await CharacterTrait.findAll({ where: { id: traitIds }, attributes: ['id'] }) + : []; + relatedChar.setDataValue('traits', traits); // 3) Trait-IDs und Mood des relatedChar const relatedTraitIds = relatedChar.traits.map(t => t.id);