From 92d6b15c3fde9facf9db18c50ae3e3e2a5f88f95 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 12 Jan 2026 08:24:00 +0100 Subject: [PATCH] Enhance proposal generation logic in FalukantService to prevent duplicate character usage - Introduced a mechanism to track used character IDs, ensuring that previously proposed characters are excluded from future proposals. - Added error handling and logging for scenarios where no eligible characters are found, improving traceability and user feedback. - Implemented a fallback to include newer characters if older ones are unavailable, enhancing the robustness of the proposal generation process. --- backend/services/falukantService.js | 65 +++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index ab122ad..73d0396 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -2462,12 +2462,28 @@ class FalukantService extends BaseService { try { const threeWeeksAgo = new Date(Date.now() - 21 * 24 * 60 * 60 * 1000); const proposalCount = Math.floor(Math.random() * 3) + 3; + let createdProposals = 0; + const usedCharacterIds = new Set(); // Verhindere doppelte Proposals + + // Hole bereits existierende Proposals, um diese Charaktere auszuschließen + const existingProposals = await DirectorProposal.findAll({ + where: { employerUserId: falukantUserId }, + attributes: ['directorCharacterId'], + raw: true + }); + existingProposals.forEach(p => usedCharacterIds.add(p.directorCharacterId)); + for (let i = 0; i < proposalCount; i++) { - const directorCharacter = await FalukantCharacter.findOne({ - where: { - regionId, - createdAt: { [Op.lt]: threeWeeksAgo }, - }, + // Versuche zuerst Charaktere, die mindestens 3 Wochen alt sind + let whereClause = { + regionId, + userId: null, // Nur NPCs + id: { [Op.notIn]: Array.from(usedCharacterIds) }, // Keine bereits verwendeten + createdAt: { [Op.lt]: threeWeeksAgo }, + }; + + let directorCharacter = await FalukantCharacter.findOne({ + where: whereClause, include: [ { model: TitleOfNobility, @@ -2477,9 +2493,41 @@ class FalukantService extends BaseService { ], order: sequelize.literal('RANDOM()'), }); + + // Fallback: Wenn keine älteren Charaktere gefunden werden, verwende auch neuere if (!directorCharacter) { - throw new Error('No directors available for the region'); + console.log(`[generateProposals] No characters older than 3 weeks found in region ${regionId}, trying all NPCs...`); + whereClause = { + regionId, + userId: null, // Nur NPCs + id: { [Op.notIn]: Array.from(usedCharacterIds) }, + }; + directorCharacter = await FalukantCharacter.findOne({ + where: whereClause, + include: [ + { + model: TitleOfNobility, + as: 'nobleTitle', + attributes: ['level'], + }, + ], + order: sequelize.literal('RANDOM()'), + }); } + + if (!directorCharacter) { + console.warn(`[generateProposals] No more available NPCs in region ${regionId} (${usedCharacterIds.size} already used)`); + // Wenn keine Charaktere gefunden werden, breche die Schleife ab + // aber wirf keinen Fehler, wenn bereits einige Proposals erstellt wurden + if (createdProposals === 0) { + throw new Error('No directors available for the region'); + } + break; // Stoppe die Schleife, aber wirf keinen Fehler + } + + // Füge diesen Charakter zu den verwendeten hinzu + usedCharacterIds.add(directorCharacter.id); + const avgKnowledge = await this.calculateAverageKnowledge(directorCharacter.id); const proposedIncome = Math.round( directorCharacter.nobleTitle.level * Math.pow(1.231, avgKnowledge / 1.5) @@ -2489,9 +2537,12 @@ class FalukantService extends BaseService { employerUserId: falukantUserId, proposedIncome, }); + createdProposals++; } + + console.log(`[generateProposals] Created ${createdProposals} director proposals for region ${regionId}`); } catch (error) { - console.log(error.message, error.stack); + console.error('[generateProposals] Error:', error.message, error.stack); throw new Error(error.message); } }