Files
boc/landvex-admin-backend/app/routers/life_engine.py
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

628 lines
25 KiB
Python

"""
Landvex Intelligence Fusion Engine (LIFE)
Continuous Multi-Source Intelligence Platform
Core Principle: Evidence Before Opinion
- First gather observable signals
- Then weigh independent sources
- Identify patterns and statistical associations
- Only then generate cautious hypotheses about possible causes
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List, Optional, Dict, Any
from datetime import datetime
from enum import Enum
from app.database import get_db
from app.core.security import get_current_user
from app.models import User
router = APIRouter(prefix="/life", tags=["life_engine"])
class EvidenceCategory(str, Enum):
OFFICIAL_REPORTING = "official_reporting"
SATELLITE = "satellite"
QUIXZOOM = "quixzoom"
NEWS = "news"
OPEN_DATA = "open_data"
HISTORICAL = "historical"
ENVIRONMENTAL = "environmental"
INFRASTRUCTURE = "infrastructure"
TEMPORAL = "temporal"
CORROBORATION = "corroboration"
class ConfidenceLevel(str, Enum):
VERY_HIGH = "very_high" # 90-100%
HIGH = "high" # 75-89%
MODERATE = "moderate" # 50-74%
LOW = "low" # 25-49%
VERY_LOW = "very_low" # 0-24%
class EventType(str, Enum):
NATURAL_DISASTER = "natural_disaster"
CONFLICT = "conflict"
INFRASTRUCTURE_FAILURE = "infrastructure_failure"
POLITICAL_INSTABILITY = "political_instability"
DISEASE_OUTBREAK = "disease_outbreak"
CONSTRUCTION_DELAY = "construction_delay"
ENVIRONMENTAL_INCIDENT = "environmental_incident"
# ─── PHILOSOPHY ───────────────────────────────────────────────────────────────
@router.get("/public/philosophy")
async def get_life_philosophy():
"""Evidence Before Opinion - core architecture principle."""
return {
"engine_name": "Landvex Intelligence Fusion Engine (LIFE)",
"version": "1.0.0",
"core_principle": "Evidence Before Opinion",
"principle_description": "The system never starts with a conclusion and looks for support. Instead, every analysis builds from observable signals upward.",
"process": [
{
"step": 1,
"name": "Gather Facts",
"description": "Collect observable signals from all available sources"
},
{
"step": 2,
"name": "Weigh Sources",
"description": "Evaluate independent sources and their reliability"
},
{
"step": 3,
"name": "Identify Patterns",
"description": "Detect statistical associations and correlations"
},
{
"step": 4,
"name": "Generate Hypotheses",
"description": "Form cautious hypotheses about possible causes"
},
],
"commitment": "Every insight answers: What evidence supports this? Which sources contributed? What observations disagree? How confident is the estimate?",
}
# ─── DATA SOURCES ─────────────────────────────────────────────────────────────
@router.get("/public/data-sources")
async def get_data_sources():
"""All continuous data acquisition sources."""
return {
"categories": [
{
"name": "Official Project Information",
"sources": [
"Development agency project portals",
"Government project databases",
"Public procurement portals",
"Budget publications",
"Tender databases",
"Evaluation reports",
"Annual reports",
"Audit reports",
"Parliamentary documents",
],
"update_frequency": "Daily",
"reliability": "High",
},
{
"name": "News Intelligence",
"sources": [
"International news",
"National news",
"Regional news",
"Local newspapers",
"RSS feeds",
"Development news",
"Humanitarian news",
"Infrastructure news",
"Agriculture news",
"Health news",
"Education news",
"Economic news",
"Environmental news",
"Security news",
"Energy news",
"Transportation news",
],
"update_frequency": "Real-time",
"reliability": "Medium",
},
{
"name": "Public Communications",
"sources": [
"Press releases",
"Official websites",
"Public blogs",
"Open social media posts from institutions",
"Project announcements",
"Public progress updates",
"Conference presentations",
"Research publications",
],
"update_frequency": "Daily",
"reliability": "Medium",
},
{
"name": "Geospatial Intelligence",
"sources": [
"Satellite imagery (Sentinel-2, Landsat)",
"Night light intensity",
"Land cover change",
"Road detection",
"Construction detection",
"Flood monitoring",
"Drought monitoring",
"Vegetation analysis",
"River changes",
"Urban expansion",
"Environmental degradation",
"Wildfire detection",
"Infrastructure growth",
],
"update_frequency": "Every 5 days",
"reliability": "Very High",
},
{
"name": "QUIXZOOM Reality Network",
"sources": [
"Field observations",
"Mission results",
"Photographic evidence",
"Video",
"Audio",
"GPS tracks",
"Infrastructure inspections",
"Community observations",
"Temporal comparisons",
],
"update_frequency": "On-demand",
"reliability": "High",
},
{
"name": "Open Data",
"sources": [
"Population data",
"Weather",
"Climate",
"Transportation",
"Electricity",
"Internet coverage",
"Water availability",
"Health indicators",
"Education statistics",
"Economic indicators",
"Commodity prices",
"Agricultural production",
"Migration statistics",
"Conflict datasets",
],
"update_frequency": "Weekly to Monthly",
"reliability": "High",
},
],
}
# ─── EVENT DETECTION ──────────────────────────────────────────────────────────
@router.get("/public/events")
async def list_detected_events(
project_id: Optional[str] = None,
event_type: Optional[EventType] = None,
country: Optional[str] = None,
):
"""Automatically detected meaningful events."""
events = [
{
"id": "evt-001",
"type": "natural_disaster",
"subtype": "flood",
"title": "Severe flooding in Mogadishu region",
"description": "Heavy rainfall caused flooding affecting infrastructure accessibility",
"location": {"country": "Somalia", "region": "Banadir", "lat": 2.0469, "lng": 45.3182},
"date": "2026-06-15",
"affected_projects": ["proj-001"],
"severity": "high",
"confidence": 92,
"sources": ["Satellite", "News", "Open data"],
"detected_at": "2026-06-16T08:00:00Z",
},
{
"id": "evt-002",
"type": "construction_delay",
"subtype": "weather_related",
"title": "Construction delay due to seasonal rainfall",
"description": "Road rehabilitation project delayed due to extended rainy season",
"location": {"country": "Nigeria", "region": "Lagos", "lat": 6.5244, "lng": 3.3792},
"date": "2026-05-20",
"affected_projects": ["proj-045"],
"severity": "medium",
"confidence": 78,
"sources": ["Satellite", "Field observation", "Weather data"],
"detected_at": "2026-05-25T10:00:00Z",
},
{
"id": "evt-003",
"type": "conflict",
"subtype": "regional_insecurity",
"title": "Regional insecurity affecting project operations",
"description": "Increased security incidents in project area affecting staff access",
"location": {"country": "Ethiopia", "region": "Tigray", "lat": 14.1628, "lng": 38.2906},
"date": "2026-04-10",
"affected_projects": ["proj-089"],
"severity": "high",
"confidence": 85,
"sources": ["News", "Security reports", "Field observation"],
"detected_at": "2026-04-12T14:00:00Z",
},
]
if country:
events = [e for e in events if e["location"]["country"].lower() == country.lower()]
if event_type:
events = [e for e in events if e["type"] == event_type.value]
return {
"events": events,
"total": len(events),
"detection_method": "Automated multi-source fusion with human verification",
}
# ─── CONTEXT GRAPH ────────────────────────────────────────────────────────────
@router.get("/public/projects/{project_id}/context")
async def get_project_context(project_id: str):
"""Continuously updated contextual graph for a project."""
return {
"project_id": project_id,
"context": {
"political_environment": {
"stability_score": 65,
"confidence": 78,
"factors": ["Democratic governance", "Regional tensions", "Election upcoming"],
},
"economic_conditions": {
"gdp_growth": 4.2,
"inflation": 8.5,
"currency_stability": "moderate",
"confidence": 82,
},
"climate": {
"current_season": "rainy",
"rainfall_vs_average": 120,
"temperature_vs_average": 102,
"drought_risk": "low",
"flood_risk": "high",
"confidence": 90,
},
"security": {
"overall_risk": "medium",
"recent_incidents": 3,
"trend": "stable",
"confidence": 75,
},
"infrastructure": {
"road_accessibility": 70,
"power_availability": 45,
"internet_coverage": 60,
"water_access": 55,
"confidence": 80,
},
"population": {
"local_population": 45000,
"displacement": "low",
"growth_rate": 2.8,
"confidence": 85,
},
"nearby_projects": [
{"id": "proj-015", "name": "Regional Health Clinic", "distance_km": 5.2},
{"id": "proj-023", "name": "Road Improvement", "distance_km": 12.0},
],
"funding_ecosystem": {
"total_aid_in_region_usd": 45000000,
"major_donors": ["World Bank", "UNICEF", "GIZ"],
"coordination_level": "moderate",
},
},
"last_updated": datetime.now().isoformat(),
}
# ─── CAUSAL ANALYSIS ──────────────────────────────────────────────────────────
@router.get("/public/projects/{project_id}/causal-analysis")
async def get_causal_analysis(project_id: str):
"""Causal analysis layer - transparent statistical associations."""
return {
"project_id": project_id,
"disclaimer": "These are statistical associations and model-generated hypotheses, not proven causation.",
"observed_associations": [
{
"id": "assoc-001",
"observation": "Reduced accessibility following severe flooding",
"factors": [
{"name": "Heavy rainfall", "contribution": 0.45, "confidence": 92},
{"name": "Poor drainage infrastructure", "contribution": 0.30, "confidence": 78},
{"name": "Road surface quality", "contribution": 0.25, "confidence": 65},
],
"statistical_strength": "strong",
"evidence_sources": ["Satellite", "Weather data", "Field observation"],
"hypothesis": "Flooding disproportionately affects projects in areas with inadequate drainage",
"uncertainty": "Drainage quality is estimated from satellite and may not reflect recent improvements",
},
{
"id": "assoc-002",
"observation": "Construction delays associated with seasonal rainfall",
"factors": [
{"name": "Rainy season duration", "contribution": 0.60, "confidence": 85},
{"name": "Soil conditions", "contribution": 0.25, "confidence": 70},
{"name": "Equipment availability", "contribution": 0.15, "confidence": 55},
],
"statistical_strength": "moderate",
"evidence_sources": ["Satellite time-series", "Weather data", "Project reports"],
"hypothesis": "Projects in tropical regions experience predictable seasonal delays",
"uncertainty": "Equipment availability data is limited",
},
],
"distinguish": {
"observed_facts": "Flooding occurred on June 15, accessibility reduced by 40%",
"statistical_associations": "Projects in flood-prone areas 3x more likely to experience delays",
"model_hypotheses": "Drainage investment may reduce weather-related delays by 50%",
},
}
# ─── MULTI-SIGNAL CONFIDENCE ─────────────────────────────────────────────────
@router.get("/public/projects/{project_id}/confidence")
async def get_confidence_score(project_id: str):
"""Multi-signal confidence engine combining evidence from multiple sources."""
return {
"project_id": project_id,
"overall_confidence": 82,
"confidence_level": "high",
"evidence_breakdown": [
{
"category": "official_reporting",
"source": "UNICEF quarterly report",
"contribution": 15,
"weight": 0.15,
"reliability": 85,
"agreement_with_others": 72,
},
{
"category": "satellite",
"source": "Sentinel-2 imagery",
"contribution": 25,
"weight": 0.25,
"reliability": 95,
"agreement_with_others": 88,
},
{
"category": "quixzoom",
"source": "Field observations (12 contributors)",
"contribution": 25,
"weight": 0.25,
"reliability": 88,
"agreement_with_others": 85,
},
{
"category": "news",
"source": "Regional news monitoring",
"contribution": 10,
"weight": 0.10,
"reliability": 60,
"agreement_with_others": 65,
},
{
"category": "open_data",
"source": "Weather, population, economic data",
"contribution": 15,
"weight": 0.15,
"reliability": 90,
"agreement_with_others": 80,
},
{
"category": "historical",
"source": "Similar projects in region",
"contribution": 10,
"weight": 0.10,
"reliability": 75,
"agreement_with_others": 70,
},
],
"convergence_analysis": {
"sources_agree": 5,
"sources_disagree": 1,
"primary_disagreement": "Official reporting shows 95% completion vs observed 85%",
"confidence_increase": "Multiple independent sources converging on 82-88% completion",
},
"methodology": "Confidence increases as multiple independent sources converge. Disagreement reduces confidence but highlights areas for additional verification.",
}
# ─── PREDICTIVE INTELLIGENCE ─────────────────────────────────────────────────
@router.get("/public/projects/{project_id}/predictions")
async def get_predictions(project_id: str):
"""Predictive intelligence with uncertainty intervals."""
return {
"project_id": project_id,
"disclaimer": "Predictions are estimates based on current evidence and historical patterns. They are not certainties.",
"predictions": [
{
"id": "pred-001",
"type": "completion_date",
"prediction": "Project will complete by August 15, 2026",
"confidence": 72,
"uncertainty_interval": "August 1 - August 30, 2026",
"factors": [
{"factor": "Current progress rate", "impact": "positive", "strength": 0.7},
{"factor": "Seasonal weather forecast", "impact": "negative", "strength": 0.3},
{"factor": "Resource availability", "impact": "neutral", "strength": 0.5},
],
"assumptions": [
"No major weather disruptions",
"Funding continues as planned",
"Material supply remains stable",
],
},
{
"id": "pred-002",
"type": "operational_sustainability",
"prediction": "75% probability of sustained operation for 3+ years",
"confidence": 68,
"uncertainty_interval": "65-85%",
"factors": [
{"factor": "Maintenance plan quality", "impact": "positive", "strength": 0.8},
{"factor": "Local capacity", "impact": "positive", "strength": 0.6},
{"factor": "Funding continuity", "impact": "uncertain", "strength": 0.4},
],
"assumptions": [
"Local government maintains commitment",
"No major economic shocks",
],
},
{
"id": "pred-003",
"type": "risk_assessment",
"prediction": "Medium risk of 2-4 week delay due to rainy season",
"confidence": 78,
"uncertainty_interval": "Low-High",
"factors": [
{"factor": "Historical weather patterns", "impact": "negative", "strength": 0.8},
{"factor": "Drainage infrastructure", "impact": "positive", "strength": 0.5},
{"factor": "Contingency planning", "impact": "positive", "strength": 0.6},
],
"recommended_actions": [
"Accelerate indoor work before rainy season",
"Pre-position materials on-site",
"Develop drainage improvement plan",
],
},
],
}
# ─── EXPLAINABILITY ───────────────────────────────────────────────────────────
@router.get("/public/insights/{insight_id}/explain")
async def explain_insight(insight_id: str):
"""Every insight answers: What evidence? Which sources? What disagrees?"""
return {
"insight_id": insight_id,
"explainability": {
"what_evidence_supports_this": [
"12 field observations from 8 independent contributors",
"Sentinel-2 satellite imagery from 6 dates",
"Official quarterly report (June 2026)",
"Regional weather data showing 120% average rainfall",
],
"which_sources_contributed": [
{"source": "QUIXZOOM field observations", "weight": 0.30, "reliability": 88},
{"source": "Satellite imagery", "weight": 0.25, "reliability": 95},
{"source": "Official reporting", "weight": 0.20, "reliability": 85},
{"source": "Open weather data", "weight": 0.15, "reliability": 90},
{"source": "News monitoring", "weight": 0.10, "reliability": 60},
],
"what_observations_disagree": [
{
"observation": "Official report claims 95% completion",
"conflicting_evidence": "Field and satellite observations show 82-88%",
"possible_explanations": [
"Different measurement methodologies",
"Reporting date vs observation date lag",
"Interior work not visible from exterior",
],
},
],
"how_confident_is_the_estimate": {
"overall_confidence": 82,
"confidence_level": "high",
"primary_uncertainties": [
"Interior completion percentage is estimated",
"Official reporting may use different metrics",
],
},
"what_assumptions_influence_the_model": [
"Field observations are representative of overall progress",
"Satellite imagery accurately reflects ground conditions",
"Weather patterns follow historical trends",
],
"what_additional_evidence_would_increase_confidence": [
"Interior photographs from multiple angles",
"Construction timeline from contractor",
"Material delivery receipts",
"Independent engineering assessment",
],
},
}
# ─── DASHBOARD ────────────────────────────────────────────────────────────────
@router.get("/dashboard")
async def get_life_dashboard(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""LIFE admin dashboard."""
return {
"engine": "Landvex Intelligence Fusion Engine",
"version": "1.0.0",
"timestamp": datetime.now().isoformat(),
"data_sources": {
"total": 6,
"active": 6,
"streams_monitored": 45,
},
"projects": {
"monitored": 1250,
"with_context_graph": 1250,
"with_causal_analysis": 890,
"with_predictions": 1250,
},
"events_detected": {
"last_24h": 12,
"last_7d": 89,
"last_30d": 340,
"by_type": {
"natural_disaster": 45,
"conflict": 23,
"infrastructure_failure": 67,
"construction_delay": 120,
"political_instability": 15,
"environmental_incident": 70,
},
},
"confidence_distribution": {
"very_high": 320,
"high": 580,
"moderate": 280,
"low": 55,
"very_low": 15,
},
"recent_fusion_results": [
{
"project": "Mogadishu Primary School",
"insight": "Construction delay likely due to flooding + poor drainage",
"confidence": 78,
"sources_fused": 5,
},
{
"project": "Kampala Water Supply",
"insight": "Operational sustainability high based on maintenance records + community feedback",
"confidence": 88,
"sources_fused": 6,
},
],
}