diff --git a/src/worker/death_log.rs b/src/worker/death_log.rs index ce0ea94..74054a0 100644 --- a/src/worker/death_log.rs +++ b/src/worker/death_log.rs @@ -31,6 +31,28 @@ fn collect_display_names(rows: Vec, key: &str) -> Vec { out } +/// Verknüpfte Namen (Ehe, Kinder, Geliebte): optional — bei Schema-/SQL-Fehlern leere Liste, +/// damit der **Kern** (`deceased`) trotzdem als JSON in `notification.tr` landet. +fn optional_linked_names( + conn: &mut DbConnection, + log_label: &'static str, + stmt: &'static str, + query: &str, + deceased_character_id: i32, +) -> Vec { + if let Err(e) = conn.prepare(stmt, query) { + eprintln!("[death_log] {log_label} prepare: {e}"); + return Vec::new(); + } + match conn.execute(stmt, &[&deceased_character_id]) { + Ok(rows) => collect_display_names(rows, "display_name"), + Err(e) => { + eprintln!("[death_log] {log_label} execute: {e}"); + Vec::new() + } + } +} + /// Lädt Verstorbenen + Ehepartner, Kinder, **aktive Geliebte** (`tr = 'lover'`, `active IS NOT FALSE`). /// Muss ausgeführt werden, bevor Beziehungen aus der DB gelöscht werden. pub fn build_deceased_context(conn: &mut DbConnection, deceased_character_id: i32) -> Result { @@ -62,21 +84,34 @@ pub fn build_deceased_context(conn: &mut DbConnection, deceased_character_id: i3 .and_then(|v| v.parse::().ok()) .unwrap_or(0); - conn.prepare("death_spouse", QUERY_DEATH_LOG_SPOUSE_DISPLAY_NAMES)?; - let spouse_rows = conn.execute("death_spouse", &[&deceased_character_id])?; - let spouses = collect_display_names(spouse_rows, "display_name"); - - conn.prepare("death_child", QUERY_DEATH_LOG_CHILD_DISPLAY_NAMES)?; - let child_rows = conn.execute("death_child", &[&deceased_character_id])?; - let children = collect_display_names(child_rows, "display_name"); - - conn.prepare("death_child_lover_birth", QUERY_DEATH_LOG_CHILD_LOVER_BIRTH_DISPLAY_NAMES)?; - let child_lover_rows = conn.execute("death_child_lover_birth", &[&deceased_character_id])?; - let lover_birth_children = collect_display_names(child_lover_rows, "display_name"); - - conn.prepare("death_lover", QUERY_DEATH_LOG_LOVER_DISPLAY_NAMES)?; - let lover_rows = conn.execute("death_lover", &[&deceased_character_id])?; - let lovers = collect_display_names(lover_rows, "display_name"); + let spouses = optional_linked_names( + conn, + "spouse", + "death_spouse", + QUERY_DEATH_LOG_SPOUSE_DISPLAY_NAMES, + deceased_character_id, + ); + let children = optional_linked_names( + conn, + "child", + "death_child", + QUERY_DEATH_LOG_CHILD_DISPLAY_NAMES, + deceased_character_id, + ); + let lover_birth_children = optional_linked_names( + conn, + "child_lover_birth", + "death_child_lover_birth", + QUERY_DEATH_LOG_CHILD_LOVER_BIRTH_DISPLAY_NAMES, + deceased_character_id, + ); + let lovers = optional_linked_names( + conn, + "lover", + "death_lover", + QUERY_DEATH_LOG_LOVER_DISPLAY_NAMES, + deceased_character_id, + ); Ok(json!({ "deceased": { diff --git a/src/worker/user_character.rs b/src/worker/user_character.rs index 6360876..a371e2d 100644 --- a/src/worker/user_character.rs +++ b/src/worker/user_character.rs @@ -806,6 +806,24 @@ impl UserCharacterWorker { // Todes- und Erb-Logik fn handle_character_death(&mut self, character_id: i32) -> Result<(), DbError> { + // Todes-Kontext **vor** Erbfolge und vor allen DELETEs (wie EventsWorker / CharacterCreationWorker). + // So ist der Charakter garantiert noch in `character`, und bei Race mit anderem Worker schlägt + // spätestens hier fehl — nicht erst nach `set_heir`. + let death_ctx = { + let mut conn = self + .base + .pool + .get() + .map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?; + match death_log::build_deceased_context(&mut conn, character_id) { + Ok(c) => Some(c), + Err(e) => { + eprintln!("[UserCharacterWorker] Todes-Log Kontext: {e}"); + None + } + } + }; + self.set_heir(character_id)?; let death_event = format!( @@ -830,14 +848,6 @@ impl UserCharacterWorker { conn.prepare("delete_election_candidate", QUERY_DELETE_ELECTION_CANDIDATE)?; conn.prepare("insert_notification", QUERY_INSERT_NOTIFICATION)?; - let death_ctx = match death_log::build_deceased_context(&mut conn, character_id) { - Ok(c) => Some(c), - Err(e) => { - eprintln!("[UserCharacterWorker] Todes-Log Kontext: {e}"); - None - } - }; - let dir_result = conn.execute("delete_director", &[&character_id])?; for row in dir_result { if let Some(user_id) = row