Integrate death log functionality into character and event processing: Added death context handling in CharacterCreationWorker and EventsWorker to enhance user notifications related to character deaths. Updated SQL queries for retrieving deceased context and modified notification logic to support detailed death notifications. Enhanced user notification methods to accommodate both short event names and JSON payloads for improved clarity in messaging.
This commit is contained in:
5
migrations/009_falukant_region_display_name.sql
Normal file
5
migrations/009_falukant_region_display_name.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
-- Optionaler Anzeigename für Regionen (Todes-/UI-Logs, Karten); ohne Spalte liefert der Daemon nur region_id.
|
||||
ALTER TABLE falukant_data.region
|
||||
ADD COLUMN IF NOT EXISTS name text;
|
||||
|
||||
COMMENT ON COLUMN falukant_data.region.name IS 'Optional: Orts-/Regionsname für Logs und UI';
|
||||
@@ -10,6 +10,7 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use super::base::{BaseWorker, Worker, WorkerState};
|
||||
use super::death_log;
|
||||
use crate::worker::sql::{
|
||||
QUERY_IS_PREVIOUS_DAY_CHARACTER_CREATED,
|
||||
QUERY_GET_TOWN_REGION_IDS,
|
||||
@@ -404,6 +405,14 @@ impl CharacterCreationWorker {
|
||||
.get()
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
let death_ctx = match death_log::build_deceased_context(&mut conn, character_id) {
|
||||
Ok(c) => Some(c),
|
||||
Err(e) => {
|
||||
eprintln!("[CharacterCreationWorker] Todes-Log Kontext: {e}");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
// 1) Director löschen und User benachrichtigen
|
||||
conn.prepare("delete_director", QUERY_DELETE_DIRECTOR)?;
|
||||
let dir_result = conn.execute("delete_director", &[&character_id])?;
|
||||
@@ -412,7 +421,15 @@ impl CharacterCreationWorker {
|
||||
.get("employer_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, user_id, "director_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "director_death", user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
user_id,
|
||||
tr.as_deref().unwrap_or("director_death"),
|
||||
)?;
|
||||
}
|
||||
|
||||
// 2) Relationships löschen und betroffene User benachrichtigen
|
||||
@@ -423,7 +440,15 @@ impl CharacterCreationWorker {
|
||||
.get("related_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, related_user_id, "relationship_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "relationship_death", related_user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
related_user_id,
|
||||
tr.as_deref().unwrap_or("relationship_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,13 +462,29 @@ impl CharacterCreationWorker {
|
||||
.get("father_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, father_user_id, "child_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "child_death", father_user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
father_user_id,
|
||||
tr.as_deref().unwrap_or("child_death"),
|
||||
)?;
|
||||
}
|
||||
if let Some(mother_user_id) = row
|
||||
.get("mother_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, mother_user_id, "child_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "child_death", mother_user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
mother_user_id,
|
||||
tr.as_deref().unwrap_or("child_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,24 +498,27 @@ impl CharacterCreationWorker {
|
||||
pool: &ConnectionPool,
|
||||
broker: &MessageBroker,
|
||||
user_id: i32,
|
||||
event_type: &str,
|
||||
tr_payload: &str,
|
||||
) -> Result<(), DbError> {
|
||||
let mut conn = pool
|
||||
.get()
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
conn.prepare("insert_notification", QUERY_INSERT_NOTIFICATION)?;
|
||||
conn.execute("insert_notification", &[&user_id, &event_type])?;
|
||||
conn.execute("insert_notification", &[&user_id, &tr_payload])?;
|
||||
|
||||
// falukantUpdateStatus
|
||||
let update_message =
|
||||
format!(r#"{{"event":"falukantUpdateStatus","user_id":{}}}"#, user_id);
|
||||
broker.publish(update_message);
|
||||
|
||||
// ursprüngliche Benachrichtigung
|
||||
let message =
|
||||
format!(r#"{{"event":"{event_type}","user_id":{}}}"#, user_id);
|
||||
broker.publish(message);
|
||||
if tr_payload.trim_start().starts_with('{') {
|
||||
broker.publish(tr_payload.to_string());
|
||||
} else {
|
||||
let message =
|
||||
format!(r#"{{"event":"{tr_payload}","user_id":{user_id}}}"#);
|
||||
broker.publish(message);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
107
src/worker/death_log.rs
Normal file
107
src/worker/death_log.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
//! Kontext für `falukant_log.notification` bei Charaktertod (Direktor, Partner, Eltern).
|
||||
//! `tr` enthält JSON mit Verstorbenem, Ansässigkeit, Alter, Ehe/Kind/Liebschaft.
|
||||
//!
|
||||
//! **Aufruf vor** `DELETE` auf `relationship` / `child_relation`, sonst sind Partner/Kinder/Geliebte leer.
|
||||
//!
|
||||
//! **Geliebte** sind keine eigene Tabelle: `falukant_data.relationship` + Typ `falukant_type.relationship.tr = 'lover'`,
|
||||
//! Zusatzdaten in `relationship_state`. Zählt nur, wenn `relationship_state.active` nicht `false` ist (wie Backend-UI).
|
||||
//! `lover_role` (`secret_affair` / `lover` / `mistress_or_favorite`) wird für die Liste **nicht** gefiltert.
|
||||
//!
|
||||
//! Kinder aus Liebschaft sind in `child_relation.birth_context = 'lover'` markiert; zusätzlich unter `linked.lover_birth_children`.
|
||||
|
||||
use crate::db::{DbConnection, DbError, Row};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use crate::worker::sql::{
|
||||
QUERY_DEATH_LOG_CHARACTER_BASE, QUERY_DEATH_LOG_CHILD_DISPLAY_NAMES,
|
||||
QUERY_DEATH_LOG_CHILD_LOVER_BIRTH_DISPLAY_NAMES, QUERY_DEATH_LOG_LOVER_DISPLAY_NAMES,
|
||||
QUERY_DEATH_LOG_SPOUSE_DISPLAY_NAMES,
|
||||
};
|
||||
|
||||
fn collect_display_names(rows: Vec<Row>, key: &str) -> Vec<String> {
|
||||
let mut out = Vec::new();
|
||||
for r in rows {
|
||||
if let Some(s) = r.get(key) {
|
||||
let t = s.trim();
|
||||
if !t.is_empty() {
|
||||
out.push(t.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// 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<Value, DbError> {
|
||||
conn.prepare("death_base", QUERY_DEATH_LOG_CHARACTER_BASE)?;
|
||||
let base_rows = conn.execute("death_base", &[&deceased_character_id])?;
|
||||
let base = base_rows.first().ok_or_else(|| {
|
||||
DbError::new(format!(
|
||||
"Todes-Log: Charakter {deceased_character_id} nicht gefunden"
|
||||
))
|
||||
})?;
|
||||
|
||||
let character_id = base
|
||||
.get("character_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(deceased_character_id);
|
||||
let display_name = base
|
||||
.get("display_name")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| character_id.to_string());
|
||||
let region_id = base
|
||||
.get("region_id")
|
||||
.and_then(|v| v.parse::<i32>().ok());
|
||||
let region_label = base
|
||||
.get("region_label")
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let age_years = base
|
||||
.get("age_years")
|
||||
.and_then(|v| v.parse::<i32>().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");
|
||||
|
||||
Ok(json!({
|
||||
"deceased": {
|
||||
"character_id": character_id,
|
||||
"display_name": display_name,
|
||||
"region_id": region_id,
|
||||
"region_label": region_label,
|
||||
"age_years": age_years,
|
||||
},
|
||||
"linked": {
|
||||
"spouses": spouses,
|
||||
"children": children,
|
||||
"lover_birth_children": lover_birth_children,
|
||||
"lovers": lovers,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
/// Vollständiges `tr`-/WebSocket-JSON mit `event` und `user_id`.
|
||||
pub fn wrap_death_notification(context: &Value, event: &str, user_id: i32) -> String {
|
||||
json!({
|
||||
"event": event,
|
||||
"user_id": user_id,
|
||||
"deceased": context.get("deceased"),
|
||||
"linked": context.get("linked"),
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use super::base::{BaseWorker, Worker, WorkerState};
|
||||
use super::death_log;
|
||||
use crate::worker::sql::{
|
||||
QUERY_GET_RANDOM_USER,
|
||||
QUERY_GET_RANDOM_INFANT,
|
||||
@@ -1751,6 +1752,15 @@ impl EventsWorker {
|
||||
.get()
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
// Todes-Kontext (Namen, Ort, Alter, Ehe/Kind/Liebschaft) vor Löschen der Beziehungen
|
||||
let death_ctx = match death_log::build_deceased_context(&mut conn, character_id) {
|
||||
Ok(c) => Some(c),
|
||||
Err(e) => {
|
||||
eprintln!("[EventsWorker] Todes-Log Kontext: {e}");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
// 1) Director löschen und User benachrichtigen
|
||||
conn.prepare("delete_director", QUERY_DELETE_DIRECTOR)?;
|
||||
let dir_result = conn.execute("delete_director", &[&character_id])?;
|
||||
@@ -1759,7 +1769,15 @@ impl EventsWorker {
|
||||
.get("employer_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, user_id, "director_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "director_death", user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
user_id,
|
||||
tr.as_deref().unwrap_or("director_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1771,7 +1789,15 @@ impl EventsWorker {
|
||||
.get("related_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, related_user_id, "relationship_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "relationship_death", related_user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
related_user_id,
|
||||
tr.as_deref().unwrap_or("relationship_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1801,13 +1827,29 @@ impl EventsWorker {
|
||||
.get("father_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, father_user_id, "child_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "child_death", father_user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
father_user_id,
|
||||
tr.as_deref().unwrap_or("child_death"),
|
||||
)?;
|
||||
}
|
||||
if let Some(mother_user_id) = row
|
||||
.get("mother_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
Self::notify_user(pool, broker, mother_user_id, "child_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "child_death", mother_user_id)
|
||||
});
|
||||
Self::notify_user(
|
||||
pool,
|
||||
broker,
|
||||
mother_user_id,
|
||||
tr.as_deref().unwrap_or("child_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1937,28 +1979,32 @@ impl EventsWorker {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `tr_payload`: kurzer `event`-Name oder JSON-Objekt (Todes-Logs mit `deceased`/`linked`).
|
||||
fn notify_user(
|
||||
pool: &ConnectionPool,
|
||||
broker: &MessageBroker,
|
||||
user_id: i32,
|
||||
event_type: &str,
|
||||
tr_payload: &str,
|
||||
) -> Result<(), DbError> {
|
||||
let mut conn = pool
|
||||
.get()
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
conn.prepare("insert_notification", QUERY_INSERT_NOTIFICATION)?;
|
||||
conn.execute("insert_notification", &[&user_id, &event_type])?;
|
||||
conn.execute("insert_notification", &[&user_id, &tr_payload])?;
|
||||
|
||||
// falukantUpdateStatus
|
||||
let update_message =
|
||||
format!(r#"{{"event":"falukantUpdateStatus","user_id":{}}}"#, user_id);
|
||||
broker.publish(update_message);
|
||||
|
||||
// ursprüngliche Benachrichtigung
|
||||
let message =
|
||||
format!(r#"{{"event":"{event_type}","user_id":{}}}"#, user_id);
|
||||
broker.publish(message);
|
||||
if tr_payload.trim_start().starts_with('{') {
|
||||
broker.publish(tr_payload.to_string());
|
||||
} else {
|
||||
let message =
|
||||
format!(r#"{{"event":"{tr_payload}","user_id":{user_id}}}"#);
|
||||
broker.publish(message);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ mod user_character;
|
||||
mod transport;
|
||||
mod weather;
|
||||
mod events;
|
||||
mod death_log;
|
||||
mod falukant_family;
|
||||
mod falukant_certificate;
|
||||
mod falukant_servants;
|
||||
|
||||
@@ -641,6 +641,67 @@ pub const QUERY_GET_REGION_CHARACTERS: &str = r#"
|
||||
SELECT id, health, user_id FROM falukant_data."character" WHERE region_id = $1 AND health > 0;
|
||||
"#;
|
||||
|
||||
/// Anzeige für Todes-Logs (`falukant_log.notification.tr` als JSON): Name, Wohnort, Alter, Verknüpfungen.
|
||||
/// `region_id` = Ansässigkeit; `region_label` aus `falukant_data.region.name`, falls vorhanden, sonst `region_id` als Text.
|
||||
pub const QUERY_DEATH_LOG_CHARACTER_BASE: &str = r#"
|
||||
SELECT
|
||||
c.id AS character_id,
|
||||
COALESCE(TRIM(BOTH FROM COALESCE(fn.label::text, '') || ' ' || COALESCE(ln.label::text, '')), c.id::text) AS display_name,
|
||||
c.region_id,
|
||||
COALESCE(NULLIF(TRIM(dr.name::text), ''), c.region_id::text) AS region_label,
|
||||
GREATEST(0, FLOOR((CURRENT_DATE - c.birthdate::date) / 365.25))::int AS age_years
|
||||
FROM falukant_data.character c
|
||||
LEFT JOIN falukant_predefine.firstname fn ON fn.id = c.first_name
|
||||
LEFT JOIN falukant_predefine.lastname ln ON ln.id = c.last_name
|
||||
LEFT JOIN falukant_data.region dr ON dr.id = c.region_id
|
||||
WHERE c.id = $1::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEATH_LOG_SPOUSE_DISPLAY_NAMES: &str = r#"
|
||||
SELECT COALESCE(TRIM(BOTH FROM COALESCE(fn.label::text, '') || ' ' || COALESCE(ln.label::text, '')), o.id::text) AS display_name
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id
|
||||
AND rt.tr IN ('married', 'engaged', 'wooing')
|
||||
JOIN falukant_data.character o ON o.id = CASE WHEN r.character1_id = $1::int THEN r.character2_id ELSE r.character1_id END
|
||||
LEFT JOIN falukant_predefine.firstname fn ON fn.id = o.first_name
|
||||
LEFT JOIN falukant_predefine.lastname ln ON ln.id = o.last_name
|
||||
WHERE r.character1_id = $1::int OR r.character2_id = $1::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DEATH_LOG_CHILD_DISPLAY_NAMES: &str = r#"
|
||||
SELECT COALESCE(TRIM(BOTH FROM COALESCE(fn.label::text, '') || ' ' || COALESCE(ln.label::text, '')), ch.id::text) AS display_name
|
||||
FROM falukant_data.child_relation cr
|
||||
JOIN falukant_data.character ch ON ch.id = cr.child_character_id
|
||||
LEFT JOIN falukant_predefine.firstname fn ON fn.id = ch.first_name
|
||||
LEFT JOIN falukant_predefine.lastname ln ON ln.id = ch.last_name
|
||||
WHERE cr.father_character_id = $1::int OR cr.mother_character_id = $1::int;
|
||||
"#;
|
||||
|
||||
/// Kinder mit `birth_context = 'lover'` (unehelich / aus Liebschaft); Teilmenge von `QUERY_DEATH_LOG_CHILD_DISPLAY_NAMES`.
|
||||
pub const QUERY_DEATH_LOG_CHILD_LOVER_BIRTH_DISPLAY_NAMES: &str = r#"
|
||||
SELECT COALESCE(TRIM(BOTH FROM COALESCE(fn.label::text, '') || ' ' || COALESCE(ln.label::text, '')), ch.id::text) AS display_name
|
||||
FROM falukant_data.child_relation cr
|
||||
JOIN falukant_data.character ch ON ch.id = cr.child_character_id
|
||||
LEFT JOIN falukant_predefine.firstname fn ON fn.id = ch.first_name
|
||||
LEFT JOIN falukant_predefine.lastname ln ON ln.id = ch.last_name
|
||||
WHERE (cr.father_character_id = $1::int OR cr.mother_character_id = $1::int)
|
||||
AND cr.birth_context = 'lover';
|
||||
"#;
|
||||
|
||||
/// Geliebte: Zeilen in `falukant_data.relationship`, Typ über `falukant_type.relationship` mit `tr = 'lover'`
|
||||
/// (kein Filter auf `relationship_state.lover_role` — `secret_affair` / `lover` / `mistress_or_favorite` sind nur Ausprägungen).
|
||||
/// „Aktiv“ wie Backend (`falukantService`): `relationship_state.active` darf nicht `false` sein (`IS NOT FALSE`).
|
||||
pub const QUERY_DEATH_LOG_LOVER_DISPLAY_NAMES: &str = r#"
|
||||
SELECT COALESCE(TRIM(BOTH FROM COALESCE(fn.label::text, '') || ' ' || COALESCE(ln.label::text, '')), o.id::text) AS display_name
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id AND rt.tr = 'lover'
|
||||
JOIN falukant_data.relationship_state rs ON rs.relationship_id = r.id AND (rs.active IS NOT FALSE)
|
||||
JOIN falukant_data.character o ON o.id = CASE WHEN r.character1_id = $1::int THEN r.character2_id ELSE r.character1_id END
|
||||
LEFT JOIN falukant_predefine.firstname fn ON fn.id = o.first_name
|
||||
LEFT JOIN falukant_predefine.lastname ln ON ln.id = o.last_name
|
||||
WHERE r.character1_id = $1::int OR r.character2_id = $1::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_DELETE_DIRECTOR: &str = r#"
|
||||
DELETE FROM falukant_data.director WHERE director_character_id = $1 RETURNING employer_user_id;
|
||||
"#;
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use super::base::{BaseWorker, Worker, WorkerState};
|
||||
use super::death_log;
|
||||
use crate::worker::sql::{
|
||||
QUERY_GET_CHARACTERS_ZERO_HEALTH,
|
||||
QUERY_GET_USERS_TO_UPDATE,
|
||||
@@ -646,23 +647,28 @@ impl UserCharacterWorker {
|
||||
self.base.broker.publish(update_status);
|
||||
}
|
||||
|
||||
/// Wie `EventsWorker::notify_user`: Eintrag in `falukant_log.notification` (`tr` = event_type) + WS.
|
||||
/// Wie `EventsWorker::notify_user`: Eintrag in `falukant_log.notification` (`tr` = Payload) + WS.
|
||||
/// `tr_payload` kann ein Kurz-String (`director_death`) oder vollständiges JSON sein.
|
||||
fn notify_user_death(
|
||||
&self,
|
||||
conn: &mut crate::db::DbConnection,
|
||||
user_id: i32,
|
||||
event_type: &str,
|
||||
tr_payload: &str,
|
||||
) -> Result<(), DbError> {
|
||||
if user_id <= 0 {
|
||||
return Ok(());
|
||||
}
|
||||
conn.execute("insert_notification", &[&user_id, &event_type])?;
|
||||
conn.execute("insert_notification", &[&user_id, &tr_payload])?;
|
||||
let update_message =
|
||||
format!(r#"{{"event":"falukantUpdateStatus","user_id":{}}}"#, user_id);
|
||||
self.base.broker.publish(update_message);
|
||||
let message =
|
||||
format!(r#"{{"event":"{event_type}","user_id":{}}}"#, user_id);
|
||||
self.base.broker.publish(message);
|
||||
if tr_payload.trim_start().starts_with('{') {
|
||||
self.base.broker.publish(tr_payload.to_string());
|
||||
} else {
|
||||
let message =
|
||||
format!(r#"{{"event":"{tr_payload}","user_id":{user_id}}}"#);
|
||||
self.base.broker.publish(message);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -692,13 +698,28 @@ 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
|
||||
.get("employer_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
self.notify_user_death(&mut conn, user_id, "director_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "director_death", user_id)
|
||||
});
|
||||
self.notify_user_death(
|
||||
&mut conn,
|
||||
user_id,
|
||||
tr.as_deref().unwrap_or("director_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,7 +729,14 @@ impl UserCharacterWorker {
|
||||
.get("related_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
self.notify_user_death(&mut conn, related_user_id, "relationship_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "relationship_death", related_user_id)
|
||||
});
|
||||
self.notify_user_death(
|
||||
&mut conn,
|
||||
related_user_id,
|
||||
tr.as_deref().unwrap_or("relationship_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,13 +747,27 @@ impl UserCharacterWorker {
|
||||
.get("father_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
self.notify_user_death(&mut conn, father_user_id, "child_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "child_death", father_user_id)
|
||||
});
|
||||
self.notify_user_death(
|
||||
&mut conn,
|
||||
father_user_id,
|
||||
tr.as_deref().unwrap_or("child_death"),
|
||||
)?;
|
||||
}
|
||||
if let Some(mother_user_id) = row
|
||||
.get("mother_user_id")
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
{
|
||||
self.notify_user_death(&mut conn, mother_user_id, "child_death")?;
|
||||
let tr = death_ctx.as_ref().map(|c| {
|
||||
death_log::wrap_death_notification(c, "child_death", mother_user_id)
|
||||
});
|
||||
self.notify_user_death(
|
||||
&mut conn,
|
||||
mother_user_id,
|
||||
tr.as_deref().unwrap_or("child_death"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
conn.execute("delete_knowledge", &[&character_id])?;
|
||||
|
||||
Reference in New Issue
Block a user