automatic apply on church jobs
This commit is contained in:
@@ -32,6 +32,8 @@ use crate::worker::sql::{
|
|||||||
QUERY_REJECT_CHURCH_APPLICATION,
|
QUERY_REJECT_CHURCH_APPLICATION,
|
||||||
QUERY_CREATE_CHURCH_APPLICATION_JOB,
|
QUERY_CREATE_CHURCH_APPLICATION_JOB,
|
||||||
QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE,
|
QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE,
|
||||||
|
QUERY_GET_OLD_PENDING_CHURCH_APPLICATIONS,
|
||||||
|
QUERY_AUTO_APPROVE_CHURCH_APPLICATION,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct PoliticsWorker {
|
pub struct PoliticsWorker {
|
||||||
@@ -106,6 +108,7 @@ impl PoliticsWorker {
|
|||||||
fn run_loop(pool: ConnectionPool, broker: MessageBroker, state: Arc<WorkerState>) {
|
fn run_loop(pool: ConnectionPool, broker: MessageBroker, state: Arc<WorkerState>) {
|
||||||
let mut last_execution: Option<Instant> = None;
|
let mut last_execution: Option<Instant> = None;
|
||||||
let mut last_church_office_run: Option<Instant> = None;
|
let mut last_church_office_run: Option<Instant> = None;
|
||||||
|
let mut last_auto_approve_run: Option<Instant> = None;
|
||||||
|
|
||||||
while state.running_worker.load(Ordering::Relaxed) {
|
while state.running_worker.load(Ordering::Relaxed) {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
@@ -140,6 +143,21 @@ impl PoliticsWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Automatische Annahme alter Applications (stündlich)
|
||||||
|
let should_run_auto_approve = match last_auto_approve_run {
|
||||||
|
None => true,
|
||||||
|
Some(prev) => {
|
||||||
|
now.saturating_duration_since(prev) >= Duration::from_secs(3600)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_run_auto_approve {
|
||||||
|
if let Err(err) = Self::auto_approve_old_church_applications(&pool, &broker) {
|
||||||
|
eprintln!("[PoliticsWorker] Fehler bei auto_approve_old_church_applications: {err}");
|
||||||
|
}
|
||||||
|
last_auto_approve_run = Some(now);
|
||||||
|
}
|
||||||
|
|
||||||
// Entspricht ungefähr der 5-Sekunden-Schleife im C++-Code
|
// Entspricht ungefähr der 5-Sekunden-Schleife im C++-Code
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
if !state.running_worker.load(Ordering::Relaxed) {
|
if !state.running_worker.load(Ordering::Relaxed) {
|
||||||
@@ -999,6 +1017,94 @@ impl PoliticsWorker {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Automatische Annahme von Church Applications, die älter als 36 Stunden sind
|
||||||
|
fn auto_approve_old_church_applications(
|
||||||
|
pool: &ConnectionPool,
|
||||||
|
broker: &MessageBroker,
|
||||||
|
) -> Result<(), DbError> {
|
||||||
|
let mut conn = pool
|
||||||
|
.get()
|
||||||
|
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||||
|
|
||||||
|
// Alle alten pending Applications abrufen
|
||||||
|
conn.prepare(
|
||||||
|
"get_old_pending_church_applications",
|
||||||
|
QUERY_GET_OLD_PENDING_CHURCH_APPLICATIONS,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
DbError::new(format!(
|
||||||
|
"[PoliticsWorker] prepare get_old_pending_church_applications: {e}"
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let rows = conn
|
||||||
|
.execute("get_old_pending_church_applications", &[])
|
||||||
|
.map_err(|e| {
|
||||||
|
DbError::new(format!(
|
||||||
|
"[PoliticsWorker] exec get_old_pending_church_applications: {e}"
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut old_applications = Vec::new();
|
||||||
|
for row in rows {
|
||||||
|
let application_id = parse_i32(&row, "application_id", -1);
|
||||||
|
let character_id = parse_i32(&row, "character_id", -1);
|
||||||
|
|
||||||
|
if application_id >= 0 {
|
||||||
|
old_applications.push((application_id, character_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if old_applications.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!(
|
||||||
|
"[PoliticsWorker] Gefunden: {} alte Church Applications (36h+), automatische Annahme",
|
||||||
|
old_applications.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Prepare auto-approve query
|
||||||
|
conn.prepare(
|
||||||
|
"auto_approve_church_application",
|
||||||
|
QUERY_AUTO_APPROVE_CHURCH_APPLICATION,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
DbError::new(format!(
|
||||||
|
"[PoliticsWorker] prepare auto_approve_church_application: {e}"
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Alle alten Applications automatisch annehmen
|
||||||
|
for (application_id, character_id) in &old_applications {
|
||||||
|
let approve_rows = conn
|
||||||
|
.execute("auto_approve_church_application", &[application_id])
|
||||||
|
.map_err(|e| {
|
||||||
|
DbError::new(format!(
|
||||||
|
"[PoliticsWorker] exec auto_approve_church_application: {e}"
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if !approve_rows.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"[PoliticsWorker] Church Application {} automatisch angenommen (36h+ alt, character_id={})",
|
||||||
|
application_id, character_id
|
||||||
|
);
|
||||||
|
|
||||||
|
// Benachrichtigung senden
|
||||||
|
if let Some(user_id) = Self::get_user_id_for_character(pool, *character_id)? {
|
||||||
|
let msg = format!(
|
||||||
|
r#"{{"event":"falukantUpdateStatus","user_id":{}}}"#,
|
||||||
|
user_id
|
||||||
|
);
|
||||||
|
broker.publish(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_user_id_for_character(
|
fn get_user_id_for_character(
|
||||||
pool: &ConnectionPool,
|
pool: &ConnectionPool,
|
||||||
character_id: i32,
|
character_id: i32,
|
||||||
|
|||||||
@@ -1836,6 +1836,62 @@ pub const QUERY_REJECT_CHURCH_APPLICATION: &str = r#"
|
|||||||
RETURNING id;
|
RETURNING id;
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
pub const QUERY_GET_OLD_PENDING_CHURCH_APPLICATIONS: &str = r#"
|
||||||
|
SELECT
|
||||||
|
ca.id AS application_id,
|
||||||
|
ca.office_type_id,
|
||||||
|
ca.character_id,
|
||||||
|
ca.region_id,
|
||||||
|
ca.supervisor_id
|
||||||
|
FROM falukant_data.church_application ca
|
||||||
|
WHERE ca.status = 'pending'
|
||||||
|
AND ca.created_at <= NOW() - INTERVAL '36 hours'
|
||||||
|
ORDER BY ca.created_at ASC;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
pub const QUERY_AUTO_APPROVE_CHURCH_APPLICATION: &str = r#"
|
||||||
|
WITH updated_application AS (
|
||||||
|
UPDATE falukant_data.church_application
|
||||||
|
SET status = 'approved',
|
||||||
|
decision_date = NOW(),
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = $1
|
||||||
|
AND status = 'pending'
|
||||||
|
AND created_at <= NOW() - INTERVAL '36 hours'
|
||||||
|
RETURNING
|
||||||
|
office_type_id,
|
||||||
|
character_id,
|
||||||
|
region_id,
|
||||||
|
supervisor_id
|
||||||
|
),
|
||||||
|
inserted_office AS (
|
||||||
|
INSERT INTO falukant_data.church_office
|
||||||
|
(office_type_id, character_id, region_id, supervisor_id, created_at, updated_at)
|
||||||
|
SELECT
|
||||||
|
office_type_id,
|
||||||
|
character_id,
|
||||||
|
region_id,
|
||||||
|
supervisor_id,
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
FROM updated_application
|
||||||
|
WHERE NOT EXISTS(
|
||||||
|
SELECT 1
|
||||||
|
FROM falukant_data.church_office co
|
||||||
|
WHERE co.office_type_id = updated_application.office_type_id
|
||||||
|
AND co.region_id = updated_application.region_id
|
||||||
|
AND co.character_id = updated_application.character_id
|
||||||
|
)
|
||||||
|
RETURNING id, office_type_id, character_id, region_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
id AS office_id,
|
||||||
|
office_type_id,
|
||||||
|
character_id,
|
||||||
|
region_id
|
||||||
|
FROM inserted_office;
|
||||||
|
"#;
|
||||||
|
|
||||||
pub const QUERY_CREATE_CHURCH_APPLICATION_JOB: &str = r#"
|
pub const QUERY_CREATE_CHURCH_APPLICATION_JOB: &str = r#"
|
||||||
INSERT INTO falukant_data.church_application
|
INSERT INTO falukant_data.church_application
|
||||||
(office_type_id, character_id, region_id, supervisor_id, status, created_at, updated_at)
|
(office_type_id, character_id, region_id, supervisor_id, status, created_at, updated_at)
|
||||||
|
|||||||
Reference in New Issue
Block a user