feat(user): add certificate production tracking and update localization
All checks were successful
Deploy to production / deploy (push) Successful in 2m50s

- Introduced a new field `certificateProductionsCountSince` in the `FalukantUser` model to track the date from which production logs are counted for certificate requirements.
- Updated the `FalukantService` to utilize the new field for calculating completed productions since the specified date.
- Enhanced the UI to display the count of productions since the last promotion, with corresponding translations added for multiple languages including Cebuano, German, English, Spanish, and French.
- Implemented a method to delete old production logs, ensuring efficient data management while maintaining necessary historical records for certificate calculations.
This commit is contained in:
Torsten Schulz (local)
2026-04-09 08:19:19 +02:00
parent f7030bbabe
commit 360bb59a4e
18 changed files with 200 additions and 25 deletions

View File

@@ -194,8 +194,12 @@ void ProduceWorker::addProductionToLog(int regionId, int userId, int productId,
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
db.prepare("QUERY_INSERT_UPDATE_PRODUCTION_LOG", QUERY_INSERT_UPDATE_PRODUCTION_LOG);
db.execute("QUERY_INSERT_UPDATE_PRODUCTION_LOG", { std::to_string(regionId), std::to_string(productId),
std::to_string(productId), std::to_string(userId) });
db.execute("QUERY_INSERT_UPDATE_PRODUCTION_LOG", {
std::to_string(regionId),
std::to_string(productId),
std::to_string(quantity),
std::to_string(userId),
});
} catch (const std::exception &e) {
}

View File

@@ -30,6 +30,7 @@ void UserCharacterWorker::run() {
processCharacterEvents();
updateCharactersMood();
handleCredits();
deleteOldProductionLogs();
} catch (const std::exception &e) {
std::cerr << "[UserCharacterWorker] Fehler in processCharacterEvents: " << e.what() << std::endl;
}
@@ -233,6 +234,17 @@ void UserCharacterWorker::setNewMoney(int falukantUserId, double newAmount) {
});
}
void UserCharacterWorker::deleteOldProductionLogs() {
try {
ConnectionGuard connGuard(pool);
auto &db = connGuard.get();
db.prepare("QUERY_DELETE_OLD_PRODUCTIONS", QUERY_DELETE_OLD_PRODUCTIONS);
db.execute("QUERY_DELETE_OLD_PRODUCTIONS");
} catch (const std::exception &e) {
std::cerr << "[UserCharacterWorker] Fehler in deleteOldProductionLogs: " << e.what() << std::endl;
}
}
void UserCharacterWorker::recalculateKnowledge() {
setCurrentStep("Get character data");
ConnectionGuard connGuard(pool);

View File

@@ -25,6 +25,7 @@ private:
int calculateHealthChange(int age);
void handleCharacterDeath(int characterId);
void recalculateKnowledge();
void deleteOldProductionLogs();
void processPregnancies();
void handleCredits();
void setHeir(int characterId);
@@ -61,7 +62,13 @@ private:
static constexpr const char *QUERY_UPDATE_GET_ITEMS_TO_UPDATE = R"(
SELECT id, product_id, producer_id, quantity
FROM falukant_log.production p
WHERE p.production_timestamp::date < current_date
WHERE (COALESCE(p.production_timestamp, p.production_date::timestamp))::date < CURRENT_DATE
)";
/** Log-Retention: ältere Zeilen entfernen (Daemon/UI-Zertifikatszählung braucht Historie nur begrenzt). */
static constexpr const char *QUERY_DELETE_OLD_PRODUCTIONS = R"(
DELETE FROM falukant_log.production
WHERE COALESCE(production_timestamp, production_date::timestamp) < NOW() - INTERVAL '30 days'
)";
static constexpr const char *QUERY_UPDATE_GET_CHARACTER_IDS = R"(

View File

@@ -71,8 +71,10 @@ void ValueRecalculationWorker::calculateProductKnowledge() {
const auto userId = std::stoi(user.at("producer_id"));
sendMessageToFalukantUsers(userId, message);
}
db.prepare("QUERY_DELETE_OLD_PRODUCTIONS", QUERY_DELETE_OLD_PRODUCTIONS);
db.execute("QUERY_DELETE_OLD_PRODUCTIONS");
/* Kein DELETE mehr auf falukant_log.production um Mitternacht: Die Einträge werden für
* Zertifikatsfortschritt (Backend + Daemon) benötigt.
* UserCharacterWorker: nach Wissens-Update pro Zeile löschen; zusätzlich stündlich Retention
* QUERY_DELETE_OLD_PRODUCTIONS (30 Tage, COALESCE(timestamp, production_date)). */
}
void ValueRecalculationWorker::calculateRegionalSellPrice() {

View File

@@ -42,21 +42,16 @@ private:
SET knowledge = LEAST(100, k.knowledge + 1)
FROM falukant_data."character" c
JOIN falukant_log.production p
ON DATE(p.production_timestamp) = CURRENT_DATE - INTERVAL '1 day'
ON DATE(COALESCE(p.production_timestamp, p.production_date::timestamp)) = CURRENT_DATE - INTERVAL '1 day'
WHERE c.id = k.character_id
AND c.user_id = 18
AND k.product_id = 10
)";
static constexpr const char *QUERY_DELETE_OLD_PRODUCTIONS = R"(
delete from falukant_log.production flp
where date(flp.production_timestamp) < CURRENT_DATE
)";
static constexpr const char *QUERY_GET_PRODUCERS_LAST_DAY = R"(
select p."producer_id"
from falukant_log.production p
where date(p."production_timestamp") = CURRENT_DATE - interval '1 day'
where date(COALESCE(p.production_timestamp, p.production_date::timestamp)) = CURRENT_DATE - interval '1 day'
group by producer_id
)";