-
Notifications
You must be signed in to change notification settings - Fork 56
Expand file tree
/
Copy pathdb-changelog-1.51.xml
More file actions
588 lines (503 loc) · 28.1 KB
/
db-changelog-1.51.xml
File metadata and controls
588 lines (503 loc) · 28.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<!--
Historical Election Cycle Trend Views - Database Changelog v1.51 (REVISED)
Author: Intelligence Operative & Political Analyst
Date: 2026-01-13 (Revised: 2026-01-13)
GitHub Issue: #8205 - Historical Election Cycle Trend Views: Swedish Parliament Context
Related PR: #8204 - Framework-validation sample data
REVISION NOTES:
This is a comprehensive revision that properly integrates ALL advanced views
for true META/META-level analysis across all 6 analytical frameworks.
Key Improvements:
1. Temporal Analysis: Added view_decision_temporal_trends, view_committee_productivity
2. Comparative Analysis: Added view_party_performance_metrics, view_committee_productivity_matrix
3. Pattern Recognition: Added view_riksdagen_voting_anomaly_detection, view_politician_risk_summary
4. Predictive Intelligence: Added view_ministry_risk_evolution, view_party_effectiveness_trends
5. Network Analysis: Added view_riksdagen_politician_influence_metrics
6. Decision Intelligence: Added view_decision_temporal_trends, view_ministry_decision_impact
Purpose:
Creates 6 comprehensive META/META-level database views for Swedish Parliament election
cycle analysis, covering ALL 6 analytical frameworks with Swedish parliamentary context.
Swedish Parliamentary Context:
- Elections every 4 years (since 1994) on second Sunday in September
- Parliamentary periods start second Tuesday in September
- Autumn semester: mid-September to ~January 25
- Spring semester: ~January 26 to next September
- Final spring semester before election is high-significance (campaign impact, policy shifts)
Key Design Principles:
1. META/META Level: Only aggregate existing advanced views, never query base tables
2. Swedish Context: 4-year cycles, autumn/spring semesters, pre-election markers
3. Framework Coverage: All 6 analytical frameworks explicitly addressed
4. Explicit Mapping: Every column mapped to source view with SQL comments
5. Temporal Dimensions: election_cycle_id, year, semester, pre-election significance
Views Created:
1. view_election_cycle_temporal_trends (Temporal Analysis framework - 35 supporting views)
2. view_election_cycle_comparative_analysis (Comparative Analysis - 26 supporting views)
3. view_election_cycle_anomaly_pattern (Pattern Recognition - 23 supporting views)
4. view_election_cycle_predictive_intelligence (Predictive Intelligence - 14 supporting views)
5. view_election_cycle_network_analysis (Network Analysis - 11 supporting views)
6. view_election_cycle_decision_intelligence (Decision Intelligence - 5 supporting views)
Intelligence Applications:
- Election-aware political scorecards
- Coalition stability analysis across election cycles
- Pre-election behavioral pattern detection
- Cross-cycle comparative analysis
- Predictive election forecasting
- Legislative effectiveness by cycle phase
-->
<changeSet id="1.51-intro" author="intelligence-operative">
<comment>
Database Changelog v1.51 - Historical Election Cycle Trend Views (REVISED)
Creates 6 META/META-level views aggregating existing advanced analytics
with Swedish parliamentary election cycle temporal dimensions.
REVISION: Now properly integrates ALL relevant advanced views for each framework
to provide comprehensive, multi-source intelligence aggregation.
Enables institutional-grade, election-season-aware intelligence across
all 6 analytical frameworks (Temporal, Comparative, Pattern Recognition,
Predictive, Network, Decision Intelligence).
</comment>
<sql>
SELECT
'v1.51-revised' AS version,
'Election cycle trend views - COMPREHENSIVE META/META level with all advanced views' AS description,
'Covers 6 frameworks: Temporal, Comparative, Pattern, Predictive, Network, Decision' AS scope,
CURRENT_TIMESTAMP AS applied_at;
</sql>
</changeSet>
<!-- ========================================================================= -->
<!-- 1. TEMPORAL ANALYSIS (ENHANCED): view_election_cycle_temporal_trends -->
<!-- ========================================================================= -->
<changeSet author="intelligence-operative" id="1.51-election-cycle-temporal-001" failOnError="true">
<comment>
REVISED: Enhanced with view_decision_temporal_trends and view_committee_productivity
Framework: Temporal Analysis (35 supporting views, 20+ risk rules)
Source Views (COMPREHENSIVE META level):
- view_politician_behavioral_trends: Behavioral metrics, moving averages
- view_riksdagen_vote_data_ballot_politician_summary_monthly: Voting patterns
- view_decision_temporal_trends: Decision outcomes, approval rates (NEW)
- view_committee_productivity: Committee activity metrics (NEW)
</comment>
<createView viewName="view_election_cycle_temporal_trends">
<![CDATA[
WITH election_cycle_calendar AS (
SELECT
year_series AS calendar_year,
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4))::INTEGER AS cycle_start_year,
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4) + 4)::INTEGER AS cycle_end_year
FROM generate_series(1994, EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 4, 1) AS year_series
),
election_cycle_periods AS (
SELECT
calendar_year,
cycle_start_year,
cycle_end_year,
(cycle_start_year || '-' || cycle_end_year) AS election_cycle_id,
(calendar_year - cycle_start_year + 1) AS cycle_year,
MAKE_DATE(calendar_year, 9, 1) AS autumn_start,
MAKE_DATE(calendar_year + 1, 1, 25) AS autumn_end,
MAKE_DATE(calendar_year, 1, 26) AS spring_start,
MAKE_DATE(calendar_year, 8, 31) AS spring_end,
CASE WHEN (calendar_year - cycle_start_year + 1) = 4 THEN TRUE ELSE FALSE END AS is_election_year
FROM election_cycle_calendar
),
temporal_data_autumn AS (
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
'autumn' AS semester,
FALSE AS is_pre_election_semester,
EXTRACT(YEAR FROM AGE(MAKE_DATE(ecp.cycle_end_year, 9, 15), ecp.autumn_start))::INTEGER * 12 +
EXTRACT(MONTH FROM AGE(MAKE_DATE(ecp.cycle_end_year, 9, 15), ecp.autumn_start))::INTEGER AS months_until_election,
-- From view_politician_behavioral_trends
COUNT(DISTINCT pbt.person_id) AS active_politicians,
ROUND(AVG(100 - pbt.avg_absence_rate), 2) AS avg_attendance_rate,
SUM(pbt.total_ballots) AS total_ballots,
SUM(pbt.total_votes) AS total_votes,
ROUND(AVG(pbt.avg_win_rate), 2) AS avg_win_rate,
ROUND(AVG(pbt.avg_rebel_rate), 2) AS avg_rebel_rate,
SUM(pbt.violation_count) AS violation_count,
ROUND(AVG(pbt.ma_3month_absence), 2) AS avg_ma_absence,
-- From view_decision_temporal_trends (NEW)
ROUND(AVG(dtt.daily_approval_rate), 2) AS avg_approval_rate,
SUM(dtt.daily_decisions) AS total_decisions,
-- From view_committee_productivity (NEW)
ROUND(AVG(cp.productivity_score), 2) AS avg_committee_productivity
FROM election_cycle_periods ecp
LEFT JOIN view_politician_behavioral_trends pbt
ON pbt.period_start >= ecp.autumn_start AND pbt.period_start <= ecp.autumn_end
LEFT JOIN view_decision_temporal_trends dtt
ON dtt.decision_day >= ecp.autumn_start AND dtt.decision_day <= ecp.autumn_end
LEFT JOIN view_committee_productivity cp
ON 1=1 -- Current snapshot, no temporal filtering available
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year, ecp.autumn_start, ecp.cycle_end_year
),
temporal_data_spring AS (
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
'spring' AS semester,
CASE WHEN ecp.is_election_year THEN TRUE ELSE FALSE END AS is_pre_election_semester,
EXTRACT(YEAR FROM AGE(MAKE_DATE(ecp.cycle_end_year, 9, 15), ecp.spring_start))::INTEGER * 12 +
EXTRACT(MONTH FROM AGE(MAKE_DATE(ecp.cycle_end_year, 9, 15), ecp.spring_start))::INTEGER AS months_until_election,
COUNT(DISTINCT pbt.person_id) AS active_politicians,
ROUND(AVG(100 - pbt.avg_absence_rate), 2) AS avg_attendance_rate,
SUM(pbt.total_ballots) AS total_ballots,
SUM(pbt.total_votes) AS total_votes,
ROUND(AVG(pbt.avg_win_rate), 2) AS avg_win_rate,
ROUND(AVG(pbt.avg_rebel_rate), 2) AS avg_rebel_rate,
SUM(pbt.violation_count) AS violation_count,
ROUND(AVG(pbt.ma_3month_absence), 2) AS avg_ma_absence,
ROUND(AVG(dtt.daily_approval_rate), 2) AS avg_approval_rate,
SUM(dtt.daily_decisions) AS total_decisions,
ROUND(AVG(cp.productivity_score), 2) AS avg_committee_productivity
FROM election_cycle_periods ecp
LEFT JOIN view_politician_behavioral_trends pbt
ON pbt.period_start >= ecp.spring_start AND pbt.period_start <= ecp.spring_end
LEFT JOIN view_decision_temporal_trends dtt
ON dtt.decision_day >= ecp.spring_start AND dtt.decision_day <= ecp.spring_end
LEFT JOIN view_committee_productivity cp
ON 1=1 -- Current snapshot, no temporal filtering available
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year, ecp.spring_start, ecp.cycle_end_year, ecp.is_election_year
)
SELECT * FROM temporal_data_autumn
UNION ALL
SELECT * FROM temporal_data_spring
ORDER BY election_cycle_id, cycle_year, semester;
]]>
</createView>
<rollback>
<dropView viewName="view_election_cycle_temporal_trends"/>
</rollback>
</changeSet>
<!-- ========================================================================= -->
<!-- 2. COMPARATIVE ANALYSIS (ENHANCED): view_election_cycle_comparative_analysis -->
<!-- ========================================================================= -->
<changeSet author="intelligence-operative" id="1.51-election-cycle-comparative-002" failOnError="true">
<comment>
REVISED: Enhanced with view_party_performance_metrics and view_committee_productivity_matrix
Framework: Comparative Analysis (26 supporting views, 15+ risk rules)
Source Views (COMPREHENSIVE):
- view_riksdagen_vote_data_ballot_party_summary_monthly: Party voting patterns
- view_party_performance_metrics: Performance scores, discipline, effectiveness (NEW)
- view_committee_productivity_matrix: Multi-committee comparisons (NEW)
</comment>
<createView viewName="view_election_cycle_comparative_analysis">
<![CDATA[
WITH election_cycle_periods AS (
SELECT
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) || '-' || (1994 + (FLOOR((year_series - 1994) / 4.0) * 4) + 4) AS election_cycle_id,
(year_series - (1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) + 1) AS cycle_year,
year_series AS calendar_year
FROM generate_series(1994, EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 4, 1) AS year_series
)
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
'annual' AS semester, -- Simplified: aggregate by year since source views are current snapshots
ppm.party,
-- From view_party_performance_metrics (NEW - provides comprehensive party analytics)
MAX(ppm.performance_score) AS performance_score,
MAX(ppm.active_members) AS active_members,
MAX(ppm.total_violations) AS party_violations,
ROUND(AVG(ppm.avg_win_rate), 2) AS party_win_rate,
ROUND(AVG(ppm.avg_participation_rate), 2) AS party_participation_rate,
MAX(ppm.documents_last_year) AS documents_last_year,
ROUND(AVG(ppm.avg_rebel_rate), 2) AS party_avg_rebel_rate,
-- From view_committee_productivity_matrix (NEW - multi-committee dimension)
COUNT(DISTINCT cpm.committee_code) AS committees_active
FROM election_cycle_periods ecp
CROSS JOIN view_party_performance_metrics ppm
LEFT JOIN view_committee_productivity_matrix cpm
ON EXTRACT(YEAR FROM cpm.period_start) = ecp.calendar_year
WHERE ppm.party IS NOT NULL
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year, ppm.party
ORDER BY election_cycle_id, cycle_year, semester, party;
]]>
</createView>
<rollback><dropView viewName="view_election_cycle_comparative_analysis"/></rollback>
</changeSet>
<!-- ========================================================================= -->
<!-- 3. PATTERN RECOGNITION (ENHANCED): view_election_cycle_anomaly_pattern -->
<!-- ========================================================================= -->
<changeSet author="intelligence-operative" id="1.51-election-cycle-pattern-003" failOnError="true">
<comment>
REVISED: Enhanced with view_riksdagen_voting_anomaly_detection and view_politician_risk_summary
Framework: Pattern Recognition (23 supporting views, 12/13 risk rules)
Source Views (COMPREHENSIVE):
- view_risk_score_evolution: Risk trajectories and escalations
- view_riksdagen_voting_anomaly_detection: Defection risk, discipline issues (NEW)
- view_politician_risk_summary: Aggregated risk profiles (NEW)
</comment>
<createView viewName="view_election_cycle_anomaly_pattern">
<![CDATA[
WITH election_cycle_periods AS (
SELECT
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) || '-' || (1994 + (FLOOR((year_series - 1994) / 4.0) * 4) + 4) AS election_cycle_id,
(year_series - (1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) + 1) AS cycle_year,
year_series AS calendar_year
FROM generate_series(1994, EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 4, 1) AS year_series
)
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
CASE WHEN EXTRACT(MONTH FROM rse.assessment_period) >= 9 OR EXTRACT(MONTH FROM rse.assessment_period) <= 1 THEN 'autumn' ELSE 'spring' END AS semester,
-- Anomaly classification
'MULTI_SOURCE_PATTERN' AS anomaly_type,
-- From view_risk_score_evolution
COUNT(DISTINCT rse.person_id) FILTER (WHERE rse.risk_severity IN ('HIGH', 'CRITICAL')) AS politician_count_with_risk,
ROUND(AVG(rse.risk_score), 2) AS avg_risk_score,
COUNT(*) FILTER (WHERE rse.severity_transition LIKE 'ESCALATION%') AS risk_escalations,
-- From view_riksdagen_voting_anomaly_detection (NEW - uses actual columns: total_rebellions, anomaly_classification)
COUNT(DISTINCT vad.person_id) FILTER (WHERE vad.anomaly_classification IN ('FREQUENT_STRONG_REBEL', 'CONSISTENT_REBEL')) AS high_anomaly_count,
ROUND(AVG(vad.total_rebellions), 2) AS avg_total_rebellions,
COUNT(DISTINCT vad.person_id) FILTER (WHERE vad.strong_consensus_rebellions >= 5) AS strong_consensus_rebels,
-- From view_politician_risk_summary (NEW - aggregated risk profiles)
ROUND(AVG(prs.risk_score), 2) AS avg_risk_score_prs,
COUNT(DISTINCT prs.person_id) FILTER (WHERE prs.risk_level IN ('HIGH', 'CRITICAL')) AS high_risk_politicians
FROM election_cycle_periods ecp
LEFT JOIN view_risk_score_evolution rse
ON EXTRACT(YEAR FROM rse.assessment_period) = ecp.calendar_year
LEFT JOIN view_riksdagen_voting_anomaly_detection vad
ON 1=1 -- Current snapshot (3-year rolling window), no temporal filtering available
LEFT JOIN view_politician_risk_summary prs
ON 1=1 -- Current snapshot, not time-filtered
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year,
CASE WHEN EXTRACT(MONTH FROM rse.assessment_period) >= 9 OR EXTRACT(MONTH FROM rse.assessment_period) <= 1 THEN 'autumn' ELSE 'spring' END
ORDER BY election_cycle_id, cycle_year, semester;
]]>
</createView>
<rollback><dropView viewName="view_election_cycle_anomaly_pattern"/></rollback>
</changeSet>
<!-- ========================================================================= -->
<!-- 4. PREDICTIVE INTELLIGENCE (ENHANCED): view_election_cycle_predictive_intelligence -->
<!-- ========================================================================= -->
<changeSet author="intelligence-operative" id="1.51-election-cycle-predictive-004" failOnError="true">
<comment>
REVISED: Enhanced with view_ministry_risk_evolution and view_party_effectiveness_trends
Framework: Predictive Intelligence (14 supporting views, 8/8 risk rules)
Source Views (COMPREHENSIVE):
- view_risk_score_evolution: Risk forecasting and trajectories
- view_ministry_risk_evolution: Ministry-level risk trends (NEW)
- view_party_effectiveness_trends: Party performance trajectories (NEW)
</comment>
<createView viewName="view_election_cycle_predictive_intelligence">
<![CDATA[
WITH election_cycle_periods AS (
SELECT
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) || '-' || (1994 + (FLOOR((year_series - 1994) / 4.0) * 4) + 4) AS election_cycle_id,
(year_series - (1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) + 1) AS cycle_year,
year_series AS calendar_year
FROM generate_series(1994, EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 4, 1) AS year_series
)
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
CASE WHEN EXTRACT(MONTH FROM rse.assessment_period) >= 9 OR EXTRACT(MONTH FROM rse.assessment_period) <= 1 THEN 'autumn' ELSE 'spring' END AS semester,
-- From view_risk_score_evolution (risk forecasting)
CASE
WHEN AVG(rse.risk_score_change) >= 10 THEN 'RAPID_ESCALATION'
WHEN AVG(rse.risk_score_change) >= 5 THEN 'MODERATE_ESCALATION'
WHEN AVG(rse.risk_score_change) <= -5 THEN 'IMPROVING'
ELSE 'STABLE'
END AS risk_forecast_category,
COUNT(DISTINCT rse.person_id) FILTER (WHERE rse.risk_trend LIKE '%INCREASE%') AS politicians_at_risk,
ROUND(AVG(rse.risk_score_change), 2) AS avg_risk_score_change,
-- From view_ministry_risk_evolution (NEW - government stability forecasting)
COUNT(DISTINCT mre.name) FILTER (WHERE mre.risk_level IN ('HIGH', 'CRITICAL')) AS ministries_at_risk,
ROUND(AVG(mre.rolling_avg_documents), 2) AS avg_ministry_productivity,
-- From view_party_effectiveness_trends (NEW - party performance forecasting)
ROUND(AVG(pet.win_rate_trend), 2) AS avg_party_win_rate_trend,
COUNT(DISTINCT pet.party) FILTER (WHERE pet.absence_trend > 0) AS parties_with_increasing_absence
FROM election_cycle_periods ecp
LEFT JOIN view_risk_score_evolution rse
ON EXTRACT(YEAR FROM rse.assessment_period) = ecp.calendar_year
LEFT JOIN view_ministry_risk_evolution mre
ON EXTRACT(YEAR FROM mre.assessment_period) = ecp.calendar_year
LEFT JOIN view_party_effectiveness_trends pet
ON EXTRACT(YEAR FROM pet.period_start) = ecp.calendar_year
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year,
CASE WHEN EXTRACT(MONTH FROM rse.assessment_period) >= 9 OR EXTRACT(MONTH FROM rse.assessment_period) <= 1 THEN 'autumn' ELSE 'spring' END
ORDER BY election_cycle_id, cycle_year, semester;
]]>
</createView>
<rollback><dropView viewName="view_election_cycle_predictive_intelligence"/></rollback>
</changeSet>
<!-- ========================================================================= -->
<!-- 5. NETWORK ANALYSIS (ENHANCED): view_election_cycle_network_analysis -->
<!-- ========================================================================= -->
<changeSet author="intelligence-operative" id="1.51-election-cycle-network-005" failOnError="true">
<comment>
REVISED: Enhanced with view_riksdagen_politician_influence_metrics
Framework: Network Analysis (11 supporting views, 3/4 risk rules)
Source Views (COMPREHENSIVE):
- view_riksdagen_coalition_alignment_matrix: Coalition structure
- view_riksdagen_politician_influence_metrics: Network centrality, power brokers (NEW)
</comment>
<createView viewName="view_election_cycle_network_analysis">
<![CDATA[
WITH election_cycle_periods AS (
SELECT
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) || '-' || (1994 + (FLOOR((year_series - 1994) / 4.0) * 4) + 4) AS election_cycle_id,
(year_series - (1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) + 1) AS cycle_year,
year_series AS calendar_year
FROM generate_series(2020, EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 4, 1) AS year_series
)
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
'aggregate' AS semester,
-- From view_riksdagen_coalition_alignment_matrix
cam.party1,
cam.party2,
cam.alignment_rate,
CASE
WHEN cam.alignment_rate >= 80 THEN 'STRONG_COALITION'
WHEN cam.alignment_rate >= 60 THEN 'MODERATE_COALITION'
ELSE 'WEAK_COALITION'
END AS coalition_strength,
-- From view_riksdagen_politician_influence_metrics (NEW - network analysis)
COUNT(DISTINCT pim.person_id) FILTER (WHERE pim.influence_classification IN ('HIGH_INFLUENCE', 'VERY_HIGH_INFLUENCE')) AS influential_politicians,
ROUND(AVG(pim.network_median), 2) AS avg_network_centrality,
COUNT(DISTINCT pim.person_id) FILTER (WHERE pim.broker_classification = 'POWER_BROKER') AS power_broker_count
FROM election_cycle_periods ecp
CROSS JOIN view_riksdagen_coalition_alignment_matrix cam
LEFT JOIN view_riksdagen_politician_influence_metrics pim
ON 1=1 -- Current snapshot
WHERE cam.party1 IS NOT NULL AND cam.party2 IS NOT NULL
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year, cam.party1, cam.party2, cam.alignment_rate
ORDER BY election_cycle_id, cycle_year, alignment_rate DESC;
]]>
</createView>
<rollback><dropView viewName="view_election_cycle_network_analysis"/></rollback>
</changeSet>
<!-- ========================================================================= -->
<!-- 6. DECISION INTELLIGENCE (ENHANCED): view_election_cycle_decision_intelligence -->
<!-- ========================================================================= -->
<changeSet author="intelligence-operative" id="1.51-election-cycle-decision-006" failOnError="true">
<comment>
REVISED: Enhanced with view_decision_temporal_trends and view_ministry_decision_impact
Framework: Decision Intelligence (5 supporting views, 5/5 risk rules)
Source Views (COMPREHENSIVE):
- view_riksdagen_party_decision_flow: Party proposal outcomes
- view_decision_temporal_trends: Temporal decision patterns (NEW)
- view_ministry_decision_impact: Government decision effectiveness (NEW)
</comment>
<createView viewName="view_election_cycle_decision_intelligence">
<![CDATA[
WITH election_cycle_periods AS (
SELECT
(1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) || '-' || (1994 + (FLOOR((year_series - 1994) / 4.0) * 4) + 4) AS election_cycle_id,
(year_series - (1994 + (FLOOR((year_series - 1994) / 4.0) * 4)) + 1) AS cycle_year,
year_series AS calendar_year
FROM generate_series(1994, EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER + 4, 1) AS year_series
)
SELECT
ecp.election_cycle_id,
ecp.cycle_year,
ecp.calendar_year,
CASE WHEN pdf.decision_month_num >= 9 OR pdf.decision_month_num <= 1 THEN 'autumn' ELSE 'spring' END AS semester,
pdf.party,
-- From view_riksdagen_party_decision_flow (party-level outcomes)
SUM(pdf.total_proposals) AS total_proposals,
SUM(pdf.approved_proposals) AS approved_proposals,
SUM(pdf.rejected_proposals) AS rejected_proposals,
ROUND(AVG(pdf.approval_rate), 2) AS avg_approval_rate,
-- Decision effectiveness classification
CASE
WHEN AVG(pdf.approval_rate) >= 75 THEN 'HIGHLY_EFFECTIVE'
WHEN AVG(pdf.approval_rate) >= 50 THEN 'MODERATELY_EFFECTIVE'
ELSE 'LOWLY_EFFECTIVE'
END AS decision_effectiveness,
-- From view_decision_temporal_trends (NEW - temporal decision patterns)
ROUND(AVG(dtt.daily_approval_rate), 2) AS temporal_approval_rate,
SUM(dtt.daily_decisions) AS temporal_decision_count,
-- From view_ministry_decision_impact (NEW - government decision effectiveness)
ROUND(AVG(mdi.approval_rate), 2) AS ministry_impact_score,
COUNT(DISTINCT mdi.ministry_code) AS ministries_with_decisions
FROM election_cycle_periods ecp
LEFT JOIN view_riksdagen_party_decision_flow pdf
ON pdf.decision_year = ecp.calendar_year
LEFT JOIN view_decision_temporal_trends dtt
ON EXTRACT(YEAR FROM dtt.decision_day) = ecp.calendar_year
LEFT JOIN view_ministry_decision_impact mdi
ON mdi.decision_year = ecp.calendar_year
WHERE pdf.party IS NOT NULL
GROUP BY ecp.election_cycle_id, ecp.cycle_year, ecp.calendar_year,
CASE WHEN pdf.decision_month_num >= 9 OR pdf.decision_month_num <= 1 THEN 'autumn' ELSE 'spring' END,
pdf.party
HAVING SUM(pdf.total_proposals) > 0
ORDER BY election_cycle_id, cycle_year, semester, party;
]]>
</createView>
<rollback><dropView viewName="view_election_cycle_decision_intelligence"/></rollback>
</changeSet>
<!-- ========================================================================= -->
<!-- VALIDATION: Verify Election Cycle Views Created Successfully -->
<!-- ========================================================================= -->
<changeSet id="1.51-validation" author="intelligence-operative">
<comment>
Validate that all 6 election cycle views were created successfully
with enhanced comprehensive META/META-level integration.
</comment>
<sql splitStatements="false"><![CDATA[
DO $$
DECLARE
v_temporal_exists BOOLEAN;
v_comparative_exists BOOLEAN;
v_pattern_exists BOOLEAN;
v_predictive_exists BOOLEAN;
v_network_exists BOOLEAN;
v_decision_exists BOOLEAN;
BEGIN
SELECT EXISTS(
SELECT 1 FROM information_schema.views
WHERE table_name = 'view_election_cycle_temporal_trends'
) INTO v_temporal_exists;
SELECT EXISTS(
SELECT 1 FROM information_schema.views
WHERE table_name = 'view_election_cycle_comparative_analysis'
) INTO v_comparative_exists;
SELECT EXISTS(
SELECT 1 FROM information_schema.views
WHERE table_name = 'view_election_cycle_anomaly_pattern'
) INTO v_pattern_exists;
SELECT EXISTS(
SELECT 1 FROM information_schema.views
WHERE table_name = 'view_election_cycle_predictive_intelligence'
) INTO v_predictive_exists;
SELECT EXISTS(
SELECT 1 FROM information_schema.views
WHERE table_name = 'view_election_cycle_network_analysis'
) INTO v_network_exists;
SELECT EXISTS(
SELECT 1 FROM information_schema.views
WHERE table_name = 'view_election_cycle_decision_intelligence'
) INTO v_decision_exists;
IF v_temporal_exists AND v_comparative_exists AND v_pattern_exists
AND v_predictive_exists AND v_network_exists AND v_decision_exists THEN
RAISE NOTICE '✓ All 6 ENHANCED election cycle views created successfully';
RAISE NOTICE ' REVISION: Now using comprehensive advanced view integration';
RAISE NOTICE ' - Temporal: Added decision_temporal_trends, committee_productivity';
RAISE NOTICE ' - Comparative: Added party_performance_metrics, committee_productivity_matrix';
RAISE NOTICE ' - Pattern: Added voting_anomaly_detection, politician_risk_summary';
RAISE NOTICE ' - Predictive: Added ministry_risk_evolution, party_effectiveness_trends';
RAISE NOTICE ' - Network: Added politician_influence_metrics';
RAISE NOTICE ' - Decision: Added decision_temporal_trends, ministry_decision_impact';
ELSE
RAISE WARNING 'Some election cycle views failed to create';
END IF;
END $$;
]]></sql>
</changeSet>
</databaseChangeLog>