Entferne automatische Annahme alter Bewerbungen und implementiere Entscheidung durch NPCs für offene Stellen ohne Vorgesetzten
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 5m13s

This commit is contained in:
Torsten Schulz (local)
2026-08-26 10:01:21 +02:00
parent 521a1104ec
commit fb5c1eb8be
3 changed files with 207 additions and 145 deletions

View File

@@ -3215,7 +3215,8 @@ pub const QUERY_CREATE_CHURCH_APPLICATION_JOB: &str = r#"
RETURNING id;
"#;
/// Nur NPCs: Spielerbewerbungen laufen über die UI.
/// Nur NPCs: Für den Einstieg ohne Amt, für eine Beförderung ausschließlich aus
/// dem unmittelbar niedrigeren derzeitigen Kirchenamt.
pub const QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE: &str = r#"
SELECT DISTINCT
c.id AS character_id,
@@ -3224,17 +3225,29 @@ pub const QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE: &str = r#"
c.title_of_nobility,
t.level AS title_level
FROM falukant_data.character c
JOIN falukant_type.church_office_type target ON target.id = $2::int
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
WHERE co.character_id = c.id
AND (
(target.hierarchy_level <= 1 AND NOT EXISTS(
SELECT 1
FROM falukant_data.church_office co
WHERE co.character_id = c.id
))
OR
(target.hierarchy_level > 1 AND EXISTS(
SELECT 1
FROM falukant_data.church_office co
JOIN falukant_type.church_office_type current
ON current.id = co.office_type_id
WHERE co.character_id = c.id
AND current.hierarchy_level = target.hierarchy_level - 1
))
)
ORDER BY RANDOM()
LIMIT $2;
LIMIT $3;
"#;
pub const QUERY_COUNT_PENDING_CHURCH_APPS_BY_OFFICE_REGION: &str = r#"
@@ -3285,9 +3298,45 @@ pub const QUERY_GET_PENDING_CHURCH_APPLICATIONS_FOR_SCORING: &str = r#"
LEFT JOIN falukant_type.title t ON t.id = ac.title_of_nobility
WHERE ca.status = 'pending'
AND ca.supervisor_id = $1::int
AND ca.created_at <= NOW() - INTERVAL '2 days'
ORDER BY ca.created_at ASC;
"#;
/// Einstiegsämter haben noch keinen Amtsinhaber als Vorgesetzten. Diese offenen
/// Bewerbungen werden deshalb vom Kirchen-NPC für die konkrete Stelle entschieden.
pub const QUERY_GET_PENDING_CHURCH_APPLICATIONS_WITHOUT_SUPERVISOR: &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,
50.0::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 cot2.id = co2.office_type_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_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 IS NULL
AND ca.office_type_id = $1::int
AND ca.region_id = $2::int
AND ca.created_at <= NOW() - INTERVAL '2 days'
ORDER BY ca.created_at ASC;
"#;
#[allow(dead_code)]
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)
@@ -3307,6 +3356,7 @@ pub const QUERY_INTERIM_APPOINT_CHURCH_OFFICE: &str = r#"
RETURNING id, office_type_id, character_id, region_id;
"#;
#[allow(dead_code)]
pub const QUERY_UPDATE_CHARACTER_HIGHEST_CHURCH_FROM_OFFICE_TYPE: &str = r#"
UPDATE falukant_data.character c
SET highest_church_hierarchy_ever = GREATEST(
@@ -3317,6 +3367,7 @@ pub const QUERY_UPDATE_CHARACTER_HIGHEST_CHURCH_FROM_OFFICE_TYPE: &str = r#"
RETURNING c.id;
"#;
#[allow(dead_code)]
pub const QUERY_FIND_INTERIM_CHURCH_NPC_CANDIDATE: &str = r#"
SELECT c.id AS character_id
FROM falukant_data.character c
@@ -3337,6 +3388,7 @@ pub const QUERY_FIND_INTERIM_CHURCH_NPC_CANDIDATE: &str = r#"
LIMIT 1;
"#;
#[allow(dead_code)]
pub const QUERY_REMOVE_LOWER_CHURCH_OFFICES_FOR_CHARACTER: &str = r#"
DELETE FROM falukant_data.church_office co
WHERE co.character_id = $1::int
@@ -4100,4 +4152,16 @@ mod tests {
assert!(query.contains(">= 16"), "{query}");
}
}
#[test]
fn npc_church_promotions_wait_two_days_and_require_the_direct_lower_rank() {
assert!(QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE
.contains("current.hierarchy_level = target.hierarchy_level - 1"));
for query in [
QUERY_GET_PENDING_CHURCH_APPLICATIONS_FOR_SCORING,
QUERY_GET_PENDING_CHURCH_APPLICATIONS_WITHOUT_SUPERVISOR,
] {
assert!(query.contains("created_at <= NOW() - INTERVAL '2 days'"));
}
}
}