Update production certificate logic for more frequent recalculations: Changed the certificate recalculation interval to approximately once per minute, updated related documentation, and adjusted the FalukantFamilyWorker to reflect these changes. Enhanced the UI WebSocket documentation to clarify the conditions under which production certificates are refreshed.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 2m56s

This commit is contained in:
Torsten Schulz (local)
2026-04-10 08:43:19 +02:00
parent 1111377913
commit 7043e8d90c
4 changed files with 17 additions and 8 deletions

View File

@@ -1,5 +1,6 @@
//! Produktionszertifikat: tägliche Neuberechnung von `falukant_user.certificate` im **FalukantFamilyWorker**-24h-Tick
//! (`run_iteration`, unabhängig von der Familien-Schema-Migration; nicht in einem eigenen Worker-Thread). Spec: `docs/FALUKANT_PRODUCTION_CERTIFICATE.md` und
//! Produktionszertifikat: regelmäßige Neuberechnung von `falukant_user.certificate` im **FalukantFamilyWorker**
//! (Standard: **1× pro Minute**, `CERTIFICATE_RECALC_INTERVAL` in `falukant_family.rs`; unabhängig von der Familien-Schema-Migration).
//! Spec: `docs/FALUKANT_PRODUCTION_CERTIFICATE.md` und
//! „Falukant: Produktionszertifikate Fach- und Integrationsspezifikation“.
use crate::db::{DbError, Row};
@@ -14,7 +15,7 @@ use crate::worker::sql::{
/// Wenn `money` darunter liegt, gilt der Spieler als bankrott → Zertifikat auf Stufe 1 (Spec §4.7).
const BANKRUPTCY_MONEY_THRESHOLD: f64 = -5000.0;
/// Einmal pro Daily-Tick (`FalukantFamilyWorker::process_daily`).
/// Periodischer Tick (`FalukantFamilyWorker::run_iteration`, Standard: 1×/Minute).
pub fn run_daily(base: &BaseWorker, broker: &MessageBroker) -> Result<(), DbError> {
let pool = &base.pool;
let mut conn = pool

View File

@@ -36,6 +36,8 @@ use crate::message_broker::MessageBroker;
const DAILY_INTERVAL: Duration = Duration::from_secs(24 * 3600);
/// Wie `DAILY_INTERVAL`: 1 Spieljahr = 1 Kalendertag — Monats-Stempel/„monthly“-Batch pro Spieltag, nicht alle 30 echten Tage.
const MONTHLY_INTERVAL: Duration = DAILY_INTERVAL;
/// Produktionszertifikat: Aufstieg/Herabstufung gegen Mindestwerte (nicht nur 1×/Tag).
const CERTIFICATE_RECALC_INTERVAL: Duration = Duration::from_secs(60);
/// 12 Monatsticke pro Spieltag (24 h = 1 Spieljahr); 2 h = 1 Spielmonat (Liebschaft + Dienerschaft).
const GAME_MONTH_SLICE_INTERVAL: Duration = Duration::from_secs(2 * 3600);
@@ -47,6 +49,7 @@ pub struct FalukantFamilyWorker {
last_monthly: Option<Instant>,
/// Gemeinsamer Tick für Liebschafts-Raten + Dienerschaft (Monatstick ≈ 2 h).
last_game_month_slice: Option<Instant>,
last_certificate_recalc: Option<Instant>,
schema_ready: bool,
/// Migration `004_falukant_servants_daemon.sql` (Dienerschaft-Ticks).
servants_schema_ready: bool,
@@ -63,6 +66,7 @@ impl FalukantFamilyWorker {
last_daily: None,
last_monthly: None,
last_game_month_slice: None,
last_certificate_recalc: None,
schema_ready: false,
servants_schema_ready: false,
lover_installment_schema_ready: false,
@@ -79,13 +83,17 @@ impl FalukantFamilyWorker {
}
}
if Self::should_run(self.last_certificate_recalc, now, CERTIFICATE_RECALC_INTERVAL) {
if let Err(e) = super::falukant_certificate::run_daily(&self.base, &self.base.broker) {
eprintln!("[FalukantFamilyWorker] falukant_certificate::run_daily: {e}");
}
self.last_certificate_recalc = Some(now);
}
if Self::should_run(self.last_daily, now, DAILY_INTERVAL) {
if let Err(e) = super::falukant_debtors::run_daily(&self.base, &self.base.broker) {
eprintln!("[FalukantFamilyWorker] falukant_debtors::run_daily: {e}");
}
if let Err(e) = super::falukant_certificate::run_daily(&self.base, &self.base.broker) {
eprintln!("[FalukantFamilyWorker] falukant_certificate::run_daily: {e}");
}
if self.schema_ready {
if let Err(e) = self.process_daily() {
eprintln!("[FalukantFamilyWorker] process_daily: {e}");