- Implemented setHeir method in FalukantService to designate a child as heir, including validation checks for user and child relationships. - Updated FalukantController to expose the setHeir endpoint, allowing users to set heirs via the API. - Enhanced FalukantRouter with a new route for setting heirs. - Modified FamilyView component to include UI elements for setting heirs, with success and error feedback. - Updated localization files in both German and English to include new translations related to heir management, improving user experience.
285 lines
16 KiB
JavaScript
285 lines
16 KiB
JavaScript
import FalukantService from '../services/falukantService.js';
|
|
|
|
function extractHashedUserId(req) {
|
|
return req.headers?.userid;
|
|
}
|
|
|
|
class FalukantController {
|
|
constructor() {
|
|
this.service = FalukantService;
|
|
|
|
// No-user endpoints
|
|
this.randomFirstName = this._wrapNoUser(this.service.randomFirstName.bind(this.service), {
|
|
successStatus: 200,
|
|
transform: gender => ({ name: gender })
|
|
});
|
|
this.randomLastName = this._wrapNoUser(this.service.randomLastName.bind(this.service), {
|
|
successStatus: 200,
|
|
transform: name => ({ name })
|
|
});
|
|
|
|
// User-scoped endpoints
|
|
this.getUser = this._wrapWithUser((userId) => this.service.getUser(userId));
|
|
this.createUser = this._wrapWithUser((userId, req) => {
|
|
const { gender, firstname, lastname } = req.body;
|
|
return this.service.createUser(userId, gender, firstname, lastname);
|
|
}, { successStatus: 201 });
|
|
|
|
this.getInfo = this._wrapWithUser((userId) => this.service.getInfo(userId));
|
|
this.getBranches = this._wrapWithUser((userId) => this.service.getBranches(userId));
|
|
this.createBranch = this._wrapWithUser((userId, req) => this.service.createBranch(userId, req.body.cityId, req.body.branchTypeId));
|
|
this.getBranchTypes = this._wrapWithUser((userId) => this.service.getBranchTypes(userId));
|
|
this.getBranch = this._wrapWithUser((userId, req) => this.service.getBranch(userId, req.params.branch));
|
|
this.upgradeBranch = this._wrapWithUser((userId, req) => this.service.upgradeBranch(userId, req.body.branchId));
|
|
this.createProduction = this._wrapWithUser((userId, req) => {
|
|
const { branchId, productId, quantity } = req.body;
|
|
return this.service.createProduction(userId, branchId, productId, quantity);
|
|
}, { successStatus: 201 });
|
|
this.getProduction = this._wrapWithUser((userId, req) => this.service.getProduction(userId, req.params.branchId));
|
|
this.getStock = this._wrapWithUser((userId, req) => this.service.getStock(userId, req.params.branchId || null));
|
|
this.createStock = this._wrapWithUser((userId, req) => {
|
|
const { branchId, stockTypeId, stockSize } = req.body;
|
|
return this.service.createStock(userId, branchId, stockTypeId, stockSize);
|
|
}, { successStatus: 201 });
|
|
this.getProducts = this._wrapWithUser((userId) => this.service.getProducts(userId));
|
|
this.getInventory = this._wrapWithUser((userId, req) => this.service.getInventory(userId, req.params.branchId));
|
|
this.sellProduct = this._wrapWithUser((userId, req) => {
|
|
const { branchId, productId, quality, quantity } = req.body;
|
|
return this.service.sellProduct(userId, branchId, productId, quality, quantity);
|
|
}, { successStatus: 201 });
|
|
this.sellAllProducts = this._wrapWithUser((userId, req) => {
|
|
const { branchId } = req.body;
|
|
return this.service.sellAllProducts(userId, branchId);
|
|
}, { successStatus: 201 });
|
|
this.moneyHistory = this._wrapWithUser((userId, req) => {
|
|
let { page, filter } = req.body;
|
|
if (!page) page = 1;
|
|
return this.service.moneyHistory(userId, page, filter);
|
|
});
|
|
this.getStorage = this._wrapWithUser((userId, req) => this.service.getStorage(userId, req.params.branchId));
|
|
this.buyStorage = this._wrapWithUser((userId, req) => {
|
|
const { branchId, amount, stockTypeId } = req.body;
|
|
return this.service.buyStorage(userId, branchId, amount, stockTypeId);
|
|
}, { successStatus: 201 });
|
|
this.sellStorage = this._wrapWithUser((userId, req) => {
|
|
const { branchId, amount, stockTypeId } = req.body;
|
|
return this.service.sellStorage(userId, branchId, amount, stockTypeId);
|
|
}, { successStatus: 202 });
|
|
|
|
this.getStockTypes = this._wrapSimple(() => this.service.getStockTypes());
|
|
this.getStockOverview = this._wrapSimple(() => this.service.getStockOverview());
|
|
this.getAllProductions = this._wrapWithUser((userId) => this.service.getAllProductions(userId));
|
|
|
|
this.getDirectorProposals = this._wrapWithUser((userId, req) => {
|
|
console.log('🔍 getDirectorProposals called with userId:', userId, 'branchId:', req.body.branchId);
|
|
return this.service.getDirectorProposals(userId, req.body.branchId);
|
|
});
|
|
this.convertProposalToDirector = this._wrapWithUser((userId, req) => this.service.convertProposalToDirector(userId, req.body.proposalId));
|
|
this.getDirectorForBranch = this._wrapWithUser((userId, req) => this.service.getDirectorForBranch(userId, req.params.branchId));
|
|
this.getAllDirectors = this._wrapWithUser((userId) => this.service.getAllDirectors(userId));
|
|
this.updateDirector = this._wrapWithUser((userId, req) => {
|
|
const { directorId, income } = req.body;
|
|
return this.service.updateDirector(userId, directorId, income);
|
|
});
|
|
|
|
this.setSetting = this._wrapWithUser((userId, req) => {
|
|
const { branchId, directorId, settingKey, value } = req.body;
|
|
return this.service.setSetting(userId, branchId, directorId, settingKey, value);
|
|
});
|
|
|
|
this.getFamily = this._wrapWithUser(async (userId) => {
|
|
const result = await this.service.getFamily(userId);
|
|
if (!result) throw { status: 404, message: 'No family data found' };
|
|
return result;
|
|
});
|
|
this.setHeir = this._wrapWithUser((userId, req) => this.service.setHeir(userId, req.body.childCharacterId));
|
|
this.acceptMarriageProposal = this._wrapWithUser((userId, req) => this.service.acceptMarriageProposal(userId, req.body.proposalId));
|
|
this.getGifts = this._wrapWithUser((userId) => {
|
|
console.log('🔍 getGifts called with userId:', userId);
|
|
return this.service.getGifts(userId);
|
|
});
|
|
this.getChildren = this._wrapWithUser((userId) => this.service.getChildren(userId));
|
|
this.sendGift = this._wrapWithUser((userId, req) => this.service.sendGift(userId, req.body.giftId));
|
|
|
|
this.getTitlesOfNobility = this._wrapWithUser((userId) => this.service.getTitlesOfNobility(userId));
|
|
this.getHouseTypes = this._wrapWithUser((userId) => this.service.getHouseTypes(userId));
|
|
this.getMoodAffect = this._wrapWithUser((userId) => this.service.getMoodAffect(userId));
|
|
this.getCharacterAffect = this._wrapWithUser((userId) => this.service.getCharacterAffect(userId));
|
|
this.getUserHouse = this._wrapWithUser((userId) => this.service.getUserHouse(userId));
|
|
this.getBuyableHouses = this._wrapWithUser((userId) => this.service.getBuyableHouses(userId));
|
|
this.buyUserHouse = this._wrapWithUser((userId, req) => this.service.buyUserHouse(userId, req.body.houseId), { successStatus: 201 });
|
|
|
|
this.getPartyTypes = this._wrapWithUser((userId) => this.service.getPartyTypes(userId));
|
|
this.createParty = this._wrapWithUser((userId, req) => {
|
|
const { partyTypeId, musicId, banquetteId, nobilityIds, servantRatio } = req.body;
|
|
return this.service.createParty(userId, partyTypeId, musicId, banquetteId, nobilityIds, servantRatio);
|
|
}, { successStatus: 201 });
|
|
this.getParties = this._wrapWithUser((userId) => this.service.getParties(userId));
|
|
|
|
this.getNotBaptisedChildren = this._wrapWithUser((userId) => this.service.getNotBaptisedChildren(userId));
|
|
this.baptise = this._wrapWithUser((userId, req) => {
|
|
const { characterId: childId, firstName } = req.body;
|
|
return this.service.baptise(userId, childId, firstName);
|
|
});
|
|
|
|
this.getEducation = this._wrapWithUser((userId) => this.service.getEducation(userId));
|
|
this.sendToSchool = this._wrapWithUser((userId, req) => {
|
|
const { item, student, studentId } = req.body;
|
|
return this.service.sendToSchool(userId, item, student, studentId);
|
|
});
|
|
|
|
this.getBankOverview = this._wrapWithUser((userId) => this.service.getBankOverview(userId));
|
|
this.getBankCredits = this._wrapWithUser((userId) => this.service.getBankCredits(userId));
|
|
this.takeBankCredits = this._wrapWithUser((userId, req) => this.service.takeBankCredits(userId, req.body.height));
|
|
|
|
this.getNobility = this._wrapWithUser((userId) => this.service.getNobility(userId));
|
|
this.advanceNobility = this._wrapWithUser((userId) => this.service.advanceNobility(userId));
|
|
|
|
this.getHealth = this._wrapWithUser((userId) => this.service.getHealth(userId));
|
|
this.healthActivity = this._wrapWithUser((userId, req) => this.service.healthActivity(userId, req.body.measureTr));
|
|
|
|
this.getPoliticsOverview = this._wrapWithUser((userId) => this.service.getPoliticsOverview(userId));
|
|
this.getOpenPolitics = this._wrapWithUser((userId) => this.service.getOpenPolitics(userId));
|
|
this.getElections = this._wrapWithUser((userId) => this.service.getElections(userId));
|
|
this.vote = this._wrapWithUser((userId, req) => this.service.vote(userId, req.body.votes));
|
|
this.applyForElections = this._wrapWithUser((userId, req) => this.service.applyForElections(userId, req.body.electionIds));
|
|
|
|
this.getRegions = this._wrapWithUser((userId) => this.service.getRegions(userId));
|
|
this.getProductPriceInRegion = this._wrapWithUser((userId, req) => {
|
|
const productId = parseInt(req.query.productId, 10);
|
|
const regionId = parseInt(req.query.regionId, 10);
|
|
if (Number.isNaN(productId) || Number.isNaN(regionId)) {
|
|
throw new Error('productId and regionId are required');
|
|
}
|
|
return this.service.getProductPriceInRegion(userId, productId, regionId);
|
|
});
|
|
this.getProductPricesInCities = this._wrapWithUser((userId, req) => {
|
|
const productId = parseInt(req.query.productId, 10);
|
|
const currentPrice = parseFloat(req.query.currentPrice);
|
|
const currentRegionId = req.query.currentRegionId ? parseInt(req.query.currentRegionId, 10) : null;
|
|
if (Number.isNaN(productId) || Number.isNaN(currentPrice)) {
|
|
throw new Error('productId and currentPrice are required');
|
|
}
|
|
return this.service.getProductPricesInCities(userId, productId, currentPrice, currentRegionId);
|
|
});
|
|
this.renovate = this._wrapWithUser((userId, req) => this.service.renovate(userId, req.body.element));
|
|
this.renovateAll = this._wrapWithUser((userId) => this.service.renovateAll(userId));
|
|
|
|
this.getUndergroundTypes = this._wrapWithUser((userId) => this.service.getUndergroundTypes(userId));
|
|
this.getNotifications = this._wrapWithUser((userId) => this.service.getNotifications(userId));
|
|
this.getAllNotifications = this._wrapWithUser((userId, req) => this.service.getAllNotifications(userId, req.query.page, req.query.size));
|
|
this.markNotificationsShown = this._wrapWithUser((userId) => this.service.markNotificationsShown(userId), { successStatus: 202 });
|
|
this.getUndergroundTargets = this._wrapWithUser((userId) => this.service.getPoliticalOfficeHolders(userId));
|
|
|
|
this.searchUsers = this._wrapWithUser((userId, req) => {
|
|
const q = req.query.q?.trim() || '';
|
|
if (q.length < 1) return [];
|
|
return this.service.searchUsers(userId, q);
|
|
});
|
|
|
|
this.createUndergroundActivity = this._wrapWithUser((userId, req) => {
|
|
const payload = req.body;
|
|
if (!payload.typeId) {
|
|
throw { status: 400, message: 'typeId is required' };
|
|
}
|
|
if (payload.typeId === 'sabotage' && !payload.target) {
|
|
throw { status: 400, message: 'target is required for sabotage' };
|
|
}
|
|
if (payload.typeId === 'corrupt_politician' && !payload.goal) {
|
|
throw { status: 400, message: 'goal is required for corrupt_politician' };
|
|
}
|
|
return this.service.createUndergroundActivity(userId, payload);
|
|
}, { successStatus: 201 });
|
|
|
|
this.getUndergroundAttacks = this._wrapWithUser((userId, req) => {
|
|
const direction = (req.query.direction || '').toLowerCase();
|
|
return this.service.getUndergroundAttacks(userId).then(result => {
|
|
if (direction === 'sent') return result.sent;
|
|
if (direction === 'received') return result.received;
|
|
return result; // both
|
|
});
|
|
});
|
|
|
|
this.getVehicleTypes = this._wrapWithUser((userId) => this.service.getVehicleTypes(userId));
|
|
this.buyVehicles = this._wrapWithUser(
|
|
(userId, req) => this.service.buyVehicles(userId, req.body),
|
|
{ successStatus: 201 }
|
|
);
|
|
this.getVehicles = this._wrapWithUser(
|
|
(userId, req) => this.service.getVehicles(userId, req.query.regionId)
|
|
);
|
|
this.createTransport = this._wrapWithUser(
|
|
(userId, req) => this.service.createTransport(userId, req.body),
|
|
{ successStatus: 201 }
|
|
);
|
|
this.getTransportRoute = this._wrapWithUser(
|
|
(userId, req) => this.service.getTransportRoute(userId, req.query)
|
|
);
|
|
this.getBranchTransports = this._wrapWithUser(
|
|
(userId, req) => this.service.getBranchTransports(userId, req.params.branchId)
|
|
);
|
|
this.repairVehicle = this._wrapWithUser(
|
|
(userId, req) => this.service.repairVehicle(userId, req.params.vehicleId),
|
|
{ successStatus: 200 }
|
|
);
|
|
this.repairAllVehicles = this._wrapWithUser(
|
|
(userId, req) => this.service.repairAllVehicles(userId, req.body.vehicleIds),
|
|
{ successStatus: 200 }
|
|
);
|
|
|
|
}
|
|
|
|
|
|
_wrapWithUser(fn, { successStatus = 200, postProcess } = {}) {
|
|
return async (req, res) => {
|
|
try {
|
|
const hashedUserId = extractHashedUserId(req);
|
|
if (!hashedUserId) {
|
|
return res.status(400).json({ error: 'Missing user identifier' });
|
|
}
|
|
const result = await fn(hashedUserId, req, res);
|
|
const toSend = postProcess ? postProcess(result) : result;
|
|
res.status(successStatus).json(toSend);
|
|
} catch (error) {
|
|
console.error('Controller error:', error);
|
|
const status = error.status && typeof error.status === 'number' ? error.status : 500;
|
|
res.status(status).json({ error: error.message || 'Internal error' });
|
|
}
|
|
};
|
|
}
|
|
|
|
_wrapSimple(fn, { successStatus = 200, postProcess } = {}) {
|
|
return async (req, res) => {
|
|
try {
|
|
const result = await fn(req, res);
|
|
const toSend = postProcess ? postProcess(result) : result;
|
|
res.status(successStatus).json(toSend);
|
|
} catch (error) {
|
|
console.error('Controller error:', error);
|
|
const status = error.status && typeof error.status === 'number' ? error.status : 500;
|
|
res.status(status).json({ error: error.message || 'Internal error' });
|
|
}
|
|
};
|
|
}
|
|
|
|
_wrapNoUser(fn, { successStatus = 200, transform } = {}) {
|
|
return async (req, res) => {
|
|
try {
|
|
let result;
|
|
if (req.params && Object.keys(req.params).length) {
|
|
result = await fn(req.params.gender);
|
|
} else {
|
|
result = await fn();
|
|
}
|
|
if (transform) result = transform(result);
|
|
res.status(successStatus).json(result);
|
|
} catch (error) {
|
|
console.error('Controller error:', error);
|
|
res.status(500).json({ error: error.message || 'Internal error' });
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
export default FalukantController;
|