import { Pool } from 'pg'; export interface DashboardMetrics { [key: string]: unknown; } export interface VotingAnomaly { first_name: string; last_name: string; party: string; rebellion_rate: number; } /** * THE CIVIC SERVICE (Strand 1 Connector) * Formål: Henter politisk intelligens uden at bruge legacy Java-kode. */ class CivicService { private static instance: CivicService; private pool: Pool; private constructor() { this.pool = new Pool({ user: process.env.CIVIC_USER || 'civic_reader', host: process.env.CIVIC_HOST || 'localhost', // Brug service-navn 'civic-vault' internt i Docker database: 'civic_vault', password: process.env.CIVIC_PWD || 'secure_civic_access', port: 5433, // Porten vi mappede i Docker }); console.log('🏛️ [CivicService] Neural Link established to Civic Node (Strand 1).'); } public static getInstance(): CivicService { if (!CivicService.instance) { CivicService.instance = new CivicService(); } return CivicService.instance; } /** * Henter "The Big Picture" dashboard data. * Baseret på 'view_riksdagen_intelligence_dashboard' fra valideringsrapporten. */ public async getDashboardMetrics(): Promise { try { const query = `SELECT * FROM view_riksdagen_intelligence_dashboard LIMIT 1;`; const result = await this.pool.query(query); return result.rows[0] || null; } catch { console.error('⚠️ [CivicService] Could not fetch dashboard. Is the Vault active?'); return null; } } /** * Finder politiske rebeller (Anomalies). * Baseret på 'view_riksdagen_voting_anomaly_detection'. */ public async getAnomalies(limit: number = 5): Promise { const query = ` SELECT first_name, last_name, party, rebellion_rate FROM view_riksdagen_voting_anomaly_detection WHERE rebellion_rate > 0.05 ORDER BY rebellion_rate DESC LIMIT $1; `; return (await this.pool.query(query, [limit])).rows; } } export const civicService = CivicService.getInstance();