Enhance church office management in Falukant daemon: Introduced falukantUpdateChurch event for church applications and appointments, updated SQL queries for church office processing, and refactored the PoliticsWorker to streamline daily tasks related to church offices. Improved handling of church application scoring and interim appointments, enhancing overall church dynamics and character interactions.
This commit is contained in:
@@ -1772,11 +1772,12 @@ pub const QUERY_SET_LEARNING_DONE: &str = r#"
|
||||
WHERE id = $1;
|
||||
"#;
|
||||
|
||||
// Church Office Queries
|
||||
// Church Office Queries (siehe docs/FALUKANT_CHURCH_DAEMON.md)
|
||||
pub const QUERY_FIND_AVAILABLE_CHURCH_OFFICES: &str = r#"
|
||||
SELECT
|
||||
cot.id AS office_type_id,
|
||||
cot.name AS office_type_name,
|
||||
cot.hierarchy_level,
|
||||
cot.seats_per_region,
|
||||
cot.region_type,
|
||||
r.id AS region_id,
|
||||
@@ -1788,7 +1789,7 @@ pub const QUERY_FIND_AVAILABLE_CHURCH_OFFICES: &str = r#"
|
||||
ON cot.id = co.office_type_id
|
||||
AND co.region_id = r.id
|
||||
WHERE tr.label_tr = cot.region_type
|
||||
GROUP BY cot.id, cot.name, cot.seats_per_region, cot.region_type, r.id
|
||||
GROUP BY cot.id, cot.name, cot.hierarchy_level, cot.seats_per_region, cot.region_type, r.id
|
||||
HAVING COUNT(co.id) < cot.seats_per_region
|
||||
ORDER BY cot.hierarchy_level ASC, r.id;
|
||||
"#;
|
||||
@@ -1821,6 +1822,8 @@ pub const QUERY_GET_CHURCH_OFFICE_REQUIREMENTS: &str = r#"
|
||||
WHERE office_type_id = $1;
|
||||
"#;
|
||||
|
||||
/// Optional für Backend/API; der Daemon nutzt `QUERY_GET_PENDING_CHURCH_APPLICATIONS_FOR_SCORING`.
|
||||
#[allow(dead_code)]
|
||||
pub const QUERY_GET_PENDING_CHURCH_APPLICATIONS: &str = r#"
|
||||
SELECT
|
||||
ca.id AS application_id,
|
||||
@@ -1837,8 +1840,15 @@ pub const QUERY_GET_PENDING_CHURCH_APPLICATIONS: &str = r#"
|
||||
ORDER BY cot.hierarchy_level ASC, ca.created_at ASC;
|
||||
"#;
|
||||
|
||||
/// Voraussetzung: Migration `007_falukant_character_church_career.sql` (highest_church_hierarchy_ever).
|
||||
pub const QUERY_CHECK_CHARACTER_ELIGIBILITY: &str = r#"
|
||||
WITH character_info AS (
|
||||
WITH prereq AS (
|
||||
SELECT $2::int AS prereq_type_id,
|
||||
CASE WHEN $2::int IS NULL THEN NULL ELSE (
|
||||
SELECT hierarchy_level FROM falukant_type.church_office_type WHERE id = $2::int
|
||||
) END AS prereq_hl
|
||||
),
|
||||
char_h AS (
|
||||
SELECT
|
||||
c.id AS character_id,
|
||||
c.title_of_nobility,
|
||||
@@ -1847,34 +1857,43 @@ pub const QUERY_CHECK_CHARACTER_ELIGIBILITY: &str = r#"
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co2
|
||||
WHERE co2.character_id = c.id
|
||||
) AS has_office
|
||||
) AS has_office,
|
||||
COALESCE(c.highest_church_hierarchy_ever, 0)::int AS highest_ever,
|
||||
COALESCE((
|
||||
SELECT MAX(cot2.hierarchy_level)
|
||||
FROM falukant_data.church_office co2
|
||||
JOIN falukant_type.church_office_type cot2 ON co2.office_type_id = cot2.id
|
||||
WHERE co2.character_id = c.id
|
||||
), 0) AS current_max_hl
|
||||
FROM falukant_data.character c
|
||||
LEFT JOIN falukant_type.title t ON c.title_of_nobility = t.id
|
||||
WHERE c.id = $1
|
||||
),
|
||||
prerequisite_check AS (
|
||||
SELECT
|
||||
CASE
|
||||
WHEN $2::int IS NULL THEN TRUE
|
||||
ELSE EXISTS(
|
||||
)
|
||||
SELECT
|
||||
ch.character_id,
|
||||
ch.title_level,
|
||||
ch.has_office,
|
||||
CASE
|
||||
WHEN pr.prereq_type_id IS NULL THEN TRUE
|
||||
ELSE (
|
||||
EXISTS(
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co
|
||||
WHERE co.character_id = $1
|
||||
AND co.office_type_id = $2::int
|
||||
AND co.office_type_id = pr.prereq_type_id
|
||||
)
|
||||
END AS has_prerequisite
|
||||
)
|
||||
SELECT
|
||||
ci.character_id,
|
||||
ci.title_level,
|
||||
ci.has_office,
|
||||
pc.has_prerequisite,
|
||||
OR (
|
||||
pr.prereq_hl IS NOT NULL
|
||||
AND GREATEST(ch.highest_ever, ch.current_max_hl) >= pr.prereq_hl
|
||||
)
|
||||
)
|
||||
END AS has_prerequisite,
|
||||
CASE
|
||||
WHEN $3::int IS NULL THEN TRUE
|
||||
ELSE COALESCE(ci.title_level, 0) >= $3::int
|
||||
ELSE COALESCE(ch.title_level, 0) >= $3::int
|
||||
END AS meets_title_requirement
|
||||
FROM character_info ci
|
||||
CROSS JOIN prerequisite_check pc;
|
||||
FROM char_h ch
|
||||
CROSS JOIN prereq pr;
|
||||
"#;
|
||||
|
||||
pub const QUERY_APPROVE_CHURCH_APPLICATION: &str = r#"
|
||||
@@ -1910,6 +1929,36 @@ pub const QUERY_APPROVE_CHURCH_APPLICATION: &str = r#"
|
||||
AND co.character_id = updated_application.character_id
|
||||
)
|
||||
RETURNING id, office_type_id, character_id, region_id
|
||||
),
|
||||
upd_highest AS (
|
||||
UPDATE falukant_data.character c
|
||||
SET highest_church_hierarchy_ever = GREATEST(
|
||||
COALESCE(c.highest_church_hierarchy_ever, 0),
|
||||
io.hl
|
||||
)::smallint
|
||||
FROM (
|
||||
SELECT io2.character_id, cot.hierarchy_level AS hl
|
||||
FROM inserted_office io2
|
||||
JOIN falukant_type.church_office_type cot ON cot.id = io2.office_type_id
|
||||
) io
|
||||
WHERE c.id = io.character_id
|
||||
RETURNING c.id
|
||||
),
|
||||
remove_lower_ranked AS (
|
||||
DELETE FROM falukant_data.church_office co
|
||||
WHERE co.id IN (
|
||||
SELECT co3.id
|
||||
FROM falukant_data.church_office co3
|
||||
JOIN falukant_type.church_office_type cot ON co3.office_type_id = cot.id
|
||||
WHERE co3.character_id IN (SELECT character_id FROM inserted_office)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co2
|
||||
JOIN falukant_type.church_office_type cot2 ON co2.office_type_id = cot2.id
|
||||
WHERE co2.character_id = co3.character_id
|
||||
AND cot2.hierarchy_level > cot.hierarchy_level
|
||||
)
|
||||
)
|
||||
)
|
||||
SELECT
|
||||
id AS office_id,
|
||||
@@ -1929,6 +1978,7 @@ pub const QUERY_REJECT_CHURCH_APPLICATION: &str = r#"
|
||||
RETURNING id;
|
||||
"#;
|
||||
|
||||
/// Nur NPC-Vorgesetzte: Spieler-Entscheidungen nicht per Timeout überschreiben.
|
||||
pub const QUERY_GET_OLD_PENDING_CHURCH_APPLICATIONS: &str = r#"
|
||||
SELECT
|
||||
ca.id AS application_id,
|
||||
@@ -1937,8 +1987,10 @@ pub const QUERY_GET_OLD_PENDING_CHURCH_APPLICATIONS: &str = r#"
|
||||
ca.region_id,
|
||||
ca.supervisor_id
|
||||
FROM falukant_data.church_application ca
|
||||
JOIN falukant_data.character sup ON sup.id = ca.supervisor_id
|
||||
WHERE ca.status = 'pending'
|
||||
AND ca.created_at <= NOW() - INTERVAL '36 hours'
|
||||
AND sup.user_id IS NULL
|
||||
ORDER BY ca.created_at ASC;
|
||||
"#;
|
||||
|
||||
@@ -1976,6 +2028,36 @@ pub const QUERY_AUTO_APPROVE_CHURCH_APPLICATION: &str = r#"
|
||||
AND co.character_id = updated_application.character_id
|
||||
)
|
||||
RETURNING id, office_type_id, character_id, region_id
|
||||
),
|
||||
upd_highest AS (
|
||||
UPDATE falukant_data.character c
|
||||
SET highest_church_hierarchy_ever = GREATEST(
|
||||
COALESCE(c.highest_church_hierarchy_ever, 0),
|
||||
io.hl
|
||||
)::smallint
|
||||
FROM (
|
||||
SELECT io2.character_id, cot.hierarchy_level AS hl
|
||||
FROM inserted_office io2
|
||||
JOIN falukant_type.church_office_type cot ON cot.id = io2.office_type_id
|
||||
) io
|
||||
WHERE c.id = io.character_id
|
||||
RETURNING c.id
|
||||
),
|
||||
remove_lower_ranked AS (
|
||||
DELETE FROM falukant_data.church_office co
|
||||
WHERE co.id IN (
|
||||
SELECT co3.id
|
||||
FROM falukant_data.church_office co3
|
||||
JOIN falukant_type.church_office_type cot ON co3.office_type_id = cot.id
|
||||
WHERE co3.character_id IN (SELECT character_id FROM inserted_office)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co2
|
||||
JOIN falukant_type.church_office_type cot2 ON co2.office_type_id = cot2.id
|
||||
WHERE co2.character_id = co3.character_id
|
||||
AND cot2.hierarchy_level > cot.hierarchy_level
|
||||
)
|
||||
)
|
||||
)
|
||||
SELECT
|
||||
id AS office_id,
|
||||
@@ -2007,6 +2089,7 @@ pub const QUERY_CREATE_CHURCH_APPLICATION_JOB: &str = r#"
|
||||
RETURNING id;
|
||||
"#;
|
||||
|
||||
/// Nur NPCs: Spielerbewerbungen laufen über die UI.
|
||||
pub const QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE: &str = r#"
|
||||
SELECT DISTINCT
|
||||
c.id AS character_id,
|
||||
@@ -2018,6 +2101,7 @@ pub const QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE: &str = r#"
|
||||
LEFT JOIN falukant_type.title t ON c.title_of_nobility = t.id
|
||||
WHERE c.region_id = $1
|
||||
AND c.health > 0
|
||||
AND c.user_id IS NULL
|
||||
AND NOT EXISTS(
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co
|
||||
@@ -2027,6 +2111,124 @@ pub const QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE: &str = r#"
|
||||
LIMIT $2;
|
||||
"#;
|
||||
|
||||
pub const QUERY_COUNT_PENDING_CHURCH_APPS_BY_OFFICE_REGION: &str = r#"
|
||||
SELECT COUNT(*)::int AS cnt
|
||||
FROM falukant_data.church_application ca
|
||||
WHERE ca.office_type_id = $1::int
|
||||
AND ca.region_id = $2::int
|
||||
AND ca.status = 'pending';
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_CHURCH_OFFICE_OCCUPIED_COUNT: &str = r#"
|
||||
SELECT COUNT(*)::int AS cnt
|
||||
FROM falukant_data.church_office co
|
||||
WHERE co.office_type_id = $1::int
|
||||
AND co.region_id = $2::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_IS_CHARACTER_NPC: &str = r#"
|
||||
SELECT (c.user_id IS NULL) AS is_npc
|
||||
FROM falukant_data.character c
|
||||
WHERE c.id = $1::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_GET_PENDING_CHURCH_APPLICATIONS_FOR_SCORING: &str = r#"
|
||||
SELECT
|
||||
ca.id AS application_id,
|
||||
ca.office_type_id,
|
||||
ca.character_id AS applicant_character_id,
|
||||
ca.region_id,
|
||||
ca.created_at,
|
||||
cot.hierarchy_level AS office_hierarchy_level,
|
||||
cot.seats_per_region,
|
||||
COALESCE(sc.reputation, 50)::float8 AS supervisor_reputation,
|
||||
COALESCE(ac.reputation, 50)::float8 AS applicant_reputation,
|
||||
COALESCE(ac.highest_church_hierarchy_ever, 0)::int AS applicant_highest_ever,
|
||||
COALESCE(t.level, 0)::int AS applicant_title_level,
|
||||
COALESCE((
|
||||
SELECT MAX(cot2.hierarchy_level)
|
||||
FROM falukant_data.church_office co2
|
||||
JOIN falukant_type.church_office_type cot2 ON co2.office_type_id = cot2.id
|
||||
WHERE co2.character_id = ac.id
|
||||
), 0)::int AS applicant_current_max_hierarchy,
|
||||
(CURRENT_DATE - ac.birthdate::date)::int AS applicant_age_days
|
||||
FROM falukant_data.church_application ca
|
||||
JOIN falukant_data.character ac ON ac.id = ca.character_id
|
||||
JOIN falukant_data.character sc ON sc.id = ca.supervisor_id
|
||||
JOIN falukant_type.church_office_type cot ON cot.id = ca.office_type_id
|
||||
LEFT JOIN falukant_type.title t ON t.id = ac.title_of_nobility
|
||||
WHERE ca.status = 'pending'
|
||||
AND ca.supervisor_id = $1::int
|
||||
ORDER BY ca.created_at ASC;
|
||||
"#;
|
||||
|
||||
pub const QUERY_INTERIM_APPOINT_CHURCH_OFFICE: &str = r#"
|
||||
INSERT INTO falukant_data.church_office
|
||||
(office_type_id, character_id, region_id, supervisor_id, created_at, updated_at)
|
||||
SELECT $1::int, $2::int, $3::int, NULL, NOW(), NOW()
|
||||
WHERE (
|
||||
SELECT COUNT(*)::int
|
||||
FROM falukant_data.church_office co
|
||||
WHERE co.office_type_id = $1::int
|
||||
AND co.region_id = $3::int
|
||||
) < $4::int
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM falukant_data.church_office co
|
||||
WHERE co.character_id = $2::int
|
||||
AND co.office_type_id = $1::int
|
||||
AND co.region_id = $3::int
|
||||
)
|
||||
RETURNING id, office_type_id, character_id, region_id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_UPDATE_CHARACTER_HIGHEST_CHURCH_FROM_OFFICE_TYPE: &str = r#"
|
||||
UPDATE falukant_data.character c
|
||||
SET highest_church_hierarchy_ever = GREATEST(
|
||||
COALESCE(c.highest_church_hierarchy_ever, 0),
|
||||
(SELECT cot.hierarchy_level FROM falukant_type.church_office_type cot WHERE cot.id = $2::int)
|
||||
)::smallint
|
||||
WHERE c.id = $1::int
|
||||
RETURNING c.id;
|
||||
"#;
|
||||
|
||||
pub const QUERY_FIND_INTERIM_CHURCH_NPC_CANDIDATE: &str = r#"
|
||||
SELECT c.id AS character_id
|
||||
FROM falukant_data.character c
|
||||
WHERE c.region_id = $1::int
|
||||
AND c.user_id IS NULL
|
||||
AND c.health > 0
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co
|
||||
JOIN falukant_type.church_office_type cot ON cot.id = co.office_type_id
|
||||
WHERE co.character_id = c.id
|
||||
AND cot.hierarchy_level >= (
|
||||
SELECT hierarchy_level FROM falukant_type.church_office_type WHERE id = $2::int
|
||||
)
|
||||
)
|
||||
ORDER BY COALESCE(c.reputation, 50) DESC,
|
||||
COALESCE(c.highest_church_hierarchy_ever, 0) DESC
|
||||
LIMIT 1;
|
||||
"#;
|
||||
|
||||
pub const QUERY_REMOVE_LOWER_CHURCH_OFFICES_FOR_CHARACTER: &str = r#"
|
||||
DELETE FROM falukant_data.church_office co
|
||||
WHERE co.character_id = $1::int
|
||||
AND co.id IN (
|
||||
SELECT co3.id
|
||||
FROM falukant_data.church_office co3
|
||||
JOIN falukant_type.church_office_type cot ON co3.office_type_id = cot.id
|
||||
WHERE co3.character_id = $1::int
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.church_office co2
|
||||
JOIN falukant_type.church_office_type cot2 ON co2.office_type_id = cot2.id
|
||||
WHERE co2.character_id = co3.character_id
|
||||
AND cot2.hierarchy_level > cot.hierarchy_level
|
||||
)
|
||||
);
|
||||
"#;
|
||||
|
||||
// --- Falukant: Dienerschaft (siehe migrations/004_falukant_servants_daemon.sql) ---
|
||||
|
||||
pub const QUERY_SERVANTS_SCHEMA_READY: &str = r#"
|
||||
|
||||
Reference in New Issue
Block a user