Enhance production certificate and election result handling: Updated the logic in run_daily to improve clarity on level progression based on weighted scores, including detailed logging for cases where players meet minimum requirements but do not advance. Introduced a new function to notify players of election results, integrating SQL queries for efficient data retrieval and notification management. Enhanced documentation for the production certificate process to clarify UI vs. daemon discrepancies.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 2m54s

This commit is contained in:
Torsten Schulz (local)
2026-04-02 14:48:39 +02:00
parent 619e5e5123
commit 21525ec125
4 changed files with 230 additions and 0 deletions

View File

@@ -1208,6 +1208,87 @@ pub const QUERY_PROCESS_ELECTIONS: &str = r#"
FROM falukant_data.process_elections();
"#;
/// Wahlergebnis für Spieler-Kandidaten (`falukant_data.candidate` + `character.user_id IS NOT NULL`).
/// Läuft nach `process_elections()`; Deduplizierung über bestehende `election_result`-Notifications (`tr` JSON).
pub const QUERY_PLAYER_ELECTION_RESULT_ROWS: &str = r#"
WITH vote_counts AS (
SELECT c.id AS candidate_id,
c.election_id,
c.character_id,
COUNT(v.id)::bigint AS vote_count
FROM falukant_data.candidate c
LEFT JOIN falukant_data.vote v ON v.candidate_id = c.id
GROUP BY c.id, c.election_id, c.character_id
),
top_per_election AS (
SELECT DISTINCT ON (vc.election_id)
vc.election_id,
vc.character_id AS top_character_id,
vc.vote_count AS top_votes
FROM vote_counts vc
ORDER BY vc.election_id, vc.vote_count DESC, vc.candidate_id
),
eligible AS (
SELECT e.id AS election_id,
e.office_type_id,
e.region_id,
e.posts_to_fill,
vc.candidate_id,
vc.character_id,
vc.vote_count,
ch.user_id
FROM falukant_data.election e
JOIN vote_counts vc ON vc.election_id = e.id
JOIN falukant_data.character ch ON ch.id = vc.character_id
WHERE ch.user_id IS NOT NULL
AND e.date::date <= CURRENT_DATE
AND e.date::date >= CURRENT_DATE - INTERVAL '7 days'
AND NOT EXISTS (
SELECT 1
FROM falukant_log.notification n
WHERE n.user_id = ch.user_id
AND n.tr LIKE '{%'
AND (n.tr::jsonb->>'event') = 'election_result'
AND (n.tr::jsonb->>'election_id')::int = e.id
)
),
ranked AS (
SELECT vc.candidate_id,
ROW_NUMBER() OVER (
PARTITION BY vc.election_id
ORDER BY vc.vote_count DESC, vc.candidate_id
) AS rank_in_election
FROM vote_counts vc
)
SELECT elig.user_id,
elig.election_id,
elig.office_type_id,
COALESCE(pot.name::text, '') AS office_name,
elig.region_id,
COALESCE(NULLIF(TRIM(dr.name::text), ''), elig.region_id::text) AS region_name,
elig.character_id,
elig.candidate_id,
elig.vote_count AS your_votes,
COALESCE(rk.rank_in_election, 0)::int AS rank_in_election,
EXISTS (
SELECT 1
FROM falukant_data.political_office po
WHERE po.character_id = elig.character_id
AND po.office_type_id = elig.office_type_id
AND po.region_id = elig.region_id
AND po.created_at >= (CURRENT_TIMESTAMP - INTERVAL '3 days')
) AS won,
tpe.top_character_id,
tpe.top_votes,
elig.posts_to_fill
FROM eligible elig
JOIN falukant_type.political_office_type pot ON pot.id = elig.office_type_id
LEFT JOIN falukant_data.region dr ON dr.id = elig.region_id
LEFT JOIN top_per_election tpe ON tpe.election_id = elig.election_id
LEFT JOIN ranked rk ON rk.candidate_id = elig.candidate_id
ORDER BY elig.election_id, elig.user_id;
"#;
pub const QUERY_TRIM_EXCESS_OFFICES_GLOBAL: &str = r#"
WITH seats AS (
SELECT