From 1e4689212b81fa4f935aed9d21bb5d6793f58294 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Tue, 23 Dec 2025 14:35:51 +0100 Subject: [PATCH] Add cleanup functionality for collapsed houses in HouseWorker: Implement methods to delete collapsed buyable houses and user houses, including notifications for affected users. Update SQL queries to support this new feature, enhancing house management and user experience. --- src/worker/house.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++- src/worker/sql.rs | 30 +++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/worker/house.rs b/src/worker/house.rs index 28ec5ab..988646f 100644 --- a/src/worker/house.rs +++ b/src/worker/house.rs @@ -10,7 +10,10 @@ use crate::worker::sql::{ QUERY_ADD_NEW_BUYABLE_HOUSE, QUERY_UPDATE_BUYABLE_HOUSE_STATE, QUERY_UPDATE_USER_HOUSE_STATE, + QUERY_DELETE_COLLAPSED_BUYABLE_HOUSES, + QUERY_DELETE_COLLAPSED_USER_HOUSES, }; +use crate::worker::{insert_notification_conn, publish_update_status}; pub struct HouseWorker { base: BaseWorker, @@ -23,7 +26,7 @@ impl HouseWorker { } } - fn run_loop(pool: ConnectionPool, _broker: MessageBroker, state: Arc) { + fn run_loop(pool: ConnectionPool, broker: MessageBroker, state: Arc) { let mut last_hourly_run: Option = None; let mut last_daily_run: Option = None; @@ -40,6 +43,9 @@ impl HouseWorker { if let Err(err) = Self::perform_task_inner(&pool) { eprintln!("[HouseWorker] Fehler in performTask: {err}"); } + if let Err(err) = Self::cleanup_collapsed_houses(&pool, &broker) { + eprintln!("[HouseWorker] Fehler in cleanup_collapsed_houses: {err}"); + } last_hourly_run = Some(now); } @@ -53,6 +59,10 @@ impl HouseWorker { if let Err(err) = Self::perform_house_state_change_inner(&pool) { eprintln!("[HouseWorker] Fehler in performHouseStateChange: {err}"); } + // Nach der täglichen Verschlechterung direkt zusammengefallene Häuser aufräumen. + if let Err(err) = Self::cleanup_collapsed_houses(&pool, &broker) { + eprintln!("[HouseWorker] Fehler in cleanup_collapsed_houses: {err}"); + } last_daily_run = Some(now); } @@ -101,6 +111,57 @@ impl HouseWorker { Ok(()) } + + fn cleanup_collapsed_houses(pool: &ConnectionPool, broker: &MessageBroker) -> Result<(), DbError> { + let mut conn = pool + .get() + .map_err(|e| DbError::new(format!("[HouseWorker] DB-Verbindung fehlgeschlagen: {e}")))?; + + conn.prepare( + "delete_collapsed_buyable_houses", + QUERY_DELETE_COLLAPSED_BUYABLE_HOUSES, + )?; + conn.prepare( + "delete_collapsed_user_houses", + QUERY_DELETE_COLLAPSED_USER_HOUSES, + )?; + + // 1) Kaufbare Häuser (ohne Besitzer) löschen + let deleted_buyable = conn.execute("delete_collapsed_buyable_houses", &[])?; + if !deleted_buyable.is_empty() { + eprintln!( + "[HouseWorker] {} kaufbare(s) Haus/Häuser zusammengefallen und entfernt", + deleted_buyable.len() + ); + } + + // 2) Häuser im Besitz löschen + Owner informieren + let deleted_user_houses = conn.execute("delete_collapsed_user_houses", &[])?; + if deleted_user_houses.is_empty() { + return Ok(()); + } + + for row in deleted_user_houses { + let house_id = row + .get("house_id") + .and_then(|v| v.parse::().ok()) + .unwrap_or(-1); + let user_id = row + .get("user_id") + .and_then(|v| v.parse::().ok()) + .unwrap_or(-1); + if house_id < 0 || user_id < 0 { + continue; + } + + // Notification + Frontend-Update + let tr = format!(r#"{{"tr":"house.collapsed","house_id":{}}}"#, house_id); + let _ = insert_notification_conn(&mut conn, user_id, &tr, None); + publish_update_status(broker, user_id); + } + + Ok(()) + } } impl Worker for HouseWorker { diff --git a/src/worker/sql.rs b/src/worker/sql.rs index 9bd5d80..7f71a60 100644 --- a/src/worker/sql.rs +++ b/src/worker/sql.rs @@ -594,6 +594,36 @@ pub const QUERY_UPDATE_USER_HOUSE_STATE: &str = r#" ); "#; +// Haus-Zusammenfall: Sobald eine Komponente <= 0 ist, wird das Haus entfernt. +// Gilt sowohl für kaufbare Häuser als auch für Häuser im Besitz. +pub const QUERY_DELETE_COLLAPSED_BUYABLE_HOUSES: &str = r#" + WITH deleted AS ( + DELETE FROM falukant_data.buyable_house + WHERE LEAST( + roof_condition, + floor_condition, + wall_condition, + window_condition + ) <= 0 + RETURNING id + ) + SELECT id AS house_id FROM deleted; +"#; + +pub const QUERY_DELETE_COLLAPSED_USER_HOUSES: &str = r#" + WITH deleted AS ( + DELETE FROM falukant_data.user_house + WHERE LEAST( + roof_condition, + floor_condition, + wall_condition, + window_condition + ) <= 0 + RETURNING id, user_id + ) + SELECT id AS house_id, user_id FROM deleted; +"#; + pub const QUERY_UPDATE_HOUSE_QUALITY: &str = r#" UPDATE falukant_data.user_house SET roof_condition = GREATEST(0, LEAST(100, roof_condition + $1)),