Füge neue Funktionen zur Verwaltung von Erben hinzu: Implementiere die API-Endpunkte zum Abrufen potenzieller Erben und zum Auswählen eines Erben. Ergänze die Logik in FalukantService zur Verarbeitung dieser Funktionen.

This commit is contained in:
Torsten Schulz (local)
2026-03-02 00:36:43 +01:00
parent 42fe568e2b
commit a2652c983f
4 changed files with 96 additions and 8 deletions

View File

@@ -2910,6 +2910,97 @@ class FalukantService extends BaseService {
return { success: true, childCharacterId };
}
async getPotentialHeirs(hashedUserId) {
const user = await this.getFalukantUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found');
if (user.character?.id) return [];
const noncivilTitle = await TitleOfNobility.findOne({
where: { labelTr: 'noncivil' },
attributes: ['id']
});
if (!noncivilTitle?.id) return [];
const tenDaysAgo = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000);
const mainRegionId = user.mainBranchRegionId || null;
const includes = [
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
{ model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] }
];
const buildWhere = ({ withRegion = true, withYoungAge = true } = {}) => {
const where = {
userId: null,
titleOfNobility: noncivilTitle.id,
health: { [Op.gt]: 0 }
};
if (withRegion && mainRegionId) where.regionId = mainRegionId;
if (withYoungAge) where.birthdate = { [Op.gte]: tenDaysAgo };
return where;
};
const loadCandidates = async (where) => FalukantCharacter.findAll({
where,
include: includes,
attributes: ['id', 'birthdate', 'gender'],
order: sequelize.random(),
limit: 10
});
let candidates = await loadCandidates(buildWhere({ withRegion: true, withYoungAge: true }));
if (candidates.length === 0) {
candidates = await loadCandidates(buildWhere({ withRegion: true, withYoungAge: false }));
}
if (candidates.length === 0) {
candidates = await loadCandidates(buildWhere({ withRegion: false, withYoungAge: false }));
}
return candidates.map(candidate => {
const plain = candidate.get({ plain: true });
return {
...plain,
age: plain.birthdate ? calcAge(plain.birthdate) : null
};
});
}
async selectHeir(hashedUserId, heirId) {
const parsedHeirId = Number(heirId);
if (!Number.isInteger(parsedHeirId) || parsedHeirId < 1) {
throw { status: 400, message: 'Invalid heirId' };
}
const user = await this.getFalukantUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found');
if (user.character?.id) {
throw { status: 409, message: 'User already has an active character' };
}
const noncivilTitle = await TitleOfNobility.findOne({
where: { labelTr: 'noncivil' },
attributes: ['id']
});
if (!noncivilTitle?.id) throw new Error('Title "noncivil" not found');
const mainRegionId = user.mainBranchRegionId || null;
const where = {
id: parsedHeirId,
userId: null,
titleOfNobility: noncivilTitle.id,
health: { [Op.gt]: 0 }
};
if (mainRegionId) where.regionId = mainRegionId;
const candidate = await FalukantCharacter.findOne({ where, attributes: ['id'] });
if (!candidate) {
throw { status: 404, message: 'Selected heir is not available' };
}
await candidate.update({ userId: user.id });
return { success: true, heirId: candidate.id };
}
async getPossiblePartners(requestingCharacterId) {
const proposals = await MarriageProposal.findAll({
where: {