Files
boc/landvex-admin-backend/app/routers/rivp_pilot1.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

193 lines
5.6 KiB
Python

"""
RIVP Pilot 1 - Real Infrastructure Monitoring
Reads from SQLite database with real road network and generated observations
"""
from fastapi import APIRouter
import sqlite3
import os
from typing import List, Optional
from datetime import datetime
router = APIRouter(prefix="/rivp-pilot1", tags=["rivp_pilot1"])
DB_PATH = "/home/bernt/.openclaw/workspace/rivp-pilot-1/rivp.db"
def get_db():
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
@router.get("/public/roads")
async def get_roads(county: Optional[str] = None, road_type: Optional[str] = None):
"""Get all roads with optional filtering"""
conn = get_db()
c = conn.cursor()
query = "SELECT * FROM roads WHERE 1=1"
params = []
if county:
query += " AND county = ?"
params.append(county)
if road_type:
query += " AND type = ?"
params.append(road_type)
query += " ORDER BY county, name"
c.execute(query, params)
roads = [dict(row) for row in c.fetchall()]
# Get observation count for each road
for road in roads:
c.execute("SELECT COUNT(*) FROM observations WHERE road_id = ?", (road['id'],))
road['observation_count'] = c.fetchone()[0]
conn.close()
return {
"total": len(roads),
"counties": list(set(r['county'] for r in roads)),
"roads": roads
}
@router.get("/public/observations")
async def get_observations(road_id: Optional[int] = None,
observation_type: Optional[str] = None,
severity: Optional[str] = None,
source: Optional[str] = None,
verified_only: bool = False):
"""Get observations with filtering"""
conn = get_db()
c = conn.cursor()
query = """
SELECT o.*, r.name as road_name, r.county
FROM observations o
JOIN roads r ON o.road_id = r.id
WHERE 1=1
"""
params = []
if road_id:
query += " AND o.road_id = ?"
params.append(road_id)
if observation_type:
query += " AND o.observation_type = ?"
params.append(observation_type)
if severity:
query += " AND o.severity = ?"
params.append(severity)
if source:
query += " AND o.source = ?"
params.append(source)
if verified_only:
query += " AND o.verified = 1"
query += " ORDER BY o.detected_date DESC"
c.execute(query, params)
observations = [dict(row) for row in c.fetchall()]
conn.close()
return {
"total": len(observations),
"observations": observations
}
@router.get("/public/dashboard")
async def get_dashboard():
"""Get dashboard statistics"""
conn = get_db()
c = conn.cursor()
# Total roads
c.execute("SELECT COUNT(*) FROM roads")
total_roads = c.fetchone()[0]
# Total observations
c.execute("SELECT COUNT(*) FROM observations")
total_observations = c.fetchone()[0]
# By type
c.execute("SELECT type, COUNT(*) FROM roads GROUP BY type")
roads_by_type = {row[0]: row[1] for row in c.fetchall()}
# By county
c.execute("SELECT county, COUNT(*) FROM roads GROUP BY county ORDER BY COUNT(*) DESC")
roads_by_county = [{"county": row[0], "count": row[1]} for row in c.fetchall()]
# Observations by type
c.execute("SELECT observation_type, COUNT(*) FROM observations GROUP BY observation_type")
obs_by_type = {row[0]: row[1] for row in c.fetchall()}
# Observations by source
c.execute("SELECT source, COUNT(*) FROM observations GROUP BY source")
obs_by_source = {row[0]: row[1] for row in c.fetchall()}
# Observations by severity
c.execute("SELECT severity, COUNT(*) FROM observations GROUP BY severity")
obs_by_severity = {row[0]: row[1] for row in c.fetchall()}
# Verified vs unverified
c.execute("SELECT verified, COUNT(*) FROM observations GROUP BY verified")
verification = {row[0]: row[1] for row in c.fetchall()}
# Average confidence
c.execute("SELECT AVG(confidence) FROM observations")
avg_confidence = c.fetchone()[0]
# Recent observations (last 30 days)
c.execute("""
SELECT COUNT(*) FROM observations
WHERE detected_date >= date('now', '-30 days')
""")
recent_obs = c.fetchone()[0]
conn.close()
return {
"roads": {
"total": total_roads,
"by_type": roads_by_type,
"by_county": roads_by_county[:10]
},
"observations": {
"total": total_observations,
"by_type": obs_by_type,
"by_source": obs_by_source,
"by_severity": obs_by_severity,
"verification": verification,
"average_confidence": round(avg_confidence, 2),
"last_30_days": recent_obs
}
}
@router.get("/public/map-data")
async def get_map_data(county: Optional[str] = None):
"""Get observation data for map visualization"""
conn = get_db()
c = conn.cursor()
query = """
SELECT o.id, o.latitude, o.longitude, o.observation_type,
o.confidence, o.severity, o.detected_date, o.verified,
r.name as road_name, r.county
FROM observations o
JOIN roads r ON o.road_id = r.id
WHERE 1=1
"""
params = []
if county:
query += " AND r.county = ?"
params.append(county)
c.execute(query, params)
points = [dict(row) for row in c.fetchall()]
conn.close()
return {
"total": len(points),
"points": points
}