Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 20, 2025

πŸ“Š Fix Remaining Empty Intelligence Views (Crisis, Risk, Proposals) βœ…

Issue: #7885 - 4 intelligence views returning 0 rows

βœ… All Tasks Completed

  • Explore repository structure and locate view definitions
  • Review TROUBLESHOOTING_EMPTY_VIEWS.md for existing patterns
  • Examine sample data to understand available data
  • Analyze view definitions in full_schema.sql
  • Diagnose root causes for each empty view
  • Create Liquibase changelog fixes (db-changelog-1.33.xml)
  • Update TROUBLESHOOTING_EMPTY_VIEWS.md with findings
  • Build and test the changes
  • Run code review and address all feedback
  • Run security scan
  • Update full_schema.sql following schema maintenance procedures
  • Validate all changelog entries are applied and tracked

🎯 Root Causes & Fixes

View Root Cause Fix Applied Expected Rows
view_riksdagen_member_proposals Case-sensitive filter ('MOT' vs 'mot') UPPER(document_type) = 'MOT' ~90,534
view_riksdagen_committee_parliament_member_proposal Same as above UPPER(document_type) = 'MOT' Subset of motions
view_riksdagen_crisis_resilience_indicators Case-sensitive votes ('Ja' vs 'JA') UPPER(vote) for all comparisons Variable
view_risk_score_evolution Status filter too restrictive IN ('active', 'Active', 'ACTIVE') Variable

πŸ“¦ Changes Made

1. Created db-changelog-1.33.xml (22KB, 5 changesets)

  • Changeset 001: Fix view_riksdagen_member_proposals
  • Changeset 002: Fix view_riksdagen_committee_parliament_member_proposal
  • Changeset 003: Fix view_riksdagen_crisis_resilience_indicators
    • Updated: Restored minimum vote thresholds (10 crisis votes OR 20 normal votes)
  • Changeset 004: Fix view_risk_score_evolution
    • Updated: Clarified comment to say "case-insensitive" instead of "broader"
  • Changeset 005: Documentation marker

2. Updated db-changelog.xml

  • Added include for db-changelog-1.33.xml (line 41)

3. Updated TROUBLESHOOTING_EMPTY_VIEWS.md (+289 lines)

  • Added new section: "Intelligence Views: Crisis, Risk, and Proposal Analysis"
  • Updated: Added ::TIMESTAMP WITH TIME ZONE casts to diagnostic queries
  • Documented all 4 views with common issues and validation queries
  • Added comprehensive diagnostic script
  • Updated changelog to v1.1

4. Updated full_schema.sql (following README-SCHEMA-MAINTENANCE.md)

  • Applied all 4 view changes to cia_dev database
  • Added 5 changelog entries to databasechangelog table
  • Regenerated full_schema.sql with pg_dump (schema + changelog data)
  • Verified all views use case-insensitive filters (UPPER())
  • File size: 583KB, 12,887 lines

πŸ“ PR Review Feedback Addressed

All comments from the code review have been addressed:

  1. βœ… Vote threshold restored (Comment 2547959874)

    • Restored minimum vote requirement: COALESCE(cv.crisis_votes, 0) >= 10 OR COALESCE(nv.normal_votes, 0) >= 20
    • Prevents inclusion of politicians with insufficient data for accurate resilience metrics
  2. βœ… Timestamp casts added (Comment 2547959889)

    • Added ::TIMESTAMP WITH TIME ZONE to diagnostic query in TROUBLESHOOTING_EMPTY_VIEWS.md
    • Matches actual view implementation
  3. βœ… Comment clarified (Comment 2547959899)

    • Changed "broader status filter" to "case-insensitive status filter for 'active' status"
    • More accurately describes the actual change

πŸ“ Schema Maintenance Process

Followed the procedures in service.data.impl/README-SCHEMA-MAINTENANCE.md:

  1. βœ… Applied view changes directly to cia_dev database
  2. βœ… Inserted changelog entries into databasechangelog table
  3. βœ… Regenerated full_schema.sql using pg_dump:
    pg_dump --schema-only + pg_dump --data-only (databasechangelog tables)
  4. βœ… Verified changelog entries present in full_schema.sql (5 entries)
  5. βœ… Verified view definitions use UPPER() for case-insensitive matching

Changelog Entries Added:

  • fix-member-proposals-1.33-001
  • fix-committee-member-proposals-1.33-002
  • fix-crisis-resilience-indicators-1.33-003
  • fix-risk-score-evolution-1.33-004
  • document-fixes-1.33-005

βœ… Quality Assurance

Build Verification:

βœ… mvn clean compile -DskipTests
   BUILD SUCCESS - All modules compiled
   Changelog files in target/classes confirmed

Code Review:

βœ… All 3 review comments addressed:
   - Minimum vote threshold restored
   - Timestamp casts added to diagnostic query
   - Comment wording corrected

Security Scan:

βœ… CodeQL: No issues (SQL/XML files don't require code analysis)

Schema Validation:

βœ… Views created in database
βœ… Changelog entries in databasechangelog table
βœ… full_schema.sql updated (583KB, 12,887 lines)
βœ… All 5 changelog entries present in full_schema.sql
βœ… View definitions use UPPER() for case-insensitive matching

πŸš€ Ready for Merge

All acceptance criteria met, code review feedback addressed, schema maintenance procedures followed, and quality checks passed.

Original prompt

This section details on the original issue you should resolve

<issue_title>πŸ“Š Fix Remaining Empty Intelligence Views (Crisis, Risk, Proposals)</issue_title>
<issue_description>## 🎯 Objective
Investigate and fix 4 additional empty intelligence views related to crisis resilience, risk evolution, and parliamentary proposals, completing the database view population effort.

Related PR: #7880 (sample-data-start)
Related Documentation: TROUBLESHOOTING_EMPTY_VIEWS.md

πŸ“‹ Background

Four additional intelligence views across various domains return 0 rows, preventing comprehensive intelligence analysis. These views represent different analytical capabilities: crisis management, risk tracking, and parliamentary proposal analysis.

Empty Views Identified (from ERRORS.txt):

  1. view_riksdagen_crisis_resilience_indicators - Crisis resilience metrics
  2. view_risk_score_evolution - Risk score trend tracking over time
  3. view_riksdagen_committee_parliament_member_proposal - Committee member proposals
  4. view_riksdagen_member_proposals - All member proposals (non-government)

πŸ“Š Current State (Measured Metrics)

From sample data analysis:

  • Views returning 0 rows: 4 views
  • Related views with data:
    • view_riksdagen_committee - 28 rows (committees exist) βœ“
    • view_riksdagen_committee_role_member - 18,991 rows (committee memberships exist) βœ“
    • document_data - 105,030 rows (documents exist) βœ“
    • document_proposal_data - 94,192 rows (proposals exist) βœ“

Intelligence Impact:

  • Crisis resilience analysis: Not available
  • Historical risk tracking: Not available
  • Parliamentary proposal analysis: Not available

βœ… Acceptance Criteria

  • Identify root cause for each empty view
  • Create Liquibase changelog fixes (db-changelog-1.32.xml)
  • Verify views return meaningful data
  • Test with sample queries
  • Update TROUBLESHOOTING_EMPTY_VIEWS.md with findings
  • Document data requirements and assumptions

πŸ› οΈ Implementation Guidance

Files to Investigate:

  • service.data.impl/src/main/resources/full_schema.sql - View definitions
  • Liquibase changelogs v1.30-v1.31 (crisis/risk views)

Investigation Steps:

1. view_riksdagen_crisis_resilience_indicators

Purpose: Track resilience metrics during crisis periods

Investigation:

-- Check view definition
SELECT pg_get_viewdef('view_riksdagen_crisis_resilience_indicators'::regclass, true);

-- Check if view requires manual crisis event tagging
SELECT 
    COUNT(*) AS total_events,
    COUNT(*) FILTER (WHERE event_type = 'CRISIS') AS crisis_events
FROM application_action_event;

-- Hypothesis: May need crisis period definitions

Likely Fix: Define crisis periods or use significant event thresholds

<changeSet id="1.32-fix-crisis-resilience-indicators" author="intelligence-analyst">
    <dropView viewName="view_riksdagen_crisis_resilience_indicators" ifExists="true"/>
    <createView viewName="view_riksdagen_crisis_resilience_indicators">
        <![CDATA[
        -- Define crisis periods based on high legislative activity
        WITH crisis_periods AS (
            SELECT DISTINCT
                DATE_TRUNC('month', vote_date) AS crisis_month
            FROM view_riksdagen_vote_data_ballot_summary_daily
            GROUP BY DATE_TRUNC('month', vote_date)
            HAVING COUNT(DISTINCT ballot_id) > (
                SELECT AVG(ballot_count) * 1.5
                FROM (
                    SELECT 
                        DATE_TRUNC('month', vote_date) AS month,
                        COUNT(DISTINCT ballot_id) AS ballot_count
                    FROM view_riksdagen_vote_data_ballot_summary_daily
                    WHERE vote_date >= CURRENT_DATE - INTERVAL '36 months'
                    GROUP BY DATE_TRUNC('month', vote_date)
                ) monthly_activity
            )
        )
        SELECT 
            cp.crisis_month,
            COUNT(DISTINCT vd.ballot_id) AS ballot_count,
            AVG(vd.participation_percent) AS avg_participation,
            STDDEV(vd.participation_percent) AS participation_variance,
            'HIGH_ACTIVITY_PERIOD' AS period_type
        FROM crisis_periods cp
        JOIN view_riksdagen_vote_data_ballot_summary_daily vd
            ON DATE_TRUNC('month', vd.vote_date) = cp.crisis_month
        GROUP BY cp.crisis_month
        ]]>
    </createView>
</changeSet>

2. view_risk_score_evolution

Purpose: Track risk scores over time

Investigation:

-- Check if risk scores exist with timestamps
SELECT 
    resource_type,
    resource_id,
    detected_date,
    risk_score
FROM rule_violation
WHERE resource_type IN ('POLITICIAN', 'PARTY', 'COMMITTEE')
  AND detected_date IS NOT NULL
LIMIT 10;

-- If empty: risk scores may not have time dimension

Likely Fix: Create time-series view from behavioral trends

<changeSet id="1.32-fix-risk-score-evolution" author="intel...

</details>


> **Custom agent used: intelligence-operative**
> Expert in political science, intelligence analysis, OSINT, behavioral analysis, and Swedish politics with focus on exposing high risk national entities

- Fixes Hack23/cia#7885

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for you](https://github.com/Hack23/cia/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) β€” coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix remaining empty intelligence views for analysis Fix 4 empty intelligence views with case-insensitive filters Nov 20, 2025
Copilot AI requested a review from pethers November 20, 2025 22:46
Copilot finished work on behalf of pethers November 20, 2025 22:46
@github-actions
Copy link

github-actions bot commented Nov 20, 2025

Dependency Review

βœ… No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@pethers pethers requested a review from Copilot November 20, 2025 22:49
Copilot finished reviewing on behalf of pethers November 20, 2025 22:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request fixes 4 empty intelligence views that were returning zero rows due to case-sensitive string filters that didn't match the actual data values in the database. The root causes were identified through sample data analysis:

  1. Motion proposal views filtered by document_type = 'MOT' but data contains 'mot' (lowercase)
  2. Crisis resilience indicators filtered by vote = 'Ja'/'Nej' but data contains 'JA'/'NEJ' (uppercase)
  3. Risk score evolution filtered by exact case status = 'active' which might miss case variations

The fixes apply case-insensitive filtering using UPPER() functions and include comprehensive troubleshooting documentation.

Key Changes

  • Database views: Updated 4 Liquibase changesets to use case-insensitive string comparisons
  • Type safety improvements: Added explicit ::TIMESTAMP WITH TIME ZONE casts for vote_date (which is stored as DATE type)
  • Documentation: Added detailed troubleshooting section with diagnostic queries and expected row counts

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
service.data.impl/src/main/resources/db-changelog.xml Added include for db-changelog-1.33.xml to master changelog
service.data.impl/src/main/resources/db-changelog-1.33.xml Created new changelog with 5 changesets fixing 4 views and documenting changes
TROUBLESHOOTING_EMPTY_VIEWS.md Added comprehensive troubleshooting section for intelligence views with diagnostic queries

LEFT JOIN normal_voting nv ON nv.person_id = pd.id
LEFT JOIN party_discipline_crisis pdc ON pdc.person_id = pd.id
WHERE pd.status = 'active'
AND (cv.crisis_votes IS NOT NULL OR nv.normal_votes IS NOT NULL);
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WHERE clause has been changed from requiring minimum vote counts (COALESCE(cv.crisis_votes, 0) >= 10 OR COALESCE(nv.normal_votes, 0) >= 20) to simply checking for NULL values (cv.crisis_votes IS NOT NULL OR nv.normal_votes IS NOT NULL). This means the view will now include politicians with very minimal voting data (e.g., a single crisis vote or normal vote), which could skew resilience metrics and classifications.

Consider whether this threshold should be retained or at least documented as a deliberate relaxation of data quality requirements. If the goal is to return any data, a lower threshold (e.g., >= 5 votes) might be more appropriate than no threshold at all.

Suggested change
AND (cv.crisis_votes IS NOT NULL OR nv.normal_votes IS NOT NULL);
AND (COALESCE(cv.crisis_votes, 0) >= 10 OR COALESCE(nv.normal_votes, 0) >= 20);

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored minimum vote thresholds in commit 0810e48. The view now requires COALESCE(cv.crisis_votes, 0) >= 10 OR COALESCE(nv.normal_votes, 0) >= 20 to ensure sufficient data for accurate resilience metrics.

Comment on lines 1051 to 1055
DATE_TRUNC('month', vote_date) AS month,
COUNT(DISTINCT embedded_id_ballot_id) AS ballot_count
FROM vote_data
WHERE vote_date >= CURRENT_DATE - INTERVAL '2 years'
GROUP BY DATE_TRUNC('month', vote_date)
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diagnostic query for checking monthly ballot distribution should cast vote_date to TIMESTAMP WITH TIME ZONE to match the actual view implementation. The current query uses DATE_TRUNC('month', vote_date) but the view uses DATE_TRUNC('month', vote_date::TIMESTAMP WITH TIME ZONE).

Change line 1051 to:

DATE_TRUNC('month', vote_date::TIMESTAMP WITH TIME ZONE) AS month,

And line 1055 to:

GROUP BY DATE_TRUNC('month', vote_date::TIMESTAMP WITH TIME ZONE)
Suggested change
DATE_TRUNC('month', vote_date) AS month,
COUNT(DISTINCT embedded_id_ballot_id) AS ballot_count
FROM vote_data
WHERE vote_date >= CURRENT_DATE - INTERVAL '2 years'
GROUP BY DATE_TRUNC('month', vote_date)
DATE_TRUNC('month', vote_date::TIMESTAMP WITH TIME ZONE) AS month,
COUNT(DISTINCT embedded_id_ballot_id) AS ballot_count
FROM vote_data
WHERE vote_date >= CURRENT_DATE - INTERVAL '2 years'
GROUP BY DATE_TRUNC('month', vote_date::TIMESTAMP WITH TIME ZONE)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added ::TIMESTAMP WITH TIME ZONE casts to the diagnostic query in commit 0810e48. The query now matches the actual view implementation.

available data even if not perfectly up-to-date.

Changes:
- Use broader status filter to include recently inactive politicians
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "Use broader status filter" but the actual change is to make the status filter case-insensitive, not broader. The filter still only includes "active" status (in any case), not additional statuses like "inactive" or "former". Consider updating the comment to say "Use case-insensitive status filter" for accuracy.

Suggested change
- Use broader status filter to include recently inactive politicians
- Use case-insensitive status filter for "active" status

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated comment to "Use case-insensitive status filter for 'active' status" in commit 0810e48, which more accurately describes the change.

@pethers
Copy link
Member

pethers commented Nov 20, 2025

@copilot apply changes based on the comments in this thread

Copilot AI requested a review from pethers November 20, 2025 23:10
Copilot finished work on behalf of pethers November 20, 2025 23:10
@pethers
Copy link
Member

pethers commented Nov 20, 2025

@copilot Need to follow https://github.com/Hack23/cia/blob/master/service.data.impl/README-SCHEMA-MAINTENANCE.md and update full-schema and validate all changelogs hace been applied correctly

Copy link
Contributor Author

Copilot AI commented Nov 20, 2025

@copilot Need to follow https://github.com/Hack23/cia/blob/master/service.data.impl/README-SCHEMA-MAINTENANCE.md and update full-schema and validate all changelogs hace been applied correctly

Followed README-SCHEMA-MAINTENANCE.md procedures in commit bef9504:

  1. Applied all 4 view changes to cia_dev database
  2. Inserted 5 changelog entries into databasechangelog table
  3. Regenerated full_schema.sql using pg_dump (schema + changelog data)
  4. Verified all changelog entries present (fix-member-proposals-1.33-001 through document-fixes-1.33-005)
  5. Confirmed view definitions use UPPER() for case-insensitive filtering

Updated full_schema.sql: 583KB, 12,887 lines with all db-changelog-1.33 changes applied.

@sonarqubecloud
Copy link

Copilot finished work on behalf of pethers November 20, 2025 23:26
@pethers pethers requested a review from Copilot November 20, 2025 23:36
Copilot finished reviewing on behalf of pethers November 20, 2025 23:38
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@pethers pethers marked this pull request as ready for review November 20, 2025 23:40
@pethers pethers merged commit d54f626 into master Nov 20, 2025
16 checks passed
@pethers pethers deleted the copilot/fix-empty-intelligence-views branch November 20, 2025 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants