From cb22b111a3cebc8fc7ab3997ace17a1714093db1 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 13 May 2026 22:06:09 +0200 Subject: [PATCH] Enhance birth delivery queries to prevent multiple births per mother per day: Updated SQL queries for marriage and planned character birth deliveries to include checks that prevent a mother from having more than one child born on the same calendar day. This change ensures compliance with the business rule of one child per mother per day, regardless of the father. --- src/worker/sql.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/worker/sql.rs b/src/worker/sql.rs index a4813c6..57e80eb 100644 --- a/src/worker/sql.rs +++ b/src/worker/sql.rs @@ -2184,6 +2184,8 @@ pub const QUERY_AUTOBATISM: &str = r#" /// Fällige Geburten (Ehe): `marriage_pregnancy_due_at <= NOW()`. /// B2: keine Ehe-Geburt, solange die Mutter eine **geplante** Schwangerschaft (`character.pregnancy_due_at`) hat. +/// B3: keine Ehe-Geburt am selben Kalendertag, an dem die Mutter schon **irgendein** Kind geboren hat +/// (Ehe/Liebschaft/geplant — ein Kind pro Mutter und Tag). pub const QUERY_GET_MARRIAGE_BIRTH_DELIVERIES: &str = r#" SELECT r.id AS relationship_id, @@ -2209,7 +2211,13 @@ pub const QUERY_GET_MARRIAGE_BIRTH_DELIVERIES: &str = r#" AND r.marriage_pregnancy_due_at <= NOW() AND ((c1.gender = 'male' AND c2.gender = 'female') OR (c1.gender = 'female' AND c2.gender = 'male')) - AND c_female.pregnancy_due_at IS NULL; + AND c_female.pregnancy_due_at IS NULL + AND NOT EXISTS ( + SELECT 1 + FROM falukant_data.child_relation cr_b + WHERE cr_b.mother_character_id = c_female.id + AND cr_b.created_at::date = CURRENT_DATE + ); "#; pub const QUERY_CLEAR_MARRIAGE_PREGNANCY_DUE: &str = r#" @@ -2372,6 +2380,12 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#" WHERE ((c1.gender = 'male' AND c2.gender = 'female') OR (c1.gender = 'female' AND c2.gender = 'male')) AND c_female.pregnancy_due_at IS NULL + AND NOT EXISTS ( + SELECT 1 + FROM falukant_data.child_relation cr_b + WHERE cr_b.mother_character_id = c_female.id + AND cr_b.created_at::date = CURRENT_DATE + ) ), mother_age AS ( SELECT @@ -2459,6 +2473,7 @@ pub const QUERY_CHARACTER_PLANNED_PREGNANCY_COLUMNS_READY: &str = r#" /// Fällige **geplante** Geburten (Weg A): Mutter trägt Termin + Vater; kein Ehe-`relationship`-Bezug. /// Vater NULL oder = Mutter: keine Zeile (Daemon überspringt; optional im Log). +/// Keine Auslieferung, wenn die Mutter heute schon ein Kind geboren hat (ein Kind pro Mutter und Tag). pub const QUERY_GET_PLANNED_CHARACTER_BIRTH_DELIVERIES: &str = r#" SELECT c_m.id AS mother_cid, @@ -2486,7 +2501,13 @@ pub const QUERY_GET_PLANNED_CHARACTER_BIRTH_DELIVERIES: &str = r#" AND c_m.pregnancy_due_at <= NOW() AND c_m.pregnancy_father_character_id IS NOT NULL AND c_m.pregnancy_father_character_id <> c_m.id - AND c_m.health > 0; + AND c_m.health > 0 + AND NOT EXISTS ( + SELECT 1 + FROM falukant_data.child_relation cr_b + WHERE cr_b.mother_character_id = c_m.id + AND cr_b.created_at::date = CURRENT_DATE + ); "#; pub const QUERY_CLEAR_CHARACTER_PREGNANCY_AFTER_BIRTH: &str = r#" @@ -3919,6 +3940,8 @@ pub const QUERY_UPDATE_CHARACTER_REPUTATION: &str = r#" WHERE id = $2::int; "#; +/// Liebschafts-Konzeption: gleiche Sperre wie Ehe auf `character.pregnancy_due_at` (geplante Schwangerschaft). +/// Max. ein Kind pro Mutter und Kalendertag — unabhängig vom Vater (Ehe/Liebschaft/geplant). pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#" SELECT CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END AS father_cid, @@ -3946,12 +3969,12 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#" -- `last_monthly_processed_at` wird im Familien-Tageslauf mitgeführt (1 Spieljahr = 1 Kalendertag). AND rs.last_monthly_processed_at IS NOT NULL AND rs.last_monthly_processed_at >= NOW() - INTERVAL '50 days' + AND c_female.pregnancy_due_at IS NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.child_relation cr - WHERE cr.father_character_id = (CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END) - AND cr.mother_character_id = (CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END) - AND cr.created_at::date >= CURRENT_DATE + WHERE cr.mother_character_id = c_female.id + AND cr.created_at::date = CURRENT_DATE ) AND (CURRENT_DATE - c_female.birthdate::date) >= 4380 AND (CURRENT_DATE - c_female.birthdate::date) < 18993 @@ -4018,7 +4041,8 @@ pub const QUERY_INSERT_CHILD_RELATION_LOVER: &str = r#" ); "#; -/// Realismus-Regel: pro Mutter maximal eine Geburt pro Kalendertag. +/// Pro Mutter maximal eine Geburt pro Kalendertag (jeder Vater); Rust prüft zusätzlich vor Insert. +/// Kandidaten-Queries (Ehe/Liebschaft/geplant) schließen dieselbe Regel per `NOT EXISTS` ein. pub const QUERY_HAS_MOTHER_BIRTH_TODAY: &str = r#" SELECT EXISTS ( SELECT 1