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.
This commit is contained in:
Torsten Schulz (local)
2026-01-12 08:24:00 +01:00
parent 91f59062f5
commit 92d6b15c3f

View File

@@ -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);
}
}