-- Debug-Queries: Tod -> Erbwechsel -> Cleanup -- Nutzung: -- psql ... -f docs/DEBUG_DEATH_SUCCESSION_QUERIES.sql -- Ersetze zuerst: -- :character_id (verstorbener Charakter) -- :user_id (falukant_user.id des Spielers) -- :heir_id (optional; geplanter Erbe) -- -- In psql z. B.: -- \set character_id 123 -- \set user_id 45 -- \set heir_id 678 -- ============================================================ -- 0) Vorab: Existenz / Ausgangszustand prüfen -- ============================================================ SELECT c.id, c.user_id, c.health, c.updated_at FROM falukant_data.character c WHERE c.id = :character_id; SELECT fu.id, fu.user_id, fu.money, fu.certificate FROM falukant_data.falukant_user fu WHERE fu.id = :user_id; -- Mögliche Erben (wie QUERY_GET_HEIR priorisiert) SELECT child_character_id, is_heir, updated_at FROM falukant_data.child_relation WHERE father_character_id = :character_id OR mother_character_id = :character_id ORDER BY (is_heir IS TRUE) DESC, updated_at DESC LIMIT 20; -- Fallback-Erbe (entspricht QUERY_RANDOM_HEIR-Prinzip: nur Vorschau) SELECT cr.child_character_id FROM falukant_data.child_relation cr JOIN falukant_data.character c ON c.id = cr.child_character_id WHERE (cr.father_character_id = :character_id OR cr.mother_character_id = :character_id) AND c.health > 0 ORDER BY RANDOM() LIMIT 1; -- ============================================================ -- 1) Queries, die der Daemon im Todespfad nutzt (Vorschau) -- Reihenfolge entspricht Worker-Logik. -- ============================================================ -- 1.1 get_falukant_user_id SELECT user_id FROM falukant_data.character WHERE id = :character_id; -- 1.2 get_heir (bevorzugt is_heir=true) SELECT child_character_id FROM falukant_data.child_relation WHERE father_character_id = :character_id OR mother_character_id = :character_id ORDER BY (is_heir IS TRUE) DESC, updated_at DESC LIMIT 1; -- 1.3 random_heir (wenn 1.2 leer) SELECT cr.child_character_id FROM falukant_data.child_relation cr JOIN falukant_data.character c ON c.id = cr.child_character_id WHERE (cr.father_character_id = :character_id OR cr.mother_character_id = :character_id) AND c.health > 0 ORDER BY RANDOM() LIMIT 1; -- 1.4 set_character_user (nur wenn Erbe vorhanden) -- UPDATE falukant_data.character -- SET user_id = :user_id, updated_at = NOW() -- WHERE id = :heir_id; -- 1.5 Vermögensberechnung: Inputs SELECT money FROM falukant_data.falukant_user WHERE id = :user_id; SELECT COALESCE(SUM(h.cost), 0) AS sum FROM falukant_data.user_house uh JOIN falukant_type.house h ON uh.house_type_id = h.id WHERE uh.user_id = :user_id; SELECT COALESCE(SUM(b.base_cost), 0) AS sum FROM falukant_data.branch br JOIN falukant_type.branch b ON br.branch_type_id = b.id WHERE br.falukant_user_id = :user_id; SELECT COALESCE(SUM(i.quantity * p.sell_cost), 0) AS sum FROM falukant_data.inventory i JOIN falukant_type.product p ON i.product_id = p.id JOIN falukant_data.stock s ON i.stock_id = s.id JOIN falukant_data.branch br ON s.branch_id = br.id WHERE br.falukant_user_id = :user_id; SELECT COALESCE(SUM(remaining_amount), 0) AS sum FROM falukant_data.credit WHERE falukant_user_id = :user_id; SELECT COUNT(DISTINCT cr.child_character_id) AS cnt FROM falukant_data.child_relation cr JOIN falukant_data.character parent ON (parent.id = cr.father_character_id OR parent.id = cr.mother_character_id) WHERE parent.user_id = :user_id; -- 1.6 set_new_money (nur wenn du den errechneten Wert testen willst) -- UPDATE falukant_data.falukant_user -- SET money = '', updated_at = NOW() -- WHERE id = :user_id; -- 1.7 delete_director WITH deleted AS ( DELETE FROM falukant_data.director WHERE director_character_id = :character_id RETURNING employer_user_id ) SELECT * FROM deleted; -- 1.8 delete_relationship WITH deleted AS ( DELETE FROM falukant_data.relationship WHERE character1_id = :character_id OR character2_id = :character_id RETURNING CASE WHEN character1_id = :character_id THEN character2_id ELSE character1_id END AS related_character_id ) SELECT c.user_id AS related_user_id FROM deleted d JOIN falukant_data.character c ON c.id = d.related_character_id; -- 1.9 delete_child_relation_by_parent DELETE FROM falukant_data.child_relation WHERE father_character_id = :character_id OR mother_character_id = :character_id; -- 1.10 delete_child_relation (als Kind) WITH deleted AS ( DELETE FROM falukant_data.child_relation WHERE child_character_id = :character_id RETURNING father_character_id, mother_character_id ) SELECT cf.user_id AS father_user_id, cm.user_id AS mother_user_id FROM deleted d JOIN falukant_data.character cf ON cf.id = d.father_character_id JOIN falukant_data.character cm ON cm.id = d.mother_character_id; -- 1.11 zusätzliche Cleanup-Queries DELETE FROM falukant_data.knowledge WHERE character_id = :character_id; DELETE FROM falukant_data.debtors_prism WHERE character_id = :character_id; WITH removed AS ( DELETE FROM falukant_data.political_office WHERE character_id = :character_id RETURNING character_id, office_type_id, region_id, created_at ), archived_removed AS ( INSERT INTO falukant_log.political_office_history (character_id, office_type_id, region_id, start_date, end_date) SELECT character_id, office_type_id, region_id, created_at, NOW() FROM removed ), affected AS ( SELECT DISTINCT office_type_id, region_id FROM removed ), seats AS ( SELECT pot.id AS office_type_id, rt.id AS region_id, pot.seats_per_region AS seats_total FROM falukant_type.political_office_type pot JOIN falukant_type.region rt ON pot.region_type = rt.label_tr JOIN affected a ON a.office_type_id = pot.id AND a.region_id = rt.id ), ranked AS ( SELECT po.id, po.character_id, po.office_type_id, po.region_id, po.created_at, s.seats_total, ROW_NUMBER() OVER ( PARTITION BY po.office_type_id, po.region_id ORDER BY po.created_at DESC ) AS rn FROM falukant_data.political_office po JOIN seats s ON s.office_type_id = po.office_type_id AND s.region_id = po.region_id ), to_delete AS ( SELECT id, character_id, office_type_id, region_id, created_at FROM ranked WHERE rn > seats_total ), archived_trim AS ( INSERT INTO falukant_log.political_office_history (character_id, office_type_id, region_id, start_date, end_date) SELECT character_id, office_type_id, region_id, created_at, NOW() FROM to_delete ) DELETE FROM falukant_data.political_office WHERE id IN (SELECT id FROM to_delete); -- election_candidate ist nicht in allen Bestands-DBs vorhanden: SELECT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'falukant_data' AND table_name = 'election_candidate' ) AS election_candidate_table_ready; -- Nur ausführen, wenn vorher TRUE: -- DELETE FROM falukant_data.election_candidate -- WHERE character_id = :character_id; -- 1.12 final delete_character DELETE FROM falukant_data.character WHERE id = :character_id; -- ============================================================ -- 2) Nachkontrolle (muss leer / 0 sein) -- ============================================================ SELECT 1 AS character_still_exists FROM falukant_data.character WHERE id = :character_id; SELECT COUNT(*) AS knowledge_left FROM falukant_data.knowledge WHERE character_id = :character_id; SELECT COUNT(*) AS debtors_prism_left FROM falukant_data.debtors_prism WHERE character_id = :character_id; SELECT COUNT(*) AS political_office_left FROM falukant_data.political_office WHERE character_id = :character_id; SELECT COUNT(*) AS election_candidate_left FROM falukant_data.election_candidate WHERE character_id = :character_id; SELECT * FROM falukant_log.political_office_history WHERE character_id = :character_id ORDER BY end_date DESC LIMIT 10; -- Neuer aktiver Charakter des Users: SELECT c.id, c.user_id, c.health, c.updated_at FROM falukant_data.character c WHERE c.user_id = :user_id ORDER BY c.updated_at DESC, c.id DESC LIMIT 10; -- ============================================================ -- 3) Unabhängig: completion_count-Fehler für Zertifikat -- ============================================================ -- 3.1 Existiert Spalte? SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'falukant_log' AND table_name = 'production' AND column_name = 'completion_count'; -- 3.2 Sofort-Fix (idempotent), falls Spalte fehlt oder unvollständig: ALTER TABLE falukant_log.production ADD COLUMN IF NOT EXISTS completion_count integer; UPDATE falukant_log.production SET completion_count = 1 WHERE completion_count IS NULL; ALTER TABLE falukant_log.production ALTER COLUMN completion_count SET DEFAULT 1, ALTER COLUMN completion_count SET NOT NULL; -- 3.3 Optional: Migration historisch sauber markieren/prüfen -- (abhängig davon, wie ihr Migrationsstände verwaltet)