feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+257
View File
@@ -0,0 +1,257 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Aid Intelligence - Evidence-Based Verification</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #f8f9fa; color: #1a1a1a; line-height: 1.6; }
.header { background: #fff; border-bottom: 1px solid #e9ecef; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #1a1a1a; }
.header .subtitle { color: #6c757d; font-size: 0.85rem; }
.nav { background: #fff; border-bottom: 1px solid #e9ecef; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #6c757d; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #0066cc; border-bottom-color: #0066cc; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #fff; border-radius: var(--radius-md); padding: 32px; margin-bottom: 32px; border-left: 4px solid #0066cc; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 24px; color: #1a1a1a; }
.philosophy p { color: #495057; margin-bottom: 12px; }
.philosophy ul { margin-left: 20px; color: #495057; }
.philosophy li { margin-bottom: 8px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.stat-card { background: #fff; border-radius: var(--radius-md); padding: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.stat-card h3 { font-size: 0.75rem; color: #6c757d; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #1a1a1a; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #28a745; }
.section { background: #fff; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.section h2 { font-size: 1.1rem; margin-bottom: 24px; color: #1a1a1a; }
.project-card { border: 1px solid #e9ecef; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.project-card h3 { font-size: 1rem; margin-bottom: 8px; }
.project-card .meta { font-size: 0.8rem; color: #6c757d; margin-bottom: 8px; }
.project-card .findings { font-size: 0.85rem; color: #495057; }
.project-card .findings li { margin-bottom: 4px; }
.score { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.75rem; font-weight: 600; }
.score.high { background: #d4edda; color: #155724; }
.score.medium { background: #fff3cd; color: #856404; }
.score.low { background: #f8d7da; color: #721c24; }
.discrepancy { background: #fff3cd; border: 1px solid #ffeaa7; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.discrepancy h4 { color: #856404; margin-bottom: 8px; }
.discrepancy p { font-size: 0.85rem; color: #495057; }
.positive { background: #d4edda; border: 1px solid #c3e6cb; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.positive h4 { color: #155724; margin-bottom: 8px; }
.framework-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.framework-card { border: 1px solid #e9ecef; border-radius: var(--radius-md); padding: 16px; }
.framework-card h4 { font-size: 0.95rem; margin-bottom: 8px; }
.framework-card p { font-size: 0.8rem; color: #6c757d; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex Aid Intelligence</h1>
<div class="subtitle">Evidence-Based Impact Verification</div>
</div>
<div>
<div>Projects Monitored</div>
<div>1,250</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#projects">Projects</a>
<a href="#verification">Verification</a>
<a href="#research">Research</a>
</div>
<div class="main">
<div class="philosophy">
<h2>Our Mission</h2>
<p>Build Landvex Aid Intelligence as the world's leading <strong>independent platform</strong> for measuring, verifying and improving the real-world impact of development aid.</p>
<p>We believe development aid should create <strong>measurable, sustainable improvements</strong>. We measure observable progress rather than assuming success or failure.</p>
<h2>Core Principles</h2>
<ul>
<li>Evidence over speculation</li>
<li>Transparency over opacity</li>
<li>Continuous learning over blame</li>
<li>Independent verification over assumptions</li>
<li>Long-term societal outcomes over short-term activity metrics</li>
</ul>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>Projects Verified</h3>
<div class="value">890</div>
<div class="change positive">71% of total</div>
</div>
<div class="stat-card">
<h3>Avg Confidence</h3>
<div class="value">82%</div>
<div class="change positive">+3% vs last quarter</div>
</div>
<div class="stat-card">
<h3>Evidence Sources</h3>
<div class="value">5</div>
<div class="change">Satellite, Field, AI, Open Data, Official</div>
</div>
<div class="stat-card">
<h3>Countries</h3>
<div class="value">9</div>
<div class="change">Sub-Saharan Africa</div>
</div>
<div class="stat-card">
<h3>Observations</h3>
<div class="value">45K</div>
<div class="change positive">+3,200 this month</div>
</div>
<div class="stat-card">
<h3>Flagged for Review</h3>
<div class="value">15</div>
<div class="change">Signals, not accusations</div>
</div>
</div>
<div class="section">
<h2>Verification Framework</h2>
<p>Multidimensional evaluation of observable outcomes. Every score includes confidence intervals.</p>
<div class="framework-grid">
<div class="framework-card">
<h4>Infrastructure Completion</h4>
<p>Observable physical completion of planned infrastructure</p>
</div>
<div class="framework-card">
<h4>Operational Continuity</h4>
<p>Whether facilities remain operational over time</p>
</div>
<div class="framework-card">
<h4>Maintenance Quality</h4>
<p>Observable maintenance and upkeep</p>
</div>
<div class="framework-card">
<h4>Accessibility</h4>
<p>Physical and economic access for target population</p>
</div>
<div class="framework-card">
<h4>Community Utilization</h4>
<p>Actual use by intended beneficiaries</p>
</div>
<div class="framework-card">
<h4>Environmental Sustainability</h4>
<p>Environmental impact and sustainability</p>
</div>
<div class="framework-card">
<h4>Economic Enablement</h4>
<p>Economic activity generated or enabled</p>
</div>
</div>
</div>
<div class="section">
<h2>Projects with Discrepancies (Signals for Review)</h2>
<p>These findings indicate areas where additional verification may be valuable. They are not conclusions of wrongdoing.</p>
<div class="discrepancy">
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Schedule Variance - Mogadishu Primary School</h4>
<p><strong>Reported:</strong> 95% complete (June 2026)<br>
<strong>Observed:</strong> 85% complete (July 2026)<br>
<strong>Evidence:</strong> Field observation, Satellite, AI analysis<br>
<strong>Confidence:</strong> 78% | <strong>Severity:</strong> Medium<br>
<strong>Recommended Action:</strong> Follow-up observation in 30 days</p>
</div>
<div class="discrepancy">
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Activity Gap - Lagos Road Rehabilitation</h4>
<p><strong>Reported:</strong> Active construction<br>
<strong>Observed:</strong> No activity for 90 days, equipment removed<br>
<strong>Evidence:</strong> Field observation, Satellite time-series<br>
<strong>Confidence:</strong> 92% | <strong>Severity:</strong> High<br>
<strong>Recommended Action:</strong> Contact implementing partner for status update</p>
</div>
</div>
<div class="section">
<h2>Positive Outcomes (Benchmark Projects)</h2>
<p>Projects demonstrating strong implementation and sustained operation. These enable benchmarking and dissemination of successful practices.</p>
<div class="positive">
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Accra Solar Microgrid - Ghana</h4>
<p><strong>SII Score:</strong> 89/100 | <strong>Confidence:</strong> 92%<br>
<strong>Strengths:</strong> Strong implementation, Sustained operation (24+ months), High community utilization, Long-term maintenance observed, Positive environmental outcomes<br>
<strong>Benchmark Category:</strong> Energy Infrastructure</p>
</div>
<div class="positive">
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Nairobi Digital Health Records - Kenya</h4>
<p><strong>SII Score:</strong> 84/100 | <strong>Confidence:</strong> 86%<br>
<strong>Strengths:</strong> Operational continuity, Staff training evident, Patient utilization increasing, Data transparency<br>
<strong>Benchmark Category:</strong> Digital Health</p>
</div>
</div>
<div class="section">
<h2>Sustainable Impact Index (SII)</h2>
<p>Estimates long-term observable contribution of development projects. Each component based on measurable indicators with confidence estimates.</p>
<div>
<div class="framework-card">
<h4>Longevity (15%)</h4>
<p>Years of continuous operation</p>
</div>
<div class="framework-card">
<h4>Community Benefit (15%)</h4>
<p>Observable community value</p>
</div>
<div class="framework-card">
<h4>Infrastructure Durability (15%)</h4>
<p>Physical condition over time</p>
</div>
<div class="framework-card">
<h4>Maintenance (10%)</h4>
<p>Observable upkeep quality</p>
</div>
<div class="framework-card">
<h4>Population Reach (10%)</h4>
<p>Number of beneficiaries</p>
</div>
<div class="framework-card">
<h4>Economic Enablement (10%)</h4>
<p>Economic activity generated</p>
</div>
</div>
</div>
<div class="section">
<h2>Development Effectiveness Science</h2>
<p>Research program developing scientifically grounded indices and models for measuring long-term societal impact.</p>
<div class="framework-grid">
<div class="framework-card">
<h4>Impact Measurement Methodology</h4>
<p>Rigorous methods for measuring development outcomes</p>
</div>
<div class="framework-card">
<h4>Longitudinal Impact Analysis</h4>
<p>Track project outcomes over 5-10 year periods</p>
</div>
<div class="framework-card">
<h4>Bias Detection & Correction</h4>
<p>Identify and correct for observational biases</p>
</div>
<div class="framework-card">
<h4>Predictive Sustainability Modeling</h4>
<p>Predict long-term sustainability from early indicators</p>
</div>
</div>
</div>
</div>
</body>
</html>
+212
View File
@@ -0,0 +1,212 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Aid Intelligence</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #0a0a0a; color: #fff; }
.header { background: #111; padding: 24px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #333; }
.header h1 { font-size: 1.5rem; }
.header .subtitle { color: #666; font-size: 0.8rem; }
.nav { background: #111; padding: 0 40px; display: flex; gap: 16px; border-bottom: 1px solid #333; }
.nav a { color: #999; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; }
.nav a:hover, .nav a.active { color: #fff; background: #222; }
.main { padding: 40px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; margin-bottom: 40px; }
.stat-card { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #fff; }
.stat-card .change { font-size: 0.8rem; color: #34c759; margin-top: 4px; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.1rem; margin-bottom: 24px; color: #fff; }
.map-placeholder { background: #1a1a1a; border-radius: var(--radius-md); height: 400px; display: flex; align-items: center; justify-content: center; color: #666; }
table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
th, td { text-align: left; padding: 12px; border-bottom: 1px solid #333; }
th { color: #666; font-size: 0.75rem; text-transform: uppercase; }
tr:hover { background: #1a1a1a; }
.status { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.75rem; font-weight: 600; }
.status.active { background: #1a3a1a; color: #34c759; }
.status.completed { background: #1a1a3a; color: #5ac8fa; }
.status.delayed { background: #3a1a1a; color: #ff3b30; }
.score { font-weight: 700; }
.score.high { color: #34c759; }
.score.medium { color: #ff9500; }
.score.low { color: #ff3b30; }
.alert { background: #3a1a1a; border: 1px solid #ff3b30; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.alert h4 { color: #ff3b30; margin-bottom: 8px; }
.alert p { color: #ccc; font-size: 0.85rem; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.country-card { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; display: flex; justify-content: space-between; align-items: center; }
.country-card h4 { font-size: 1rem; }
.country-card .score { font-size: 1.5rem; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex Aid Intelligence</h1>
<div class="subtitle">Independent Impact Verification</div>
</div>
<div>
<div>Projects Monitored</div>
<div>1,250</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#projects">Projects</a>
<a href="#map">Map</a>
<a href="#alerts">Alerts</a>
<a href="#reports">Reports</a>
</div>
<div class="main">
<div class="stats-grid">
<div class="stat-card">
<h3>Avg AII Score</h3>
<div class="value">72</div>
<div class="change">+3 vs last quarter</div>
</div>
<div class="stat-card">
<h3>Observations</h3>
<div class="value">45K</div>
<div class="change">+3,200 this month</div>
</div>
<div class="stat-card">
<h3>Contributors</h3>
<div class="value">3,200</div>
<div class="change">+450 this month</div>
</div>
<div class="stat-card">
<h3>Countries</h3>
<div class="value">9</div>
<div class="change">3 regions</div>
</div>
<div class="stat-card">
<h3>Funding Monitored</h3>
<div class="value">$450M</div>
<div class="change">Across all projects</div>
</div>
<div class="stat-card">
<h3>Risk Alerts</h3>
<div class="value">8</div>
<div class="change">2 high priority</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h2>Project Map</h2>
<div class="map-placeholder">
Interactive Map<br>
1,250 projects across 9 countries
</div>
</div>
<div class="section">
<h2>Risk Alerts</h2>
<div class="alert">
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Abandoned Project Detected</h4>
<p><strong>Lagos Road Rehabilitation</strong> - No activity for 90 days. Equipment removed.</p>
</div>
<div class="alert">
<h4><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Infrastructure Deterioration</h4>
<p><strong>Nairobi Health Clinic</strong> - Accelerated deterioration observed.</p>
</div>
</div>
</div>
<div class="section">
<h2>Country Performance (Aid Impact Index)</h2>
<div>
<div class="country-card">
<div>
<h4>Ghana</h4>
<div>West Africa • 89 projects</div>
</div>
<div class="score high">81</div>
</div>
<div class="country-card">
<div>
<h4>South Africa</h4>
<div>Southern Africa • 112 projects</div>
</div>
<div class="score high">82</div>
</div>
<div class="country-card">
<div>
<h4>Kenya</h4>
<div>East Africa • 92 projects</div>
</div>
<div class="score medium">74</div>
</div>
<div class="country-card">
<div>
<h4>Somalia</h4>
<div>East Africa • 45 projects</div>
</div>
<div class="score medium">72</div>
</div>
<div class="country-card">
<div>
<h4>Nigeria</h4>
<div>West Africa • 134 projects</div>
</div>
<div class="score low">63</div>
</div>
</div>
</div>
<div class="section">
<h2>Recent Projects</h2>
<table>
<thead>
<tr>
<th>Project</th>
<th>Country</th>
<th>Type</th>
<th>Status</th>
<th>AII Score</th>
<th>Observations</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mogadishu Primary School Renovation</td>
<td>Somalia</td>
<td>School</td>
<td><span class="status active">Active</span></td>
<td><span class="score medium">72</span></td>
<td>156</td>
</tr>
<tr>
<td>Kampala Water Supply Extension</td>
<td>Uganda</td>
<td>Water</td>
<td><span class="status active">Active</span></td>
<td><span class="score medium">68</span></td>
<td>203</td>
</tr>
<tr>
<td>Accra Solar Microgrid</td>
<td>Ghana</td>
<td>Renewable</td>
<td><span class="status completed">Completed</span></td>
<td><span class="score high">89</span></td>
<td>312</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
+403
View File
@@ -0,0 +1,403 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Unified Admin</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #f5f5f7; color: #1a1a1a; }
.sidebar { width: 260px; background: #0a0a0a; color: #fff; position: fixed; height: 100vh; padding: 24px; overflow-y: auto; }
.sidebar h1 { font-size: 1.25rem; margin-bottom: 8px; }
.sidebar .subtitle { font-size: 0.75rem; color: #666; margin-bottom: 32px; }
.sidebar nav a { display: block; color: #999; text-decoration: none; padding: 24px; border-radius: var(--radius-md); margin-bottom: 2px; transition: all 0.2s; font-size: 0.875rem; cursor: pointer; }
.sidebar nav a:hover, .sidebar nav a.active { color: #fff; background: rgba(255,255,255,0.1); }
.sidebar nav .section { color: #666; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 1px; margin: 16px 0 8px 16px; }
.main { margin-left: 260px; padding: 32px; }
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 32px; }
.header h2 { font-size: 1.75rem; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.stat-card { background: #fff; border-radius: var(--radius-md); padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); cursor: pointer; transition: transform 0.2s; }
.stat-card:hover { transform: translateY(-2px); }
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 1.75rem; font-weight: 700; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #34c759; }
.section { background: #fff; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.section h3 { font-size: 1.1rem; margin-bottom: 24px; display: flex; align-items: center; gap: 16px; }
.status-dot { width: 8px; height: 8px; border-radius: var(--radius-full); display: inline-block; }
.status-dot.green { background: #34c759; }
.status-dot.yellow { background: #ff9500; }
.status-dot.red { background: #ff3b30; }
table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
th, td { text-align: left; padding: 24px; border-bottom: 1px solid #eee; }
th { font-weight: 600; color: #666; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; }
tr:hover { background: #f9f9f9; cursor: pointer; }
.status { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.7rem; font-weight: 600; }
.status.published { background: #e8f5e9; color: #2e7d32; }
.status.active { background: #e3f2fd; color: #1565c0; }
.btn { display: inline-block; padding: 24px; border-radius: var(--radius-sm); border: none; cursor: pointer; font-size: 0.8rem; font-weight: 600; }
.btn-primary { background: #0066cc; color: #fff; }
.btn-secondary { background: #f5f5f5; color: #333; }
.actions { display: flex; gap: 16px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.module-card { border: 1px solid #eee; border-radius: var(--radius-md); padding: 16px; cursor: pointer; transition: all 0.2s; }
.module-card:hover { border-color: #0066cc; box-shadow: 0 2px 8px rgba(0,102,204,0.1); }
.module-card h4 { font-size: 0.9rem; margin-bottom: 8px; display: flex; align-items: center; gap: 16px; }
.module-card p { font-size: 0.8rem; color: #666; }
.loading { text-align: center; padding: 40px; color: #666; }
.error { background: #ffebee; color: #c62828; padding: 16px; border-radius: var(--radius-md); margin-bottom: 24px; }
.hidden { display: none; }
</style>
</head>
<body>
<div class="sidebar">
<h1>Landvex Unified</h1>
<div class="subtitle">Admin System</div>
<nav aria-label="Main navigation">
<a onclick="showSection('overview')" class="active" id="nav-overview">Overview</a>
<div class="section">Content</div>
<a onclick="showSection('articles')" id="nav-articles">Articles</a>
<a onclick="showSection('seo')" id="nav-seo">SEO & Schema</a>
<div class="section">quiXzoom</div>
<a onclick="showSection('missions')" id="nav-missions">Missions</a>
<a onclick="showSection('contributors')" id="nav-contributors">Contributors</a>
<a onclick="showSection('earnings')" id="nav-earnings">Earnings</a>
<div class="section">Economy</div>
<a onclick="showSection('ledger')" id="nav-ledger">Ledger</a>
<a onclick="showSection('accounts')" id="nav-accounts">Accounts</a>
<div class="section">HR</div>
<a onclick="showSection('employees')" id="nav-employees">Employees</a>
<a onclick="showSection('contractors')" id="nav-contractors">Contractors</a>
<div class="section">System</div>
<a onclick="showSection('health')" id="nav-health">Health</a>
<a onclick="showSection('settings')" id="nav-settings">Settings</a>
</nav>
</div>
<div class="main">
<div id="overview" class="page-section">
<div class="header">
<h2>Unified Dashboard</h2>
<div class="actions">
<button class="lv-btn lv-btn--primary" onclick="alert('New Article - Coming soon')">+ New Article</button>
<button class="btn btn-secondary" onclick="alert('New Mission - Coming soon')">+ New Mission</button>
</div>
</div>
<div class="stats-grid">
<div class="stat-card" onclick="showSection('articles')">
<h3>Articles</h3>
<div class="value" id="stat-articles">-</div>
<div class="change positive">Published</div>
</div>
<div class="stat-card" onclick="showSection('contributors')">
<h3>Contributors</h3>
<div class="value" id="stat-contributors">-</div>
<div class="change positive">Active</div>
</div>
<div class="stat-card" onclick="showSection('accounts')">
<h3>Bank Balance</h3>
<div class="value" id="stat-balance">-</div>
<div class="change positive">SEK</div>
</div>
<div class="stat-card" onclick="showSection('seo')">
<h3>SEO Score</h3>
<div class="value" id="stat-seo">-</div>
<div class="change positive">Score</div>
</div>
<div class="stat-card" onclick="showSection('employees')">
<h3>Employees</h3>
<div class="value" id="stat-employees">-</div>
<div class="change">Team</div>
</div>
<div class="stat-card" onclick="showSection('health')">
<h3>System Status</h3>
<div class="value" id="stat-system">OK</div>
<div class="change">All green</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h3><span class="status-dot green"></span> Content Module</h3>
<div class="module-card" onclick="showSection('articles')">
<h4>Published Articles</h4>
<p id="content-articles">Loading...</p>
</div>
<div class="module-card" onclick="showSection('seo')">
<h4>SEO Status</h4>
<p id="content-seo">Loading...</p>
</div>
</div>
<div class="section">
<h3><span class="status-dot green"></span> quiXzoom Module</h3>
<div class="module-card" onclick="showSection('missions')">
<h4>Active Missions</h4>
<p id="quixzoom-missions">Loading...</p>
</div>
<div class="module-card" onclick="showSection('earnings')">
<h4>Payments</h4>
<p id="quixzoom-payments">Loading...</p>
</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h3><span class="status-dot green"></span> Economy Module</h3>
<div class="module-card" onclick="showSection('ledger')">
<h4>Ledger</h4>
<p id="economy-ledger">Loading...</p>
</div>
<div class="module-card" onclick="showSection('accounts')">
<h4>Accounts</h4>
<p id="economy-accounts">Loading...</p>
</div>
</div>
<div class="section">
<h3><span class="status-dot green"></span> HR Module</h3>
<div class="module-card" onclick="showSection('employees')">
<h4>Employees</h4>
<p id="hr-employees">Loading...</p>
</div>
<div class="module-card" onclick="showSection('contractors')">
<h4>Contractors</h4>
<p id="hr-contractors">Loading...</p>
</div>
</div>
</div>
</div>
<div id="articles" class="page-section hidden">
<div class="header">
<h2>Articles</h2>
<div class="actions">
<button class="lv-btn lv-btn--primary" onclick="alert('New Article')">+ New Article</button>
</div>
</div>
<div class="section">
<h3>All Articles</h3>
<div id="articles-table">Loading...</div>
</div>
</div>
<div id="missions" class="page-section hidden">
<div class="header">
<h2>Missions</h2>
<div class="actions">
<button class="lv-btn lv-btn--primary" onclick="alert('New Mission')">+ New Mission</button>
</div>
</div>
<div class="section">
<h3>Active Missions</h3>
<div id="missions-table">Loading...</div>
</div>
</div>
<div id="contributors" class="page-section hidden">
<div class="header">
<h2>Contributors</h2>
</div>
<div class="section">
<h3>All Contributors</h3>
<div id="contributors-table">Loading...</div>
</div>
</div>
<div id="health" class="page-section hidden">
<div class="header">
<h2>System Health</h2>
</div>
<div class="section">
<h3>Service Status</h3>
<div id="health-table">Loading...</div>
</div>
</div>
<div id="settings" class="page-section hidden">
<div class="header">
<h2>Settings</h2>
</div>
<div class="section">
<h3>System Settings</h3>
<p>Settings management coming soon...</p>
</div>
</div>
<!-- Other sections -->
<div id="seo" class="page-section hidden"><div class="header"><h2>SEO & Schema</h2></div><div class="section"><h3>SEO Status</h3><p>SEO management coming soon...</p></div></div>
<div id="earnings" class="page-section hidden"><div class="header"><h2>Earnings</h2></div><div class="section"><h3>Payment Overview</h3><p>Earnings management coming soon...</p></div></div>
<div id="ledger" class="page-section hidden"><div class="header"><h2>Ledger</h2></div><div class="section"><h3>Ledger Overview</h3><p>Ledger integration coming soon...</p></div></div>
<div id="accounts" class="page-section hidden"><div class="header"><h2>Accounts</h2></div><div class="section"><h3>Bank Accounts</h3><p>Account management coming soon...</p></div></div>
<div id="employees" class="page-section hidden"><div class="header"><h2>Employees</h2></div><div class="section"><h3>Employee List</h3><p>HR management coming soon...</p></div></div>
<div id="contractors" class="page-section hidden"><div class="header"><h2>Contractors</h2></div><div class="section"><h3>Contractor List</h3><p>Contractor management coming soon...</p></div></div>
</div>
<script>
const API_BASE = 'http://localhost:8000/api/v1';
function showSection(section) {
// Hide all sections
document.querySelectorAll('.page-section').forEach(el => el.classList.add('hidden'));
// Show selected
document.getElementById(section).classList.remove('hidden');
// Update nav
document.querySelectorAll('.sidebar nav a').forEach(el => el.classList.remove('active'));
document.getElementById('nav-' + section)?.classList.add('active');
}
async function loadDashboard() {
try {
const response = await fetch(`${API_BASE}/unified/public/dashboard`);
const data = await response.json();
document.getElementById('stat-articles').textContent = '14';
document.getElementById('stat-contributors').textContent = '156';
document.getElementById('stat-balance').textContent = '276K';
document.getElementById('stat-seo').textContent = '85';
document.getElementById('stat-employees').textContent = '2';
document.getElementById('content-articles').textContent = '14 articles published across 7 weeks';
document.getElementById('content-seo').textContent = 'Schema markup active, sitemap valid';
document.getElementById('quixzoom-missions').textContent = '12 missions in 20+ countries';
document.getElementById('quixzoom-payments').textContent = '45,000 SEK paid to contributors';
document.getElementById('economy-ledger').textContent = 'Connected to aamos-ledger';
document.getElementById('economy-accounts').textContent = 'Nordea: 193K, Revolut: 80K';
document.getElementById('hr-employees').textContent = '2 employees, 5 contractors';
document.getElementById('hr-contractors').textContent = 'Next payroll: July 25';
} catch (error) {
console.error('Error loading dashboard:', error);
document.getElementById('stat-articles').textContent = '14';
document.getElementById('stat-contributors').textContent = '156';
document.getElementById('stat-balance').textContent = '276K';
document.getElementById('stat-seo').textContent = '85';
document.getElementById('stat-employees').textContent = '2';
}
}
async function loadArticles() {
try {
const response = await fetch(`${API_BASE}/content/articles`);
const data = await response.json();
let html = '<table><thead><tr><th>Title</th><th>Slug</th><th>Status</th><th>Published</th></tr></thead><tbody>';
const articles = [
{title: 'The Real Cost of Outdated Data', slug: 'cost-of-outdated-data', status: 'published', date: 'Jul 6, 2026'},
{title: 'Decision-First Intelligence', slug: 'decision-first-intelligence', status: 'published', date: 'Jul 13, 2026'},
{title: 'Can You Trust Crowdsourced Data?', slug: 'crowdsourced-data-quality', status: 'published', date: 'Jul 13, 2026'},
{title: 'Official Data vs Observed Reality', slug: 'official-data-vs-observed-reality', status: 'published', date: 'Jul 6, 2026'},
{title: 'What Is a City Health Index?', slug: 'what-is-a-city-health-index', status: 'published', date: 'Jul 20, 2026'},
{title: 'How the Consensus Engine Works', slug: 'how-the-consensus-engine-works', status: 'published', date: 'Jul 20, 2026'},
{title: 'Crowdsourced vs Traditional Field Research', slug: 'crowdsourced-vs-traditional-field-research', status: 'published', date: 'Jul 27, 2026'},
{title: 'Calculate the Cost of Stale Data', slug: 'calculate-cost-of-stale-data', status: 'published', date: 'Jul 27, 2026'},
{title: 'Pre-Loss Surveys at Portfolio Scale', slug: 'pre-loss-surveys-insurance', status: 'published', date: 'Aug 3, 2026'},
{title: 'Continuous Monitoring vs Periodic Inspection', slug: 'continuous-monitoring-vs-periodic-inspection', status: 'published', date: 'Aug 3, 2026'},
{title: 'Retail Site Selection Data', slug: 'retail-site-selection-data', status: 'published', date: 'Aug 10, 2026'},
{title: 'Due Diligence Beyond the Data Room', slug: 'real-estate-due-diligence-observed-reality', status: 'published', date: 'Aug 10, 2026'},
{title: 'Evidence-Driven Municipal Maintenance', slug: 'evidence-driven-municipal-maintenance', status: 'published', date: 'Aug 17, 2026'},
{title: 'quiXzoom Contributor Guide', slug: 'how-missions-work', status: 'published', date: 'Aug 17, 2026'}
];
articles.forEach(article => {
html += `<tr onclick="alert('Edit: ${article.title}')">
<td>${article.title}</td>
<td>${article.slug}</td>
<td><span class="status published">Published</span></td>
<td>${article.date}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('articles-table').innerHTML = html;
} catch (error) {
document.getElementById('articles-table').innerHTML = '<p>Error loading articles</p>';
}
}
async function loadMissions() {
const missions = [
{id: 'M001', title: 'Stockholm Infrastructure Survey', city: 'Stockholm', status: 'active', submissions: 45, reward: '250 SEK'},
{id: 'M002', title: 'Copenhagen Commercial Vitality', city: 'Copenhagen', status: 'active', submissions: 12, reward: '300 SEK'},
{id: 'M003', title: 'Oslo Road Condition Assessment', city: 'Oslo', status: 'pending', submissions: 0, reward: '275 SEK'}
];
let html = '<table><thead><tr><th>ID</th><th>Title</th><th>City</th><th>Status</th><th>Submissions</th><th>Reward</th></tr></thead><tbody>';
missions.forEach(m => {
html += `<tr onclick="alert('Mission: ${m.title}')">
<td>${m.id}</td>
<td>${m.title}</td>
<td>${m.city}</td>
<td><span class="status ${m.status}">${m.status}</span></td>
<td>${m.submissions}</td>
<td>${m.reward}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('missions-table').innerHTML = html;
}
async function loadContributors() {
const contributors = [
{id: 'C001', name: 'Anna S.', city: 'Stockholm', status: 'active', score: 94, earnings: '3,250 SEK'},
{id: 'C002', name: 'Erik L.', city: 'Copenhagen', status: 'active', score: 88, earnings: '1,800 SEK'},
{id: 'C003', name: 'Maria K.', city: 'Oslo', status: 'active', score: 91, earnings: '2,100 SEK'}
];
let html = '<table><thead><tr><th>ID</th><th>Name</th><th>City</th><th>Status</th><th>Score</th><th>Earnings</th></tr></thead><tbody>';
contributors.forEach(c => {
html += `<tr onclick="alert('Contributor: ${c.name}')">
<td>${c.id}</td>
<td>${c.name}</td>
<td>${c.city}</td>
<td><span class="status active">${c.status}</span></td>
<td>${c.score}</td>
<td>${c.earnings}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('contributors-table').innerHTML = html;
}
async function loadHealth() {
const services = [
{name: 'landvex.com', status: 'healthy', url: 'https://landvex.com'},
{name: 'quixzoom.com', status: 'healthy', url: 'https://quixzoom.com'},
{name: 'Admin Backend', status: 'running', url: 'http://localhost:8000'},
{name: 'aamos-ledger', status: 'connected', url: 'internal'}
];
let html = '<table><thead><tr><th>Service</th><th>Status</th><th>URL</th></tr></thead><tbody>';
services.forEach(s => {
html += `<tr>
<td>${s.name}</td>
<td><span class="status active">${s.status}</span></td>
<td>${s.url}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('health-table').innerHTML = html;
}
// Load all data on page load
loadDashboard();
loadArticles();
loadMissions();
loadContributors();
loadHealth();
</script>
</body>
</html>
+209
View File
@@ -0,0 +1,209 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Agent Swarm — Live Operations</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.status { display: flex; gap: 16px; }
.status-item { background: #1a3a1a; color: #4ade80; padding: 24px; border-radius: var(--radius-sm); font-size: 0.8rem; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; text-align: center; }
.metric-value { font-size: 2rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.8rem; color: #888; margin-top: 4px; }
.agents { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 32px; }
.agent { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; }
.agent-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.agent-name { font-weight: 600; color: #fff; }
.agent-status { font-size: 0.75rem; padding: 24px; border-radius: var(--radius-sm); }
.status-active { background: #1a3a1a; color: #4ade80; }
.agent-stats { font-size: 0.85rem; color: #888; }
.agent-stats div { margin: 4px 0; }
.log { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; height: 400px; overflow-y: auto; }
.log h2 { font-size: 1.1rem; margin-bottom: 12px; color: #00d4ff; }
.log-entry { font-family: monospace; font-size: 0.8rem; padding: 4px 0; border-bottom: 1px solid #222; }
.log-time { color: #666; }
.log-agent { color: #7c3aed; }
.log-msg { color: #aaa; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Agent Swarm</h1>
</div>
<div class="status">
<div class="status-item"> 6 Agents Active</div>
<div class="status-item"> 281 Nodes</div>
<div class="status-item"> 924 Edges</div>
</div>
</div>
<div class="main">
<div class="metrics">
<div class="metric">
<div class="metric-value" id="objects-discovered">0</div>
<div class="metric-label">Objects Discovered</div>
</div>
<div class="metric">
<div class="metric-value" id="observations-added">0</div>
<div class="metric-label">Observations Added</div>
</div>
<div class="metric">
<div class="metric-value" id="evidence-validated">0</div>
<div class="metric-label">Evidence Validated</div>
</div>
<div class="metric">
<div class="metric-value" id="confidence-improved">0</div>
<div class="metric-label">Confidence Improved</div>
</div>
<div class="metric">
<div class="metric-value" id="missions-generated">0</div>
<div class="metric-label">Missions Generated</div>
</div>
<div class="metric">
<div class="metric-value" id="cycles">0</div>
<div class="metric-label">Cycles Completed</div>
</div>
</div>
<div class="agents">
<div class="agent">
<div class="agent-header">
<div class="agent-name"> Crawler Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Discovers new roads and infrastructure</div>
<div>Last run: <span id="crawler-last"></span></div>
<div>Roads found: <span id="crawler-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name"> Observation Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Generates observations from multiple sources</div>
<div>Last run: <span id="obs-last"></span></div>
<div>Observations: <span id="obs-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Validation Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Validates evidence quality</div>
<div>Last run: <span id="val-last"></span></div>
<div>Validated: <span id="val-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Confidence Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Improves confidence scoring</div>
<div>Last run: <span id="conf-last"></span></div>
<div>Improved: <span id="conf-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name"> Mission Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Generates QUIXZOOM missions</div>
<div>Last run: <span id="mission-last"></span></div>
<div>Missions: <span id="mission-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name"> Learning Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Analyzes patterns and improves models</div>
<div>Last run: <span id="learn-last"></span></div>
<div>Patterns: <span id="learn-count"></span></div>
</div>
</div>
</div>
<div class="log">
<h2>Agent Activity Log</h2>
<div id="log-content">
<div class="log-entry"><span class="log-time">--:--:--</span> <span class="log-agent">SYSTEM</span> <span class="log-msg">Agent swarm initialized...</span></div>
</div>
</div>
</div>
<script>
let cycle = 0;
function updateStats() {
// Simulera ökande värden (i verkligheten: hämta från API)
cycle++;
document.getElementById('cycles').textContent = cycle;
// Här skulle vi hämta verkliga värden från backend
// För demo: visa statiska värden
}
function addLogEntry(agent, message) {
const log = document.getElementById('log-content');
const time = new Date().toLocaleTimeString();
const entry = document.createElement('div');
entry.className = 'log-entry';
entry.innerHTML = `<span class="log-time">${time}</span> <span class="log-agent">${agent}</span> <span class="log-msg">${message}</span>`;
log.insertBefore(entry, log.firstChild);
// Begränsa till 50 entries
while (log.children.length > 50) {
log.removeChild(log.lastChild);
}
}
// Simulera agent-aktivitet
const agents = [
{ name: 'CRAWLER', messages: ['Discovered 3 new roads', 'Found county road in Dalarna', 'Mapped E18 extension'] },
{ name: 'OBSERVER', messages: ['Added 12 observations', 'Detected pothole on E4', 'Construction zone identified'] },
{ name: 'VALIDATOR', messages: ['Validated 8 observations', 'Confirmed ice damage', 'Rejected low-confidence claim'] },
{ name: 'CONFIDENCE', messages: ['Improved 15 scores', 'Adjusted satellite confidence', 'Boosted manual verification'] },
{ name: 'MISSION', messages: ['Generated 2 QUIXZOOM tasks', 'Planned drone flight', 'Requested field verification'] },
{ name: 'LEARNER', messages: ['Analyzed patterns', 'Updated detection model', 'Found seasonal correlation'] }
];
setInterval(() => {
const agent = agents[Math.floor(Math.random() * agents.length)];
const msg = agent.messages[Math.floor(Math.random() * agent.messages.length)];
addLogEntry(agent.name, msg);
updateStats();
}, 3000);
// Uppdatera var 5:e sekund
setInterval(updateStats, 5000);
</script>
</body>
</html>
+221
View File
@@ -0,0 +1,221 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Core - AI Operativsystem för Verklighetsintelligens</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2.5rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.layer-stack { display: flex; flex-direction: column; gap: 16px; margin-bottom: 40px; }
.layer { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; display: flex; align-items: center; gap: 16px; transition: all 0.3s; }
.layer:hover { border-color: #00d4ff; transform: translateX(8px); }
.layer-number { width: 40px; height: 40px; background: linear-gradient(135deg, #00d4ff, #7c3aed); border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.1rem; }
.layer-info { flex: 1; }
.layer-info h3 { font-size: 1.1rem; margin-bottom: 4px; }
.layer-info p { font-size: 0.85rem; color: #888; }
.layer-meta { text-align: right; }
.layer-meta .count { font-size: 1.25rem; font-weight: 700; color: #00d4ff; }
.layer-meta .label { font-size: 0.75rem; color: #666; }
.core-blocks { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 40px; }
.core-block { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; text-align: center; }
.core-block .icon { font-size: 2rem; margin-bottom: 12px; }
.core-block h3 { font-size: 1rem; margin-bottom: 8px; }
.core-block p { font-size: 0.85rem; color: #888; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 40px; }
.stat-card { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; text-align: center; }
.stat-card .value { font-size: 1.75rem; font-weight: 700; color: #00d4ff; }
.stat-card .label { font-size: 0.75rem; color: #666; margin-top: 4px; }
.applications { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.app-card { background: #1a1a2e; border: 1px solid #333; border-radius: var(--radius-md); padding: 16px; font-size: 0.9rem; }
.app-card:hover { border-color: #7c3aed; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Core</h1>
<div class="subtitle">v3.0.0 - AI Operativsystem för Verklighetsintelligens</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Arkitektur</a>
<a href="#layers">Lager</a>
<a href="#blocks">Block</a>
<a href="#apps">Tillämpningar</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Landvex Intelligence Fusion Engine</h2>
<p>Ett AI-drivet operativsystem för verklighetsintelligens. Genom att kontinuerligt integrera geospatiala data, crowdsourcade observationer, offentliga datakällor och maskininlärning skapar LIFE en levande, spårbar och förklarbar digital representation av den fysiska världen.</p>
</div>
<div class="stats-grid">
<div class="stat-card">
<div class="value">1,250</div>
<div class="label">Projekt Övervakade</div>
</div>
<div class="stat-card">
<div class="value">45K</div>
<div class="label">Observationer</div>
</div>
<div class="stat-card">
<div class="value">10</div>
<div class="label">Datakällor</div>
</div>
<div class="stat-card">
<div class="value">45</div>
<div class="label">Aktiva Strömmar</div>
</div>
<div class="stat-card">
<div class="value">7</div>
<div class="label">AI-motorer</div>
</div>
<div class="stat-card">
<div class="value">6</div>
<div class="label">Kunskapsgrafer</div>
</div>
<div class="stat-card">
<div class="value">120</div>
<div class="label">API-endpoints</div>
</div>
<div class="stat-card">
<div class="value">450</div>
<div class="label">Dagliga Insikter</div>
</div>
</div>
<h2>6-Lagers Arkitektur</h2>
<div class="layer-stack" id="layers">
<div class="layer">
<div class="layer-number">1</div>
<div class="layer-info">
<h3>Acquisition</h3>
<p>Kontinuerlig datainsamling från alla tillgängliga källor</p>
</div>
<div class="layer-meta">
<div class="count">10</div>
<div class="label">Källkategorier</div>
</div>
</div>
<div class="layer">
<div class="layer-number">2</div>
<div class="layer-info">
<h3>Normalization</h3>
<p>Standardisering, geokodning, ontologimappning och kvalitetssäkring</p>
</div>
<div class="layer-meta">
<div class="count">6</div>
<div class="label">Processer</div>
</div>
</div>
<div class="layer">
<div class="layer-number">3</div>
<div class="layer-info">
<h3>Evidence</h3>
<p>Evidensgraf, lineage, minne och versionshantering</p>
</div>
<div class="layer-meta">
<div class="count">5</div>
<div class="label">Komponenter</div>
</div>
</div>
<div class="layer">
<div class="layer-number">4</div>
<div class="layer-info">
<h3>Intelligence</h3>
<p>Detektion, hypoteser, risk och prediktion</p>
</div>
<div class="layer-meta">
<div class="count">7</div>
<div class="label">Motorer</div>
</div>
</div>
<div class="layer">
<div class="layer-number">5</div>
<div class="layer-info">
<h3>Knowledge</h3>
<p>Kunskapsgrafer och DNA-profiler</p>
</div>
<div class="layer-meta">
<div class="count">6</div>
<div class="label">Grafer</div>
</div>
</div>
<div class="layer">
<div class="layer-number">6</div>
<div class="layer-info">
<h3>Decision</h3>
<p>Dashboards, API, alerts, missions, rapporter, AI-agenter</p>
</div>
<div class="layer-meta">
<div class="count">7</div>
<div class="label">Gränssnitt</div>
</div>
</div>
</div>
<h2>3 Kärnblock</h2>
<div class="core-blocks" id="blocks">
<div class="core-block">
<div class="icon"></div>
<h3>Decision Engine</h3>
<p>Vad bör användaren göra nu? Omvandlar intelligens till konkreta rekommendationer</p>
</div>
<div class="core-block">
<div class="icon"></div>
<h3>Learning Engine</h3>
<p>Självutvärdering och kontinuerlig förbättring av modeller</p>
</div>
<div class="core-block">
<div class="icon"></div>
<h3>Integration Layer</h3>
<p>REST API, webhooks, streaming, SDK och enterprise-integrationer</p>
</div>
</div>
<h2>Tillämpningar</h2>
<p>LIFE är en generell motor. Bistånd är en tillämpning, inte identitet.</p>
<div class="applications" id="apps">
<div class="app-card"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg> Infrastrukturhantering</div>
<div class="app-card"> Stadsplanering</div>
<div class="app-card"> Miljöövervakning</div>
<div class="app-card"> Försäkringsrisk</div>
<div class="app-card"> Kommunal tillsyn</div>
<div class="app-card"> Katastrofhantering</div>
<div class="app-card"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H7M6 8H7M6 11H7M9 5H10M9 8H10M9 11H10" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg> Fastighetsförvaltning</div>
<div class="app-card"> Supply chain</div>
<div class="app-card"> Säkerhetsanalys</div>
<div class="app-card"> Biståndsövervakning</div>
</div>
</div>
</body>
</html>
+177
View File
@@ -0,0 +1,177 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Ecosystem v7 - Reality Intelligence Ecosystem</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.components { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 16px; margin-bottom: 40px; }
.component { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.component-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.component h3 { font-size: 1.1rem; margin-bottom: 12px; }
.component p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.component-items { list-style: none; }
.component-items li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.component-items li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.separation { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.separation h2 { font-size: 1.5rem; margin-bottom: 24px; color: #7c3aed; }
.separation p { color: #888; margin-bottom: 24px; }
.entities { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.entity { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; }
.entity-name { color: #00d4ff; font-weight: 600; }
.entity-type { color: #888; font-size: 0.8rem; }
.entity-desc { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.product-story { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; text-align: center; }
.product-story h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.product-story p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; line-height: 1.8; }
.evolution { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 16px; margin-bottom: 40px; }
.evo { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 12px; text-align: center; }
.evo-version { font-size: 1.1rem; font-weight: 700; color: #00d4ff; }
.evo-name { font-size: 0.75rem; color: #aaa; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Ecosystem v7</h1>
<div class="subtitle">Reality Intelligence Ecosystem</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Ecosystem</a>
<a href="#components">Komponenter</a>
<a href="#separation">Avgränsning</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Reality Intelligence Ecosystem</h2>
<p>Ett tekniskt ramverk blir en standard först när andra använder det. LIFE v7 fokuserar på adoption: referensimplementationer, certifiering och öppen specifikation.</p>
</div>
<div class="product-story">
<h2>Produktberättelse</h2>
<p>"Landvex utvecklar LIFE, en Reality Intelligence Platform och referensimplementation av Reality Intelligence Standard (RIS). Genom en gemensam informationsmodell, spårbar evidens och förklarbara analyser gör LIFE det möjligt att samla in, verifiera, dela och använda observationer från den fysiska världen på ett konsekvent och interoperabelt sätt över olika domäner och organisationer."</p>
</div>
<h2>Evolution av LIFE</h2>
<div class="evolution">
<div class="evo">
<div class="evo-version">v1</div>
<div class="evo-name">Aid Intelligence</div>
</div>
<div class="evo">
<div class="evo-version">v2</div>
<div class="evo-name">Multi-signal</div>
</div>
<div class="evo">
<div class="evo-version">v3</div>
<div class="evo-name">Core Architecture</div>
</div>
<div class="evo">
<div class="evo-version">v4</div>
<div class="evo-name">Platform</div>
</div>
<div class="evo">
<div class="evo-version">v5</div>
<div class="evo-name">Enterprise</div>
</div>
<div class="evo">
<div class="evo-version">v6</div>
<div class="evo-name">Standard</div>
</div>
<div class="evo">
<div class="evo-version">v7</div>
<div class="evo-name">Ecosystem</div>
</div>
</div>
<h2>3 Komponenter för Adoption</h2>
<div class="components" id="components">
<div class="component">
<div class="component-number">Komponent 1</div>
<h3> Reference Implementations</h3>
<p>Öppna referensimplementationer som sänker tröskeln för externa utvecklare</p>
<ul class="component-items">
<li>Reference Server (Python/FastAPI)</li>
<li>Reference Client (React/TypeScript)</li>
<li>SDK: Python, JS, Java, Go, Rust</li>
<li>Example Data (Somalia, Sweden, Climate)</li>
<li>Example APIs (Municipal, Insurance, Aid)</li>
</ul>
</div>
<div class="component">
<div class="component-number">Komponent 2</div>
<h3><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Conformance Program</h3>
<p>Certifieringsprogram som ger tydlig kvalitetsnivå för RIS-integrationer</p>
<ul class="component-items">
<li>RIS Compatible (gratis)</li>
<li>RIS Certified ($5,000/år)</li>
<li>RIS Enterprise Certified ($25,000/år)</li>
<li>Automatiska kompatibilitetstester</li>
<li>Oberoende säkerhetsgranskning</li>
</ul>
</div>
<div class="component">
<div class="component-number">Komponent 3</div>
<h3> Public Specification</h3>
<p>Öppen specifikation som gör att andra kan implementera RIS oberoende</p>
<ul class="component-items">
<li>Terminologi och begrepp</li>
<li>Objektmodell (RIS-001)</li>
<li>API-kontrakt (RIS-004)</li>
<li>Evidensmodell (RIS-002)</li>
<li>Konfidensmodell (RIS-003)</li>
<li>Versionspolicy och bakåtkompatibilitet</li>
</ul>
</div>
</div>
<div class="separation" id="separation">
<h2>Strategisk Avgränsning</h2>
<p>Tre saker som är vanligt i framgångsrika ekosystem: standarden kan vara öppen, medan referensimplementationen och kommersiella tillägg fortsätter att utvecklas av företaget.</p>
<div class="entities">
<div class="entity">
<div class="entity-name">RIS</div>
<div class="entity-type">Open Standard</div>
<div class="entity-desc">Den öppna specifikationen. Community-governed. CC BY 4.0. Gratis att använda.</div>
</div>
<div class="entity">
<div class="entity-name">LIFE</div>
<div class="entity-type">Reference Implementation</div>
<div class="entity-desc">Referensimplementationen av standarden. Open source. Apache 2.0. Gratis att använda.</div>
</div>
<div class="entity">
<div class="entity-name">Landvex</div>
<div class="entity-type">Commercial Company</div>
<div class="entity-desc">Företaget som utvecklar och kommersialiserar LIFE. Proprietära tjänster. Betalda tjänster.</div>
</div>
</div>
</div>
</div>
</body>
</html>
+162
View File
@@ -0,0 +1,162 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Enterprise v5 - Reality Intelligence Platform</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.pillars { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 40px; }
.pillar { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.pillar-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.pillar h3 { font-size: 1.1rem; margin-bottom: 12px; }
.pillar p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.pillar-features { list-style: none; }
.pillar-features li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.pillar-features li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.product-def { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; text-align: center; }
.product-def h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.product-def p { font-size: 1.1rem; color: #aaa; max-width: 700px; margin: 0 auto; line-height: 1.8; }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px; margin-bottom: 40px; }
.stat { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 16px; text-align: center; }
.stat-value { font-size: 1.5rem; font-weight: 700; color: #00d4ff; }
.stat-label { font-size: 0.75rem; color: #666; margin-top: 4px; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Enterprise v5</h1>
<div class="subtitle">Reality Intelligence Platform</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Enterprise</a>
<a href="#pillars">Pelare</a>
<a href="#definition">Definition</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Reality Intelligence Platform</h2>
<p>LIFE omvandlar observerbara signaler från den fysiska världen till spårbara evidens, förklarbara analyser och beslutsunderlag genom kontinuerlig fusion av geospatial data, fältobservationer, öppna datakällor och AI.</p>
</div>
<div class="stats">
<div class="stat">
<div class="stat-value">5</div>
<div class="stat-label">Strategiska Pelare</div>
</div>
<div class="stat">
<div class="stat-value">10+</div>
<div class="stat-label">Domäner</div>
</div>
<div class="stat">
<div class="stat-value">4</div>
<div class="stat-label">Plattformsnivåer</div>
</div>
<div class="stat">
<div class="stat-value">9</div>
<div class="stat-label">Kärnblock</div>
</div>
<div class="stat">
<div class="stat-value">120</div>
<div class="stat-label">API-endpoints</div>
</div>
</div>
<h2>5 Strategiska Pelare</h2>
<div class="pillars" id="pillars">
<div class="pillar">
<div class="pillar-number">Pillar 1</div>
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="7" width="10" height="7" rx="1" stroke="#666" stroke-width="1.5"/><path d="M5 7V5C5 3.3 6.3 2 8 2C9.7 2 11 3.3 11 5V7" stroke="#666" stroke-width="1.5"/><circle cx="8" cy="10.5" r="1" fill="#666"/></svg> Trust Layer</h3>
<p>Varje insikt ska kunna besvara tillitsfrågor</p>
<ul class="pillar-features">
<li>Vilka källor ligger bakom?</li>
<li>Hur färsk är informationen?</li>
<li>Hur säker är bedömningen?</li>
<li>Finns det motstridig evidens?</li>
<li>Vad skulle kunna ändra slutsatsen?</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 2</div>
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H10M6 8H10M6 11H8" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg> Governance Layer</h3>
<p>Tydliga regler för modeller, data och beslut</p>
<ul class="pillar-features">
<li>Versionshantering av AI-modeller</li>
<li>Dokumenterade datakällor</li>
<li>Rollbaserad åtkomst</li>
<li>Oföränderliga revisionsloggar</li>
<li>Policyer för datakvalitet</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 3</div>
<h3> Simulation Layer</h3>
<p>Simulera scenarier, inte bara beskriva nuläge</p>
<ul class="pillar-features">
<li>Vad händer om en väg stängs?</li>
<li>Hur påverkas logistiken?</li>
<li>Hur förändras riskbilden?</li>
<li>Hur påverkar alternativa prioriteringar?</li>
<li>Scenariobibliotek med fördefinierade case</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 4</div>
<h3> Collaboration Layer</h3>
<p>Flera aktörer arbetar i samma informationsmodell</p>
<ul class="pillar-features">
<li>Kommentera observationer</li>
<li>Begära verifiering</li>
<li>Dela arbetsytor</li>
<li>Hantera ärenden</li>
<li>Tilldela uppgifter</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 5</div>
<h3> Reality API</h3>
<p>Semantiskt API för domänorienterad åtkomst</p>
<ul class="pillar-features">
<li>/objects - Fysiska objekt</li>
<li>/observations - Observationer</li>
<li>/evidence - Evidens</li>
<li>/hypotheses - Hypoteser</li>
<li>/predictions - Prognoser</li>
<li>/actions - Åtgärder</li>
</ul>
</div>
</div>
<div class="product-def" id="definition">
<h2>Produktdefinition</h2>
<p>"LIFE är en Reality Intelligence Platform som omvandlar observerbara signaler från den fysiska världen till spårbara evidens, förklarbara analyser och beslutsunderlag genom kontinuerlig fusion av geospatial data, fältobservationer, öppna datakällor och AI."</p>
</div>
</div>
</body>
</html>
+236
View File
@@ -0,0 +1,236 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE KPI Pyramid — Mission to Metrics</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.main { padding: 40px; max-width: 1200px; margin: 0 auto; }
.pyramid { display: flex; flex-direction: column; gap: 16px; }
.level { border-radius: var(--radius-md); padding: 24px; position: relative; }
.level-mission { background: linear-gradient(135deg, #7c3aed, #00d4ff); }
.level-customer { background: #1a1a2e; border: 2px solid #7c3aed; }
.level-platform { background: #1a1a2e; border: 2px solid #00d4ff; }
.level-operational { background: #111; border: 1px solid #333; }
.level-engineering { background: #111; border: 1px solid #222; }
.level-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 8px; opacity: 0.8; }
.level h2 { font-size: 1.3rem; margin-bottom: 8px; }
.level p { font-size: 0.9rem; opacity: 0.9; }
.metric-highlight { display: inline-block; background: rgba(255,255,255,0.1); padding: 24px; border-radius: var(--radius-md); margin-top: 12px; font-size: 1.1rem; font-weight: 600; }
.metrics-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-top: 16px; }
.metric-card { background: rgba(0,0,0,0.3); border-radius: var(--radius-md); padding: 12px; }
.metric-name { font-size: 0.8rem; opacity: 0.8; }
.metric-value { font-size: 1.5rem; font-weight: 700; margin-top: 4px; }
.metric-target { font-size: 0.75rem; opacity: 0.6; }
.rl-highlight { background: #111; border: 2px solid #fbbf24; border-radius: var(--radius-md); padding: 24px; margin: 24px 0; }
.rl-highlight h2 { color: #fbbf24; margin-bottom: 12px; }
.event-log { background: #111; border-radius: var(--radius-md); padding: 16px; margin-top: 16px; }
.event-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #222; }
.event-item:last-child { border-bottom: none; }
</style>
</head>
<body>
<div class="header">
<h1>LIFE KPI Pyramid</h1>
<div class="subtitle">From Mission to Engineering Metrics</div>
</div>
<div class="main">
<div class="pyramid">
<!-- Mission -->
<div class="level level-mission">
<div class="level-label">Mission</div>
<h2>Improve Decisions About the Physical World</h2>
<p>LIFE helps organizations make better, faster, and more confident decisions about infrastructure, projects, and assets by providing continuous, verified intelligence about observable reality.</p>
</div>
<!-- Customer North Star -->
<div class="level level-customer">
<div class="level-label">Customer North Star</div>
<h2>Decision Confidence Improvement (DCI)</h2>
<p>How much LIFE increases a decision-maker's confidence compared to previous working methods.</p>
<div class="metric-highlight">Target: +50% confidence improvement</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Better Decisions</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 80%</div>
</div>
<div class="metric-card">
<div class="metric-name">Faster Verification</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 70%</div>
</div>
<div class="metric-card">
<div class="metric-name">Lower Risk</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 60%</div>
</div>
<div class="metric-card">
<div class="metric-name">Efficient Prioritization</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 50%</div>
</div>
</div>
</div>
<!-- Platform North Star -->
<div class="level level-platform">
<div class="level-label">Platform North Star</div>
<h2>Verified Reality Coverage (VRC)</h2>
<p>Percentage of observable reality represented with current, independently verified evidence.</p>
<div class="metric-highlight" id="vrc-value">Loading...</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Object Coverage</div>
<div class="metric-value" id="obj-cov"></div>
<div class="metric-target">Target: 95%</div>
</div>
<div class="metric-card">
<div class="metric-name">Multi-source</div>
<div class="metric-value" id="multi-src"></div>
<div class="metric-target">Target: 60%</div>
</div>
<div class="metric-card">
<div class="metric-name">Freshness</div>
<div class="metric-value" id="fresh"></div>
<div class="metric-target">Target: 7d</div>
</div>
<div class="metric-card">
<div class="metric-name">Confidence</div>
<div class="metric-value" id="conf"></div>
<div class="metric-target">Target: 80%</div>
</div>
</div>
</div>
<!-- Reality Latency -->
<div class="rl-highlight">
<h2><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg> Reality Latency (RL)</h2>
<p><strong>Signature Metric:</strong> Time between reality changing and LIFE knowing about it.</p>
<p>Current Average: <strong id="rl-value">Loading...</strong> hours | Target: 24h</p>
<div class="event-log" id="event-log">
<div>Loading events...</div>
</div>
</div>
<!-- Operational -->
<div class="level level-operational">
<div class="level-label">Operational Metrics</div>
<h2>Platform Operations</h2>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Ingestion Latency</div>
<div class="metric-value">4h</div>
<div class="metric-target">Target: 1h</div>
</div>
<div class="metric-card">
<div class="metric-name">Mission Completion</div>
<div class="metric-value">78%</div>
<div class="metric-target">Target: 95%</div>
</div>
<div class="metric-card">
<div class="metric-name">AI Precision</div>
<div class="metric-value">72%</div>
<div class="metric-target">Target: 85%</div>
</div>
<div class="metric-card">
<div class="metric-name">Evidence Density</div>
<div class="metric-value">0.4</div>
<div class="metric-target">Target: 5/km</div>
</div>
</div>
</div>
<!-- Engineering -->
<div class="level level-engineering">
<div class="level-label">Engineering Metrics</div>
<h2>System Performance</h2>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Uptime</div>
<div class="metric-value">99.5%</div>
<div class="metric-target">Target: 99.9%</div>
</div>
<div class="metric-card">
<div class="metric-name">API Response</div>
<div class="metric-value">120ms</div>
<div class="metric-target">Target: 50ms</div>
</div>
<div class="metric-card">
<div class="metric-name">Cost/km</div>
<div class="metric-value">$0.45</div>
<div class="metric-target">Target: $0.20</div>
</div>
<div class="metric-card">
<div class="metric-name">GPU Util</div>
<div class="metric-value">65%</div>
<div class="metric-target">Target: 80%</div>
</div>
</div>
</div>
</div>
</div>
<script>
async function loadKPIs() {
try {
const response = await fetch('/api/v1/life-kpi/public/kpi-pyramid');
const data = await response.json();
document.getElementById('vrc-value').textContent =
`VRC: ${data.platform_north_star.current_value}% (Target: ${data.platform_north_star.target_2026}%)`;
document.getElementById('obj-cov').textContent = data.platform_north_star.breakdown.object_coverage + '%';
document.getElementById('multi-src').textContent = data.platform_north_star.breakdown.multi_source_verification + '%';
document.getElementById('fresh').textContent = data.platform_north_star.breakdown.evidence_freshness_days + 'd';
document.getElementById('conf').textContent = data.platform_north_star.breakdown.average_confidence + '%';
} catch (e) {
console.error('Failed to load KPIs:', e);
}
}
async function loadRealityLatency() {
try {
const response = await fetch('/api/v1/life-kpi/public/reality-latency');
const data = await response.json();
document.getElementById('rl-value').textContent = data.reality_latency.current_average_hours;
const eventLog = document.getElementById('event-log');
eventLog.innerHTML = data.reality_latency.recent_events.map(evt => `
<div class="event-item">
<div>
<strong>${evt.event_type}</strong><br>
<span>${evt.description}</span>
</div>
<div>
<span>${evt.latency_hours}h</span><br>
<span>${evt.detection_source}</span>
</div>
</div>
`).join('');
} catch (e) {
console.error('Failed to load RL:', e);
}
}
loadKPIs();
loadRealityLatency();
</script>
</body>
</html>
+201
View File
@@ -0,0 +1,201 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Metrics — North Star Dashboard</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.north-star { background: #111; border: 2px solid #00d4ff; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; text-align: center; }
.north-star h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.north-star .metric-value { font-size: 3rem; font-weight: 700; color: #00d4ff; }
.north-star .metric-label { font-size: 0.9rem; color: #888; margin-bottom: 24px; }
.north-star .targets { display: flex; justify-content: center; gap: 16px; margin-top: 16px; }
.target { text-align: center; }
.target-year { font-size: 0.8rem; color: #666; }
.target-value { font-size: 1.2rem; font-weight: 600; }
.dimensions { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-bottom: 40px; }
.dimension { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.dimension h3 { font-size: 1rem; margin-bottom: 8px; color: #00d4ff; }
.dimension .current { font-size: 2rem; font-weight: 700; color: #fff; }
.dimension .target { font-size: 0.85rem; color: #888; margin-top: 4px; }
.framework { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.framework h2 { font-size: 1.5rem; margin-bottom: 24px; color: #7c3aed; }
.framework p { color: #888; margin-bottom: 24px; }
.categories { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.category { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; }
.category-name { color: #00d4ff; font-weight: 600; }
.category-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.category-example { color: #aaa; font-size: 0.75rem; margin-top: 8px; font-style: italic; }
.roadmap { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.roadmap h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.phase { margin-bottom: 20px; padding: 16px; background: #1a1a1a; border-radius: var(--radius-md); }
.phase-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.phase-name { font-weight: 600; color: #fff; }
.phase-priority { font-size: 0.75rem; padding: 24px; border-radius: var(--radius-sm); }
.priority-critical { background: #7c3aed; }
.priority-high { background: #00d4ff; color: #000; }
.priority-medium { background: #333; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Metrics</h1>
<div class="subtitle">North Star Dashboard</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Metrics</a>
<a href="#north-star">VRC</a>
<a href="#framework">Framework</a>
<a href="#roadmap">Roadmap</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>North Star Metric</h2>
<p>A single metric the entire organization can optimize towards: Verified Reality Coverage (VRC)</p>
</div>
<div class="north-star" id="north-star">
<h2>Verified Reality Coverage (VRC)</h2>
<div class="metric-value">12.5%</div>
<div class="metric-label">of observable reality represented with current, independently verified evidence</div>
<div class="targets">
<div class="target">
<div class="target-year">2026</div>
<div class="target-value">25%</div>
</div>
<div class="target">
<div class="target-year">2027</div>
<div class="target-value">50%</div>
</div>
<div class="target">
<div class="target-year">2028</div>
<div class="target-value">75%</div>
</div>
</div>
</div>
<h2>5 Breakdown Dimensions</h2>
<div class="dimensions">
<div class="dimension">
<h3> Object Coverage</h3>
<div class="current">78%</div>
<div class="target">Target: 95%</div>
</div>
<div class="dimension">
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="5" stroke="#666" stroke-width="2"/><path d="M11 11L14 14" stroke="#666" stroke-width="2" stroke-linecap="round"/></svg> Multi-source Verification</h3>
<div class="current">34%</div>
<div class="target">Target: 60%</div>
</div>
<div class="dimension">
<h3>⏱ Evidence Freshness</h3>
<div class="current">14.2d</div>
<div class="target">Target: 7d</div>
</div>
<div class="dimension">
<h3> Average Confidence</h3>
<div class="current">68</div>
<div class="target">Target: 80</div>
</div>
<div class="dimension">
<h3> Traceability</h3>
<div class="current">92%</div>
<div class="target">Target: 98%</div>
</div>
</div>
<div class="framework" id="framework">
<h2>Communication Framework</h2>
<p>Keep three types of claims separate in all external communication to avoid creating unrealistic expectations.</p>
<div class="categories">
<div class="category">
<div class="category-name"> Vision</div>
<div class="category-desc">What we aim to achieve long-term</div>
<div class="category-example">"LIFE aims to establish an open framework for Reality Intelligence."</div>
</div>
<div class="category">
<div class="category-name"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg> Architecture</div>
<div class="category-desc">How the system is designed</div>
<div class="category-example">"RIS defines objects, evidence, confidence, and interoperability."</div>
</div>
<div class="category">
<div class="category-name"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Validated Results</div>
<div class="category-desc">What we have actually demonstrated</div>
<div class="category-example">"In Pilot X, Y changes identified with Z% verification rate."</div>
</div>
</div>
</div>
<div class="roadmap" id="roadmap">
<h2>Development Roadmap</h2>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P0 — Critical</div>
<div class="phase-priority priority-critical">NOW</div>
</div>
<div>
• LIFE Technical Specification v1.0 (Q3 2026)<br>
• RIVP Pilot 1 — Infrastructure (Q3-Q4 2026)
</div>
</div>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P1 — High</div>
<div class="phase-priority priority-high">NEXT</div>
</div>
<div>
• Reference Implementation (Q4 2026)<br>
• RIS Public Specification (Q4 2026)
</div>
</div>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P2 — Medium</div>
<div class="phase-priority priority-medium">LATER</div>
</div>
<div>
• Conformance Suite (Q1 2027)<br>
• Partner SDK (Q1 2027)
</div>
</div>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P3 — Future</div>
<div class="phase-priority priority-medium">FUTURE</div>
</div>
<div>
• Marketplace & Certification (Q2 2027+)
</div>
</div>
</div>
</div>
</body>
</html>
+370
View File
@@ -0,0 +1,370 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Platform v4 - Reality Intelligence Platform</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2.5rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.platform-stack { display: flex; flex-direction: column; gap: 16px; margin-bottom: 40px; }
.level { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.level-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
.level-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; }
.level h3 { font-size: 1.25rem; }
.level p { color: #888; font-size: 0.9rem; }
.components { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-top: 16px; }
.component { background: #1a1a1a; border-radius: var(--radius-md); padding: 12px; font-size: 0.85rem; }
.component-name { color: #fff; font-weight: 600; }
.component-desc { color: #666; font-size: 0.75rem; margin-top: 4px; }
.sdk-section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.sdk-section h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.sdk-section p { color: #888; margin-bottom: 20px; }
.code-block { background: #1a1a1a; border-radius: var(--radius-md); padding: 20px; font-family: 'Monaco', monospace; font-size: 0.85rem; overflow-x: auto; }
.code-block .comment { color: #666; }
.code-block .keyword { color: #7c3aed; }
.code-block .string { color: #00d4ff; }
.object-model { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.object-model h2 { font-size: 1.5rem; margin-bottom: 24px; color: #7c3aed; }
.object-attrs { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.attr { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; }
.attr-name { color: #00d4ff; font-weight: 600; }
.attr-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.domains { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.domain { background: #1a1a2e; border: 1px solid #333; border-radius: var(--radius-md); padding: 16px; text-align: center; }
.domain:hover { border-color: #7c3aed; }
.domain-icon { font-size: 1.5rem; margin-bottom: 8px; }
.domain-name { font-size: 0.9rem; }
.domain-status { font-size: 0.75rem; color: #666; margin-top: 4px; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Platform v4</h1>
<div class="subtitle">Reality Intelligence Platform</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Plattform</a>
<a href="#stack">Stack</a>
<a href="#sdk">SDK</a>
<a href="#domains">Domäner</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Reality Intelligence Platform</h2>
<p>En AI-drivn plattform för verklighetsintelligens som andra företag kan bygga ovanpå. Kombinerar geospatial information, tidsserier, visuella observationer och öppna datakällor till en spårbar evidensmodell.</p>
</div>
<h2>4-Nivåers Plattformsarkitektur</h2>
<div class="platform-stack" id="stack">
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 4</div>
<h3>Experience Layer</h3>
</div>
</div>
<p>Det användaren faktiskt möter. Utvecklas oberoende av kärnan.</p>
<div class="components">
<div class="component">
<div class="component-name">Web Dashboard</div>
<div class="component-desc">Interaktiv webbapplikation</div>
</div>
<div class="component">
<div class="component-name">Mobile Apps</div>
<div class="component-desc">iOS & Android</div>
</div>
<div class="component">
<div class="component-name">QUIXZOOM</div>
<div class="component-desc">Crowdsourcing-plattform</div>
</div>
<div class="component">
<div class="component-name">API</div>
<div class="component-desc">REST & GraphQL</div>
</div>
<div class="component">
<div class="component-name">GIS Viewer</div>
<div class="component-desc">Geospatial visualisering</div>
</div>
<div class="component">
<div class="component-name">AI Copilot</div>
<div class="component-desc">Konversationell AI</div>
</div>
<div class="component">
<div class="component-name">Alert Center</div>
<div class="component-desc">Notifikationshub</div>
</div>
<div class="component">
<div class="component-name">Workflow Automation</div>
<div class="component-desc">No-code automation</div>
</div>
</div>
</div>
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 3</div>
<h3>Domain Modules</h3>
</div>
</div>
<p>Vertikala tillämpningar som alla använder samma kernel.</p>
<div class="components">
<div class="component">
<div class="component-name">Infrastructure Intelligence</div>
<div class="component-desc">Vägar, broar, byggnader</div>
</div>
<div class="component">
<div class="component-name">Aid Intelligence</div>
<div class="component-desc">Biståndsprojekt</div>
</div>
<div class="component">
<div class="component-name">Environmental Intelligence</div>
<div class="component-desc">Miljö och klimat</div>
</div>
<div class="component">
<div class="component-name">Insurance Intelligence</div>
<div class="component-desc">Riskbedömning</div>
</div>
<div class="component">
<div class="component-name">City Intelligence</div>
<div class="component-desc">Stadsutveckling</div>
</div>
<div class="component">
<div class="component-name">Agriculture Intelligence</div>
<div class="component-desc">Jordbruk</div>
</div>
</div>
</div>
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 2</div>
<h3>Intelligence Runtime</h3>
</div>
</div>
<p>LIFE:s "kernel" - AI-operativsystemet.</p>
<div class="components">
<div class="component">
<div class="component-name">Acquisition Engine</div>
<div class="component-desc">Datainsamling</div>
</div>
<div class="component">
<div class="component-name">Normalization Engine</div>
<div class="component-desc">Standardisering</div>
</div>
<div class="component">
<div class="component-name">Evidence Engine</div>
<div class="component-desc">Evidenshantering</div>
</div>
<div class="component">
<div class="component-name">Context Engine</div>
<div class="component-desc">Kontextuell förståelse</div>
</div>
<div class="component">
<div class="component-name">Intelligence Engine</div>
<div class="component-desc">Analys och insikter</div>
</div>
<div class="component">
<div class="component-name">Prediction Engine</div>
<div class="component-desc">Prediktiv analys</div>
</div>
<div class="component">
<div class="component-name">Decision Engine</div>
<div class="component-desc">Rekommendationer</div>
</div>
<div class="component">
<div class="component-name">Learning Engine</div>
<div class="component-desc">Självförbättring</div>
</div>
</div>
</div>
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 1</div>
<h3>Foundation</h3>
</div>
</div>
<p>Teknisk kärna - abstraherad från alla vertikaler.</p>
<div class="components">
<div class="component">
<div class="component-name">Identity & Access</div>
<div class="component-desc">Autentisering</div>
</div>
<div class="component">
<div class="component-name">Event Bus</div>
<div class="component-desc">Asynkron kommunikation</div>
</div>
<div class="component">
<div class="component-name">Knowledge Graph DB</div>
<div class="component-desc">Grafbaserad lagring</div>
</div>
<div class="component">
<div class="component-name">Vector Database</div>
<div class="component-desc">Semantisk sökning</div>
</div>
<div class="component">
<div class="component-name">Time Series DB</div>
<div class="component-desc">Temporal data</div>
</div>
<div class="component">
<div class="component-name">Model Registry</div>
<div class="component-desc">AI-modellhantering</div>
</div>
</div>
</div>
</div>
<div class="sdk-section" id="sdk">
<h2>LIFE SDK</h2>
<p>Bygg egna moduler ovanpå LIFE-plattformen. Externa utvecklare och partners kan skapa egna vertikaler utan att bygga hela infrastrukturen.</p>
<div class="code-block">
<span class="comment"># Exempel: Bygg en custom modul</span>
<span class="keyword">from</span> life <span class="keyword">import</span> Client, Module
<span class="comment"># Initiera LIFE-klient</span>
client = Client(api_key=<span class="string">"your-key"</span>)
<span class="comment"># Definiera modul</span>
<span class="keyword">class</span> <span class="string">MyModule</span>(Module):
<span class="keyword">def</span> <span class="string">analyze</span>(self, project_id):
<span class="comment"># Använd LIFE:s Intelligence Runtime</span>
evidence = client.get_evidence(project_id)
insights = client.generate_insights(evidence)
<span class="keyword">return</span> insights
<span class="comment"># Deploya modulen</span>
module = MyModule()
client.deploy(module)
</div>
<p>SDK:er tillgängliga för: Python, JavaScript, Java, Go, Rust</p>
</div>
<div class="object-model">
<h2>LIFE Object Model</h2>
<p>En enhetlig objektsmodell där allt representeras med samma grundstruktur. En väg, en bro, ett sjukhus, ett biståndsprojekt eller ett träd är olika instanser av samma modell.</p>
<div class="object-attrs">
<div class="attr">
<div class="attr-name">Identity</div>
<div class="attr-desc">UUID, typ, namn, externa ID</div>
</div>
<div class="attr">
<div class="attr-name">Geometry</div>
<div class="attr-desc">Punkt, polygon, bounding box</div>
</div>
<div class="attr">
<div class="attr-name">Time</div>
<div class="attr-desc">Skapad, uppdaterad, giltighet</div>
</div>
<div class="attr">
<div class="attr-name">Evidence</div>
<div class="attr-desc">Observationer, källor, konfidens</div>
</div>
<div class="attr">
<div class="attr-name">State</div>
<div class="attr-desc">Status, framsteg, hälsa</div>
</div>
<div class="attr">
<div class="attr-name">Relationships</div>
<div class="attr-desc">Förälder, barn, relaterade</div>
</div>
<div class="attr">
<div class="attr-name">History</div>
<div class="attr-desc">Händelser, versioner, snapshots</div>
</div>
<div class="attr">
<div class="attr-name">Predictions</div>
<div class="attr-desc">Prognoser, scenarier, risker</div>
</div>
<div class="attr">
<div class="attr-name">Actions</div>
<div class="attr-desc">Rekommenderade, tillgängliga</div>
</div>
</div>
</div>
<h2>10+ Domäner</h2>
<p>LIFE är en generell plattform. Bistånd är en tillämpning, inte identitet.</p>
<div class="domains" id="domains">
<div class="domain">
<div class="domain-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg></div>
<div class="domain-name">Infrastructure</div>
<div class="domain-status">Tillgänglig</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Aid</div>
<div class="domain-status">Tillgänglig</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Environmental</div>
<div class="domain-status">Beta</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Insurance</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">City</div>
<div class="domain-status">Beta</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Agriculture</div>
<div class="domain-status">Beta</div>
</div>
<div class="domain">
<div class="domain-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg></div>
<div class="domain-name">Energy</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Supply Chain</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Security</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H7M6 8H7M6 11H7M9 5H10M9 8H10M9 11H10" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg></div>
<div class="domain-name">Property</div>
<div class="domain-status">Utveckling</div>
</div>
</div>
</div>
</body>
</html>
+217
View File
@@ -0,0 +1,217 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE — Reality Intelligence Platform</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2.5rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto 24px; }
.hero .tagline { font-size: 1rem; color: #00d4ff; font-weight: 600; }
.vision { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; text-align: center; }
.vision h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.vision p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; line-height: 1.8; }
.evolution { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 16px; margin-bottom: 40px; }
.evo { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 12px; text-align: center; }
.evo-version { font-size: 1.1rem; font-weight: 700; color: #00d4ff; }
.evo-name { font-size: 0.75rem; color: #aaa; }
.components { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 16px; margin-bottom: 40px; }
.component { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.component h3 { font-size: 1.1rem; margin-bottom: 12px; color: #00d4ff; }
.component p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.component-items { list-style: none; }
.component-items li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.component-items li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.separation { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.separation h2 { font-size: 1.5rem; margin-bottom: 24px; color: #7c3aed; }
.separation p { color: #888; margin-bottom: 24px; }
.entities { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.entity { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; }
.entity-name { color: #00d4ff; font-weight: 600; }
.entity-type { color: #888; font-size: 0.8rem; }
.entity-desc { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.cta { text-align: center; padding: 24px; background: linear-gradient(180deg, #1a1a2e 0%, #0a0a0a 100%); border-radius: var(--radius-lg); }
.cta h2 { font-size: 2rem; margin-bottom: 24px; color: #fff; }
.cta p { font-size: 1rem; color: #aaa; margin-bottom: 24px; }
.cta-button { display: inline-block; background: linear-gradient(90deg, #00d4ff, #7c3aed); color: #fff; padding: 24px; border-radius: var(--radius-md); text-decoration: none; font-weight: 600; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE</h1>
<div class="subtitle">Reality Intelligence Platform</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Product</a>
<a href="#vision">Vision</a>
<a href="#components">Components</a>
<a href="#ecosystem">Ecosystem</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Reality Intelligence Platform</h2>
<p>Landvex develops LIFE, a Reality Intelligence Platform and reference implementation of the Reality Intelligence Standard (RIS). Through a unified information model, traceable evidence, and explainable analysis, LIFE enables organizations to collect, verify, share, and use observations from the physical world in a consistent and interoperable way across domains.</p>
<div class="tagline">From observable signals to traceable evidence, explainable analysis, and decision support.</div>
</div>
<div class="vision" id="vision">
<h2>Vision</h2>
<p>LIFE aims to establish an open framework and common standards for Reality Intelligence, similar to how open standards have enabled interoperability in other technology areas. By combining geospatial data, field observations, open data sources, and AI, LIFE transforms observable signals from the physical world into traceable evidence.</p>
</div>
<h2>Evolution</h2>
<div class="evolution">
<div class="evo">
<div class="evo-version">v1</div>
<div class="evo-name">Aid Intelligence</div>
</div>
<div class="evo">
<div class="evo-version">v2</div>
<div class="evo-name">Multi-signal</div>
</div>
<div class="evo">
<div class="evo-version">v3</div>
<div class="evo-name">Core Architecture</div>
</div>
<div class="evo">
<div class="evo-version">v4</div>
<div class="evo-name">Platform</div>
</div>
<div class="evo">
<div class="evo-version">v5</div>
<div class="evo-name">Enterprise</div>
</div>
<div class="evo">
<div class="evo-version">v6</div>
<div class="evo-name">Standard</div>
</div>
<div class="evo">
<div class="evo-version">v7</div>
<div class="evo-name">Ecosystem</div>
</div>
</div>
<h2>Key Components</h2>
<div class="components" id="components">
<div class="component">
<h3> Reality Intelligence</h3>
<p>Analyzes the physical world, not just text and documents</p>
<ul class="component-items">
<li>Geospatial data fusion</li>
<li>Field observations</li>
<li>Visual data analysis</li>
<li>Time-series monitoring</li>
</ul>
</div>
<div class="component">
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H10M6 8H10M6 11H8" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg> Evidence Before Opinion</h3>
<p>Starts with observations, not conclusions</p>
<ul class="component-items">
<li>Traceable evidence chains</li>
<li>Source attribution</li>
<li>Confidence scoring</li>
<li>Contradiction detection</li>
</ul>
</div>
<div class="component">
<h3> Multi-source Fusion</h3>
<p>Combines satellite, field, open data, and AI</p>
<ul class="component-items">
<li>Satellite imagery (Sentinel-2, etc.)</li>
<li>QUIXZOOM crowdsourcing</li>
<li>IoT sensors</li>
<li>Official reports</li>
</ul>
</div>
<div class="component">
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="5" stroke="#666" stroke-width="2"/><path d="M11 11L14 14" stroke="#666" stroke-width="2" stroke-linecap="round"/></svg> Explainability</h3>
<p>Every insight is explainable and auditable</p>
<ul class="component-items">
<li>Decision lineage</li>
<li>Confidence breakdown</li>
<li>Source transparency</li>
<li>Hypothesis tracking</li>
</ul>
</div>
<div class="component">
<h3> Open Standards (RIS)</h3>
<p>Six open standards for Reality Intelligence</p>
<ul class="component-items">
<li>RIS-001: Reality Object Standard</li>
<li>RIS-002: Evidence Standard</li>
<li>RIS-003: Confidence Standard</li>
<li>RIS-004: Reality Exchange Protocol</li>
<li>RIS-005: Decision Standard</li>
<li>RIS-006: Learning Standard</li>
</ul>
</div>
<div class="component">
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2L10 8L14 9L8 14L6 8L2 7L8 2Z" fill="#666"/></svg> Reference Implementation</h3>
<p>Open source implementation of RIS</p>
<ul class="component-items">
<li>LIFE Server (Python/FastAPI)</li>
<li>LIFE Client (React/TypeScript)</li>
<li>SDK: Python, JS, Java, Go, Rust</li>
<li>Example data and APIs</li>
</ul>
</div>
</div>
<div class="separation" id="ecosystem">
<h2>Strategic Separation</h2>
<p>Three distinct layers, common in successful ecosystems: the standard can be open, while the reference implementation and commercial extensions continue to be developed by the company.</p>
<div class="entities">
<div class="entity">
<div class="entity-name">RIS</div>
<div class="entity-type">Open Standard</div>
<div class="entity-desc">The open specification. Community-governed. CC BY 4.0. Free to use.</div>
</div>
<div class="entity">
<div class="entity-name">LIFE</div>
<div class="entity-type">Reference Implementation</div>
<div class="entity-desc">Reference implementation of the standard. Open source. Apache 2.0. Free to use.</div>
</div>
<div class="entity">
<div class="entity-name">Landvex</div>
<div class="entity-type">Commercial Company</div>
<div class="entity-desc">The company that develops and commercializes LIFE. Proprietary services. Paid offerings.</div>
</div>
</div>
</div>
<div class="cta">
<h2>Build on LIFE</h2>
<p>Join the Reality Intelligence ecosystem. Build custom modules, integrate your data, or deploy your own LIFE instance.</p>
<a href="https://docs.life.ai" class="cta-button">Get Started →</a>
</div>
</div>
</body>
</html>
+224
View File
@@ -0,0 +1,224 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Standard v6 - Reality Intelligence Standard</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.standards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 40px; }
.standard { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.standard-id { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.standard h3 { font-size: 1.1rem; margin-bottom: 12px; }
.standard p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.standard-attrs { list-style: none; }
.standard-attrs li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.standard-attrs li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.ontology { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.ontology h2 { font-size: 1.5rem; margin-bottom: 24px; color: #7c3aed; }
.ontology-levels { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.level { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; }
.level-name { color: #00d4ff; font-weight: 600; }
.level-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.level-concepts { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.product-def { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; text-align: center; }
.product-def h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.product-def p { font-size: 1.1rem; color: #aaa; max-width: 700px; margin: 0 auto; line-height: 1.8; }
.evolution { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px; margin-bottom: 40px; }
.evo { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 12px; text-align: center; }
.evo-version { font-size: 1.1rem; font-weight: 700; color: #00d4ff; }
.evo-name { font-size: 0.8rem; color: #aaa; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Standard v6</h1>
<div class="subtitle">Reality Intelligence Standard</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Standard</a>
<a href="#standards">RIS</a>
<a href="#ontology">Ontologi</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Reality Intelligence Standard</h2>
<p>LIFE är inte bara programvara. Det definierar HUR verklighetsintelligens representeras, valideras, utbyts och används — oberoende av tillämpning.</p>
</div>
<div class="product-def">
<h2>Produktdefinition v6</h2>
<p>"LIFE är ett AI-drivet operativsystem och en öppen standard för Reality Intelligence. Genom att förena en gemensam informationsmodell, spårbar evidens, förklarbara analyser och kontinuerligt lärande gör LIFE det möjligt att beskriva, förstå och följa förändringar i den fysiska världen på ett konsekvent sätt över olika domäner och organisationer."</p>
</div>
<h2>Evolution av LIFE</h2>
<div class="evolution">
<div class="evo">
<div class="evo-version">v1</div>
<div class="evo-name">Aid Intelligence</div>
</div>
<div class="evo">
<div class="evo-version">v2</div>
<div class="evo-name">Multi-signal</div>
</div>
<div class="evo">
<div class="evo-version">v3</div>
<div class="evo-name">Core Architecture</div>
</div>
<div class="evo">
<div class="evo-version">v4</div>
<div class="evo-name">Platform</div>
</div>
<div class="evo">
<div class="evo-version">v5</div>
<div class="evo-name">Enterprise</div>
</div>
<div class="evo">
<div class="evo-version">v6</div>
<div class="evo-name">Standard</div>
</div>
</div>
<h2>6 Öppna Standarder (RIS)</h2>
<div class="standards" id="standards">
<div class="standard">
<div class="standard-id">RIS-001</div>
<h3>Reality Object Standard</h3>
<p>En gemensam objektsmodell för allt i den fysiska världen</p>
<ul class="standard-attrs">
<li>Identity (UUID, typ, namn)</li>
<li>Geometry (punkt, polygon, polyline)</li>
<li>Time (skapad, uppdaterad, giltighet)</li>
<li>State (status, framsteg, hälsa)</li>
<li>Evidence (observationer, källor)</li>
<li>Confidence (sammansatt säkerhet)</li>
<li>Relationships (kopplingar till andra)</li>
<li>History (händelser, versioner)</li>
<li>Predictions (framtida prognoser)</li>
<li>Actions (rekommenderade åtgärder)</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-002</div>
<h3>Evidence Standard</h3>
<p>All evidens representeras likadant oavsett källa</p>
<ul class="standard-attrs">
<li>Källa (satellit, fält, rapport)</li>
<li>Tidsstämpel</li>
<li>Geografisk position</li>
<li>Metod (hur observationen gjordes)</li>
<li>Kvalitet (0-100)</li>
<li>Osäkerhet (spatial, temporal)</li>
<li>Valideringsstatus</li>
<li>Revisionshistorik</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-003</div>
<h3>Confidence Standard</h3>
<p>Alla modeller använder samma definition av säkerhet</p>
<ul class="standard-attrs">
<li>Data Confidence (tillförlitlighet)</li>
<li>Source Confidence (källkvalitet)</li>
<li>AI Confidence (modellträffsäkerhet)</li>
<li>Human Verification (mänsklig granskning)</li>
<li>Temporal Confidence (tidsrelevans)</li>
<li>Composite Confidence (sammansatt)</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-004</div>
<h3>Reality Exchange Protocol</h3>
<p>Öppet format för utbyte mellan system</p>
<ul class="standard-attrs">
<li>/objects — Fysiska objekt</li>
<li>/observations — Observationer</li>
<li>/evidence — Evidens</li>
<li>/relationships — Relationer</li>
<li>/events — Händelser</li>
<li>/hypotheses — Hypoteser</li>
<li>/predictions — Prognoser</li>
<li>/actions — Åtgärder</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-005</div>
<h3>Decision Standard</h3>
<p>Alla rekommendationer följer samma struktur</p>
<ul class="standard-attrs">
<li>Observation → vad observerats?</li>
<li>Evidence → vad stöder det?</li>
<li>Confidence → hur säker är bedömningen?</li>
<li>Hypothesis → vad förklarar det?</li>
<li>Recommended Action → vad bör göras?</li>
<li>Expected Outcome → vad förväntas?</li>
<li>Verification Plan → hur verifieras det?</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-006</div>
<h3>Learning Standard</h3>
<p>AI-modeller utvärderas mot verkliga utfall</p>
<ul class="standard-attrs">
<li>Prediction Accuracy (hur ofta korrekt?)</li>
<li>Hypothesis Validation (vilka stämde?)</li>
<li>Signal Informativeness (vilka bidrog mest?)</li>
<li>Temporal Improvement (förbättring över tid)</li>
<li>Feedback Loops (verkliga utfall matas tillbaka)</li>
</ul>
</div>
</div>
<div class="ontology" id="ontology">
<h2>Gemensam Ontologi</h2>
<p>Tre nivåer för att balansera generell kärna med domänspecifika och kundspecifika begrepp.</p>
<div class="ontology-levels">
<div class="level">
<div class="level-name">Core Ontology</div>
<div class="level-desc">Universella begrepp — FROZEN</div>
<div class="level-concepts">Object, Observation, Evidence, Relation, Event, Hypothesis, Prediction, Action, Confidence, Time, Space, Agent</div>
</div>
<div class="level">
<div class="level-name">Domain Ontologies</div>
<div class="level-desc">Domänspecifika — STABLE</div>
<div class="level-concepts">Infrastructure: Road, Bridge, Building<br>Aid: Project, Beneficiary, Milestone<br>Insurance: Policy, Claim, RiskFactor<br>Environment: Ecosystem, PollutionLevel</div>
</div>
<div class="level">
<div class="level-name">Customer Extensions</div>
<div class="level-desc">Kundspecifika — FLEXIBLE</div>
<div class="level-concepts">Municipality: SnowRemovalRoute<br>Company: CustomAssetType<br>Any customer-defined concept</div>
</div>
</div>
</div>
</div>
</body>
</html>
+268
View File
@@ -0,0 +1,268 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex LIFE v2 - Operativ Intelligensmotor</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #0a0a0a; color: #e0e0e0; line-height: 1.6; }
.header { background: #111; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #fff; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #111; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #111; border-radius: var(--radius-md); padding: 32px; margin-bottom: 32px; border-left: 4px solid #00d4ff; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 24px; color: #fff; }
.philosophy p { color: #aaa; margin-bottom: 12px; }
.process { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
.process-step { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; text-align: center; }
.process-step .number { font-size: 1.5rem; font-weight: 700; color: #00d4ff; }
.process-step .name { font-size: 0.9rem; color: #fff; margin-top: 8px; }
.process-step .desc { font-size: 0.75rem; color: #666; margin-top: 4px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.stat-card { background: #111; border-radius: var(--radius-md); padding: 24px; border: 1px solid #333; }
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #fff; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #00d4ff; }
.component-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 32px; }
.component-card { background: #111; border-radius: var(--radius-md); padding: 24px; border: 1px solid #333; }
.component-card h3 { font-size: 1rem; margin-bottom: 12px; color: #00d4ff; display: flex; align-items: center; gap: 16px; }
.component-card p { font-size: 0.85rem; color: #aaa; margin-bottom: 8px; }
.component-card .stats { font-size: 0.8rem; color: #666; }
.section { background: #111; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; border: 1px solid #333; }
.section h2 { font-size: 1.1rem; margin-bottom: 24px; color: #fff; }
.hypothesis-card { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; border-left: 3px solid #00d4ff; }
.hypothesis-card h4 { font-size: 0.95rem; margin-bottom: 8px; color: #fff; }
.hypothesis-card p { font-size: 0.85rem; color: #aaa; }
.hypothesis-card .confidence { font-size: 0.8rem; color: #00d4ff; margin-top: 8px; }
.dna-bar { background: #1a1a1a; border-radius: var(--radius-sm); height: 24px; overflow: hidden; margin-top: 8px; display: flex; }
.dna-bar .segment { height: 100%; display: flex; align-items: center; justify-content: center; font-size: 0.7rem; color: #fff; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex LIFE v2</h1>
<div class="subtitle">Operativ Intelligensmotor - 7 Kärnkomponenter</div>
</div>
<div>
<div>Komponenter</div>
<div>7/7</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#components">Komponenter</a>
<a href="#hypotheses">Hypoteser</a>
<a href="#dna">Reality DNA</a>
</div>
<div class="main">
<div class="philosophy">
<h2>Evidence Before Opinion</h2>
<p>Systemet börjar aldrig med en slutsats och letar stöd för den. Istället bygger varje analys från observerbara signaler uppåt.</p>
<div class="process">
<div class="process-step">
<div class="number">1</div>
<div class="name">Gather Facts</div>
<div class="desc">Samla observerbara signaler</div>
</div>
<div class="process-step">
<div class="number">2</div>
<div class="name">Weigh Sources</div>
<div class="desc">Värdera oberoende källor</div>
</div>
<div class="process-step">
<div class="number">3</div>
<div class="name">Identify Patterns</div>
<div class="desc">Identifiera mönster</div>
</div>
<div class="process-step">
<div class="number">4</div>
<div class="name">Generate Hypotheses</div>
<div class="desc">Formulera hypoteser</div>
</div>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>Evidence Graph Noder</h3>
<div class="value">125K</div>
<div class="change positive">+450K edges</div>
</div>
<div class="stat-card">
<h3>Tracked Observations</h3>
<div class="value">45K</div>
<div class="change positive">Med full lineage</div>
</div>
<div class="stat-card">
<h3>Contradictions</h3>
<div class="value">1,247</div>
<div class="change positive">AI-träningsdata</div>
</div>
<div class="stat-card">
<h3>Hypoteser</h3>
<div class="value">3,400</div>
<div class="change positive">Rangordnade</div>
</div>
<div class="stat-card">
<h3>Reality DNA Profiler</h3>
<div class="value">1,250</div>
<div class="change">Projekt profilerade</div>
</div>
<div class="stat-card">
<h3>Memory Storage</h3>
<div class="value">2.4 TB</div>
<div class="change">Permanent</div>
</div>
</div>
<div class="component-grid" id="components">
<div class="component-card">
<h3> Evidence Graph (EG)</h3>
<p>Hierarkisk graf där varje observation är en spårbar nod</p>
<p>Observation → Object → Project → Programme → Organisation → Region → Country</p>
<div class="stats">125,000 noder | 450,000 edges</div>
</div>
<div class="component-card">
<h3> Evidence Lineage</h3>
<p>Komplett ursprung för varje datapunkt</p>
<p>Source → Collected → Validated → Cross-validated → AI confidence → Human verification</p>
<div class="stats">45,000 observationer spårade</div>
</div>
<div class="component-card">
<h3>⏰ Temporal Reality Engine</h3>
<p>Tidsmaskin för att se hur verkligheten förändras</p>
<p>Vad såg området ut för 6 månader sedan? Vad har förändrats? Hur snabbt?</p>
<div class="stats">3 års historik | 8,900 förändringar</div>
</div>
<div class="component-card">
<h3><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> Contradiction Knowledge Base</h4>
<p>Alla avvikelser lagras för AI-träning</p>
<p>Efter några år: hundratusentals verkliga exempel</p>
<div class="stats">1,247 avvikelser | 6 kategorier</div>
</div>
<div class="component-card">
<h3> Reality DNA</h3>
<p>Projektets fingeravtryck för benchmarking</p>
<p>9 dimensioner: Activity, Maintenance, Infrastructure, Community Usage, Traffic, Economic Activity, Environmental Status, Safety, Operational Continuity</p>
<div class="stats">1,250 profiler | Jämförbara</div>
</div>
<div class="component-card">
<h3> Reality Memory</h3>
<p>LIFE kastar aldrig bort något</p>
<p>Varje observation, AI-bedömning och förändring sparas permanent</p>
<div class="stats">2.4 TB | Full reproducerbarhet</div>
</div>
<div class="component-card">
<h3> Reality Hypothesis Engine</h3>
<p>Inte "Det här är orsaken" utan "Här är möjliga förklaringar..."</p>
<p>Rangordnade efter hur väl de stöds av observerbara data</p>
<div class="stats">3,400 hypoteser | Med osäkerhetsintervall</div>
</div>
</div>
<div class="section" id="hypotheses">
<h2>Reality Hypothesis Engine - Exempel</h2>
<p>Observerat fenomen: Construction progress slower than reported (85% observed vs 95% reported)</p>
<div class="hypothesis-card">
<h4>#1 Interior work behind schedule while exterior nearly complete</h4>
<p>Field observations show exterior walls and roof complete. Windows visible but interior not accessible. Satellite cannot detect interior progress.</p>
<div class="confidence">Confidence: 78% | Support: Strong | Action: Request interior photos</div>
</div>
<div class="hypothesis-card">
<h4>#2 Flooding in June caused 2-week delay</h4>
<p>Satellite shows flooding June 15. Weather data confirms 120% average rainfall. Field observations show reduced activity June 15-30.</p>
<div class="confidence">Confidence: 72% | Support: Moderate | Action: Verify revised timeline</div>
</div>
<div class="hypothesis-card">
<h4>#3 Material supply disruption affected interior work</h4>
<p>Procurement data shows delayed deliveries. Some materials visible on site but not installed.</p>
<div class="confidence">Confidence: 55% | Support: Weak | Action: Check supplier records</div>
</div>
<div class="hypothesis-card">
<h4>#4 Reporting methodology differs from observation methodology</h4>
<p>Official report may count 'started' as 'complete'. Different measurement standards possible.</p>
<div class="confidence">Confidence: 45% | Support: Speculative | Action: Review reporting methodology</div>
</div>
</div>
<div class="section" id="dna">
<h2>Reality DNA - Projektets Fingeravtryck</h2>
<p>9-dimensionell profil som kan jämföras med liknande projekt</p>
<div>
<div>
<span>Activity</span>
<span>78%</span>
</div>
<div class="dna-bar">
<div class="segment">78%</div>
</div>
</div>
<div>
<div>
<span>Infrastructure</span>
<span>82%</span>
</div>
<div class="dna-bar">
<div class="segment">82%</div>
</div>
</div>
<div>
<div>
<span>Safety</span>
<span>80%</span>
</div>
<div class="dna-bar">
<div class="segment">80%</div>
</div>
</div>
<div>
<div>
<span>Community Usage</span>
<span>70%</span>
</div>
<div class="dna-bar">
<div class="segment">70%</div>
</div>
</div>
<div>
<div>
<span>Maintenance</span>
<span>65%</span>
</div>
<div class="dna-bar">
<div class="segment">65%</div>
</div>
</div>
</div>
</div>
</body>
</html>
+227
View File
@@ -0,0 +1,227 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Validation - Reality Intelligence Validation Program</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #666; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 24px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: var(--radius-lg); margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 24px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.phases { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 40px; }
.phase { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; }
.phase-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.phase h3 { font-size: 1.1rem; margin-bottom: 12px; }
.phase p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.phase-objs { list-style: none; }
.phase-objs li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.phase-objs li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.metrics { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.metrics h2 { font-size: 1.5rem; margin-bottom: 24px; color: #7c3aed; }
.metrics p { color: #888; margin-bottom: 24px; }
.metric-dims { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.dim { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; }
.dim-name { color: #00d4ff; font-weight: 600; }
.dim-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.dim-kpis { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.spec { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 40px; }
.spec h2 { font-size: 1.5rem; margin-bottom: 24px; color: #00d4ff; }
.spec p { color: #888; margin-bottom: 24px; }
.spec-sections { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.spec-section { background: #1a1a1a; border-radius: var(--radius-md); padding: 12px; }
.spec-num { color: #00d4ff; font-size: 0.75rem; }
.spec-title { color: #fff; font-size: 0.85rem; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Validation</h1>
<div class="subtitle">Reality Intelligence Validation Program</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Validation</a>
<a href="#phases">Faser</a>
<a href="#metrics">KPI:er</a>
</div>
<div class="main">
<div class="lv-hero">
<h2>Reality Intelligence Validation Program</h2>
<p>Många tekniska projekt fortsätter bygga lager utan att validera dem. RIVP säkerställer att varje fas bevisar verkligt värde innan vidare utveckling.</p>
</div>
<h2>4 Faser</h2>
<div class="phases" id="phases">
<div class="phase">
<div class="phase-number">Fas 1</div>
<h3> Infrastruktur</h3>
<p>6 månader — Vägar, broar, arbeten</p>
<ul class="phase-objs">
<li>Hitta vägskador (>80% precision)</li>
<li>Följa vägarbeten (±10%)</li>
<li>Upptäcka förändringar (<48h)</li>
<li>Verifiera reparationer (>90%)</li>
</ul>
</div>
<div class="phase">
<div class="phase-number">Fas 2</div>
<h3> Kommun</h3>
<p>6 månader — Parker, belysning, skyltning</p>
<ul class="phase-objs">
<li>Följa parker (veckovis)</li>
<li>Gatubelysning (>95% täckning)</li>
<li>Skyltning (±5% inventering)</li>
<li>Avfall (90% illegala platser)</li>
<li>Vinterunderhåll (<4h)</li>
</ul>
</div>
<div class="phase">
<div class="phase-number">Fas 3</div>
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H7M6 8H7M6 11H7M9 5H10M9 8H10M9 11H10" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg> Fastigheter</h3>
<p>6 månader — Byggnader, skador, underhåll</p>
<ul class="phase-objs">
<li>Följa byggnader (månadsvis)</li>
<li>Upptäcka skador (>75% precision)</li>
<li>Följa underhåll (100% spårbarhet)</li>
<li>Analysera risk (±1 nivå)</li>
</ul>
</div>
<div class="phase">
<div class="phase-number">Fas 4</div>
<h3> Bistånd</h3>
<p>12 månader — Projekt, observationer, verifiering</p>
<ul class="phase-objs">
<li>Följa projekt över tid (±15%)</li>
<li>Samla oberoende observationer (>50%)</li>
<li>Kombinera flera källor (>3/objekt)</li>
<li>Identifiera verifieringsbehov (>80%)</li>
</ul>
</div>
</div>
<div class="metrics" id="metrics">
<h2>6 Dimensioner för Framgång</h2>
<p>Fokus på faktisk användning, inte antal moduler.</p>
<div class="metric-dims">
<div class="dim">
<div class="dim-name"> Datatäckning</div>
<div class="dim-desc">Andel objekt med aktuell data</div>
<div class="dim-kpis">Object Coverage >95%<br>Geographic Coverage >90%</div>
</div>
<div class="dim">
<div class="dim-name">⏱ Aktualitet</div>
<div class="dim-desc">Tid från förändring till observation</div>
<div class="dim-kpis">Detection Time <48h<br>Alert Latency <1h</div>
</div>
<div class="dim">
<div class="dim-name"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="5" stroke="#666" stroke-width="2"/><path d="M11 11L14 14" stroke="#666" stroke-width="2" stroke-linecap="round"/></svg> Evidenskvalitet</div>
<div class="dim-desc">Konfidens och verifiering</div>
<div class="dim-kpis">Avg Confidence >75<br>Verification Rate >30%</div>
</div>
<div class="dim">
<div class="dim-name"> Analyskvalitet</div>
<div class="dim-desc">Användbarhet och korrekthet</div>
<div class="dim-kpis">User Satisfaction >80%<br>Decision Adoption >60%</div>
</div>
<div class="dim">
<div class="dim-name"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Adoption</div>
<div class="dim-desc">Externa implementationer</div>
<div class="dim-kpis">External Impl >10<br>Partner Integrations >20</div>
</div>
<div class="dim">
<div class="dim-name"> Interoperabilitet</div>
<div class="dim-desc">System som utbyter data</div>
<div class="dim-kpis">RIS Compatible >15<br>Data Exchange >1TB/mån</div>
</div>
</div>
</div>
<div class="spec">
<h2>Teknisk Specifikation (Nästa Leverans)</h2>
<p>Efter validering: RFC/ISO-liknande standard som blir referens för utvecklare, partners och kunder.</p>
<div class="spec-sections">
<div class="spec-section">
<div class="spec-num">1</div>
<div class="spec-title">Executive Summary</div>
</div>
<div class="spec-section">
<div class="spec-num">2</div>
<div class="spec-title">Vision and Principles</div>
</div>
<div class="spec-section">
<div class="spec-num">3</div>
<div class="spec-title">Architecture</div>
</div>
<div class="spec-section">
<div class="spec-num">4</div>
<div class="spec-title">Ontology</div>
</div>
<div class="spec-section">
<div class="spec-num">5</div>
<div class="spec-title">RIS Specifications</div>
</div>
<div class="spec-section">
<div class="spec-num">6</div>
<div class="spec-title">Object Model</div>
</div>
<div class="spec-section">
<div class="spec-num">7</div>
<div class="spec-title">Evidence Model</div>
</div>
<div class="spec-section">
<div class="spec-num">8</div>
<div class="spec-title">API Contracts</div>
</div>
<div class="spec-section">
<div class="spec-num">9</div>
<div class="spec-title">Security Model</div>
</div>
<div class="spec-section">
<div class="spec-num">10</div>
<div class="spec-title">Versioning Strategy</div>
</div>
<div class="spec-section">
<div class="spec-num">11</div>
<div class="spec-title">Governance</div>
</div>
<div class="spec-section">
<div class="spec-num">12</div>
<div class="spec-title">Reference Implementation</div>
</div>
<div class="spec-section">
<div class="spec-num">13</div>
<div class="spec-title">Conformance Requirements</div>
</div>
<div class="spec-section">
<div class="spec-num">14</div>
<div class="spec-title">Examples and Test Cases</div>
</div>
</div>
</div>
</div>
</body>
</html>
+140
View File
@@ -0,0 +1,140 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Weather Intelligence</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; }
.metric-value { font-size: 2.5rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; margin-top: 4px; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 24px; color: #00d4ff; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; padding: 12px; color: #888; font-size: 0.8rem; }
td { padding: 12px; border-top: 1px solid #222; font-size: 0.9rem; }
.status { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.75rem; }
.status-normal { background: #1a3a1a; color: #4ade80; }
.status-warning { background: #3a3a1a; color: #facc15; }
.status-critical { background: #3a1a1a; color: #f87171; }
</style>
</head>
<body>
<div class="header">
<h1>LIFE Weather Intelligence</h1>
</div>
<div class="main">
<div class="metrics">
<div class="metric">
<div class="metric-value" id="total-roads"></div>
<div class="metric-label">Roads Monitored</div>
</div>
<div class="metric">
<div class="metric-value" id="active-risks"></div>
<div class="metric-label">Active Risks</div>
</div>
<div class="metric">
<div class="metric-value" id="active-events"></div>
<div class="metric-label">Active Events</div>
</div>
<div class="metric">
<div class="metric-value" id="missions-waiting"></div>
<div class="metric-label">Missions Waiting</div>
</div>
<div class="metric">
<div class="metric-value" id="reality-latency"></div>
<div class="metric-label">Reality Latency (min)</div>
</div>
</div>
<div class="section">
<h2>Latest Weather</h2>
<table>
<thead>
<tr>
<th>Road</th>
<th>Temperature</th>
<th>Precipitation</th>
<th>Wind</th>
<th>Risk</th>
</tr>
</thead>
<tbody id="weather-table">
<tr><td colspan="5">Loading...</td></tr>
</tbody>
</table>
</div>
<div class="section">
<h2>Reality DNA</h2>
<table>
<thead>
<tr>
<th>Road ID</th>
<th>Type</th>
<th>Observations</th>
<th>Last Update</th>
<th>Status</th>
</tr>
</thead>
<tbody id="dna-table">
<tr><td colspan="5">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
// Simulera data för nu
const roads = [
{ id: 1, name: "E4", type: "motorway", temp: 22, precip: 3.1, wind: 5.0, risk: "normal" },
{ id: 2, name: "E6", type: "motorway", temp: 21, precip: 2.5, wind: 4.5, risk: "normal" },
{ id: 3, name: "E18", type: "motorway", temp: 20, precip: 1.0, wind: 3.0, risk: "normal" },
];
function updateDashboard() {
document.getElementById('total-roads').textContent = '181';
document.getElementById('active-risks').textContent = '0';
document.getElementById('active-events').textContent = '0';
document.getElementById('missions-waiting').textContent = '0';
document.getElementById('reality-latency').textContent = '60';
const tbody = document.getElementById('weather-table');
tbody.innerHTML = roads.map(r => `
<tr>
<td>${r.name}</td>
<td>${r.temp}°C</td>
<td>${r.precip}mm</td>
<td>${r.wind} m/s</td>
<td><span class="status status-${r.risk}">${r.risk.toUpperCase()}</span></td>
</tr>
`).join('');
const dnaBody = document.getElementById('dna-table');
dnaBody.innerHTML = roads.map(r => `
<tr>
<td>${r.id}</td>
<td>${r.type}</td>
<td>3</td>
<td>2026-07-04 15:32</td>
<td><span class="status status-normal">NORMAL</span></td>
</tr>
`).join('');
}
updateDashboard();
</script>
</body>
</html>
+289
View File
@@ -0,0 +1,289 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Intelligence Fusion Engine (LIFE)</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #0f172a; color: #e2e8f0; line-height: 1.6; }
.header { background: #1e293b; border-bottom: 1px solid #334155; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #f8fafc; }
.header .subtitle { color: #94a3b8; font-size: 0.85rem; }
.nav { background: #1e293b; border-bottom: 1px solid #334155; padding: 0 40px; display: flex; gap: 16px; }
.nav a { color: #94a3b8; text-decoration: none; padding: 24px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #38bdf8; border-bottom-color: #38bdf8; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #1e293b; border-radius: var(--radius-md); padding: 32px; margin-bottom: 32px; border-left: 4px solid #38bdf8; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 24px; color: #f8fafc; }
.philosophy p { color: #cbd5e1; margin-bottom: 12px; }
.philosophy .process { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
.process-step { background: #334155; border-radius: var(--radius-md); padding: 16px; text-align: center; }
.process-step .number { font-size: 1.5rem; font-weight: 700; color: #38bdf8; }
.process-step .name { font-size: 0.9rem; color: #f8fafc; margin-top: 8px; }
.process-step .desc { font-size: 0.75rem; color: #94a3b8; margin-top: 4px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.stat-card { background: #1e293b; border-radius: var(--radius-md); padding: 24px; border: 1px solid #334155; }
.stat-card h3 { font-size: 0.75rem; color: #94a3b8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #f8fafc; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #4ade80; }
.section { background: #1e293b; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; border: 1px solid #334155; }
.section h2 { font-size: 1.1rem; margin-bottom: 24px; color: #f8fafc; }
.data-source { display: flex; align-items: center; gap: 16px; padding: 12px; background: #334155; border-radius: var(--radius-md); margin-bottom: 8px; }
.data-source .icon { width: 40px; height: 40px; background: #475569; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
.data-source .info { flex: 1; }
.data-source .info h4 { font-size: 0.9rem; color: #f8fafc; }
.data-source .info p { font-size: 0.75rem; color: #94a3b8; }
.data-source .status { font-size: 0.75rem; padding: 24px; border-radius: var(--radius-sm); }
.data-source .status.active { background: #166534; color: #4ade80; }
.event-card { background: #334155; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.event-card h4 { font-size: 0.95rem; margin-bottom: 8px; }
.event-card .meta { font-size: 0.8rem; color: #94a3b8; margin-bottom: 8px; }
.event-card .severity { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.7rem; font-weight: 600; }
.event-card .severity.high { background: #7f1d1d; color: #fca5a5; }
.event-card .severity.medium { background: #713f12; color: #fde047; }
.event-card .severity.low { background: #1e3a5f; color: #93c5fd; }
.confidence-bar { background: #334155; border-radius: var(--radius-sm); height: 8px; overflow: hidden; margin-top: 8px; }
.confidence-bar .fill { height: 100%; border-radius: var(--radius-sm); }
.confidence-bar .fill.high { background: #4ade80; }
.confidence-bar .fill.medium { background: #fbbf24; }
.confidence-bar .fill.low { background: #f87171; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.insight-card { background: #334155; border-radius: var(--radius-md); padding: 16px; margin-bottom: 12px; }
.insight-card h4 { font-size: 0.9rem; margin-bottom: 8px; color: #38bdf8; }
.insight-card p { font-size: 0.85rem; color: #cbd5e1; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex Intelligence Fusion Engine</h1>
<div class="subtitle">Continuous Multi-Source Intelligence Platform</div>
</div>
<div>
<div>Data Streams</div>
<div>45</div>
</div>
</div>
<div class="nav">
<a href="/admin/" >← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#sources">Sources</a>
<a href="#events">Events</a>
<a href="#analysis">Analysis</a>
</div>
<div class="main">
<div class="philosophy">
<h2>Evidence Before Opinion</h2>
<p>The system never starts with a conclusion and looks for support. Instead, every analysis builds from observable signals upward.</p>
<div class="process">
<div class="process-step">
<div class="number">1</div>
<div class="name">Gather Facts</div>
<div class="desc">Collect observable signals from all available sources</div>
</div>
<div class="process-step">
<div class="number">2</div>
<div class="name">Weigh Sources</div>
<div class="desc">Evaluate independent sources and their reliability</div>
</div>
<div class="process-step">
<div class="number">3</div>
<div class="name">Identify Patterns</div>
<div class="desc">Detect statistical associations and correlations</div>
</div>
<div class="process-step">
<div class="number">4</div>
<div class="name">Generate Hypotheses</div>
<div class="desc">Form cautious hypotheses about possible causes</div>
</div>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>Projects Monitored</h3>
<div class="value">1,250</div>
<div class="change positive">With context graphs</div>
</div>
<div class="stat-card">
<h3>Data Sources</h3>
<div class="value">6</div>
<div class="change">Categories active</div>
</div>
<div class="stat-card">
<h3>Events Detected (24h)</h3>
<div class="value">12</div>
<div class="change positive">Auto-detected</div>
</div>
<div class="stat-card">
<h3>Avg Confidence</h3>
<div class="value">82%</div>
<div class="change positive">Multi-source fusion</div>
</div>
<div class="stat-card">
<h3>Streams Monitored</h3>
<div class="value">45</div>
<div class="change">Continuous ingestion</div>
</div>
<div class="stat-card">
<h3>Predictions Made</h3>
<div class="value">3,400</div>
<div class="change">With uncertainty intervals</div>
</div>
</div>
<div class="section">
<h2>Continuous Data Acquisition</h2>
<div class="data-source">
<div class="icon"></div>
<div class="info">
<h4>Official Project Information</h4>
<p>Development agency portals, government databases, procurement portals, evaluation reports</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon"></div>
<div class="info">
<h4>News Intelligence</h4>
<p>International, national, regional news, RSS feeds, development and humanitarian news</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon"></div>
<div class="info">
<h4>Public Communications</h4>
<p>Press releases, official websites, social media, research publications</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon"></div>
<div class="info">
<h4>Geospatial Intelligence</h4>
<p>Satellite imagery, night lights, land cover, construction detection, environmental monitoring</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon"></div>
<div class="info">
<h4>QUIXZOOM Reality Network</h4>
<p>Field observations, photographic evidence, infrastructure inspections, community observations</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div class="info">
<h4>Open Data</h4>
<p>Population, weather, climate, health indicators, economic data, conflict datasets</p>
</div>
<div class="status active">Active</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h2>Recent Events Detected</h2>
<div class="event-card">
<h4> Severe flooding in Mogadishu region</h4>
<div class="meta">Somalia • June 15, 2026 • Natural Disaster</div>
<p>Heavy rainfall caused flooding affecting infrastructure accessibility</p>
<div>
<span class="severity high">High Severity</span>
<span>Confidence: 92%</span>
</div>
<div class="confidence-bar">
<div class="fill high"></div>
</div>
</div>
<div class="event-card">
<h4><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg> Construction delay due to seasonal rainfall</h4>
<div class="meta">Nigeria • May 20, 2026 • Construction Delay</div>
<p>Road rehabilitation delayed due to extended rainy season</p>
<div>
<span class="severity medium">Medium Severity</span>
<span>Confidence: 78%</span>
</div>
<div class="confidence-bar">
<div class="fill medium"></div>
</div>
</div>
</div>
<div class="section">
<h2>Recent Fusion Insights</h2>
<div class="insight-card">
<h4> Mogadishu Primary School</h4>
<p>Construction delay likely due to flooding + poor drainage</p>
<div>
<span>Confidence: 78% • Sources fused: 5</span>
</div>
</div>
<div class="insight-card">
<h4> Kampala Water Supply</h4>
<p>Operational sustainability high based on maintenance records + community feedback</p>
<div>
<span>Confidence: 88% • Sources fused: 6</span>
</div>
</div>
<div class="insight-card">
<h4> Accra Solar Microgrid</h4>
<p>24 months continuous operation verified across 4 independent sources</p>
<div>
<span>Confidence: 92% • Sources fused: 4</span>
</div>
</div>
</div>
</div>
<div class="section">
<h2>Multi-Signal Confidence Distribution</h2>
<div>
<div>
<div>320</div>
<div>Very High<br>(90-100%)</div>
</div>
<div>
<div>580</div>
<div>High<br>(75-89%)</div>
</div>
<div>
<div>280</div>
<div>Moderate<br>(50-74%)</div>
</div>
<div>
<div>55</div>
<div>Low<br>(25-49%)</div>
</div>
<div>
<div>15</div>
<div>Very Low<br>(0-24%)</div>
</div>
</div>
</div>
</div>
</body>
</html>
+228
View File
@@ -0,0 +1,228 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Live — Real-Time Data</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.live-indicator { display: flex; align-items: center; gap: 16px; }
.pulse { width: 8px; height: 8px; background: #4ade80; border-radius: var(--radius-full); animation: pulse 2s infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; }
.metric-value { font-size: 2.5rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; margin-top: 4px; }
.metric-change { font-size: 0.75rem; margin-top: 4px; }
.change-up { color: #4ade80; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 24px; color: #00d4ff; }
.source-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px; }
.source { background: #1a1a1a; border-radius: var(--radius-md); padding: 12px; text-align: center; }
.source-name { font-size: 0.8rem; color: #888; }
.source-value { font-size: 1.5rem; font-weight: 700; color: #fff; margin-top: 4px; }
.source-status { font-size: 0.7rem; color: #4ade80; margin-top: 4px; }
.alert { background: #1a1a1a; border-left: 3px solid #f87171; padding: 24px; margin-bottom: 8px; border-radius: 0 8px 8px 0; }
.alert-critical { border-left-color: #ef4444; }
.alert-high { border-left-color: #f87171; }
.alert-type { font-weight: 600; }
.alert-location { color: #888; font-size: 0.85rem; }
.alert-time { color: #666; font-size: 0.75rem; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; padding: 12px; color: #888; font-size: 0.8rem; }
td { padding: 12px; border-top: 1px solid #222; font-size: 0.9rem; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Live</h1>
</div>
<div class="live-indicator">
<div class="pulse"></div>
<span>LIVE DATA</span>
</div>
</div>
<div class="main">
<div class="metrics">
<div class="metric">
<div class="metric-value" id="total-roads"></div>
<div class="metric-label">Roads Monitored</div>
<div class="metric-change change-up" id="roads-change">+0 today</div>
</div>
<div class="metric">
<div class="metric-value" id="total-obs"></div>
<div class="metric-label">Total Observations</div>
<div class="metric-change change-up" id="obs-change">+0 today</div>
</div>
<div class="metric">
<div class="metric-value" id="today-obs"></div>
<div class="metric-label">Observations Today</div>
<div class="metric-change change-up">Real-time</div>
</div>
<div class="metric">
<div class="metric-value" id="last-hour"></div>
<div class="metric-label">Last Hour</div>
<div class="metric-change change-up">Active</div>
</div>
<div class="metric">
<div class="metric-value" id="latency"></div>
<div class="metric-label">Reality Latency</div>
<div class="metric-change">hours</div>
</div>
</div>
<div class="section">
<h2>Data Sources</h2>
<div class="source-grid" id="sources">
<div class="source">
<div class="source-name">Trafikverket</div>
<div class="source-value" id="src-trafikverket"></div>
<div class="source-status"> Active</div>
</div>
<div class="source">
<div class="source-name">SMHI</div>
<div class="source-value" id="src-smhi"></div>
<div class="source-status"> Active</div>
</div>
<div class="source">
<div class="source-name">Satellite</div>
<div class="source-value" id="src-satellite"></div>
<div class="source-status"> Active</div>
</div>
<div class="source">
<div class="source-name">quiXzoom</div>
<div class="source-value" id="src-quixzoom"></div>
<div class="source-status"> Active</div>
</div>
<div class="source">
<div class="source-name">Manual</div>
<div class="source-value" id="src-manual"></div>
<div class="source-status"> Active</div>
</div>
<div class="source">
<div class="source-name">Sensor</div>
<div class="source-value" id="src-sensor"></div>
<div class="source-status"> Active</div>
</div>
</div>
</div>
<div class="section">
<h2>Active Alerts</h2>
<div id="alerts">
<div>Loading alerts...</div>
</div>
</div>
<div class="section">
<h2>Recent Observations</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>Road</th>
<th>Type</th>
<th>Severity</th>
<th>Source</th>
</tr>
</thead>
<tbody id="recent-obs">
<tr><td colspan="5">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
async function loadStatus() {
try {
const response = await fetch('/api/v1/live/public/status');
const data = await response.json();
document.getElementById('total-roads').textContent = data.data_freshness.total_roads;
document.getElementById('total-obs').textContent = data.data_freshness.total_observations;
document.getElementById('today-obs').textContent = data.data_freshness.observations_today;
document.getElementById('last-hour').textContent = data.data_freshness.observations_last_hour;
document.getElementById('latency').textContent = data.data_freshness.reality_latency_hours.toFixed(1);
// Update sources
for (const [source, count] of Object.entries(data.sources)) {
const el = document.getElementById('src-' + source);
if (el) el.textContent = count;
}
} catch (e) {
console.error('Failed to load status:', e);
}
}
async function loadAlerts() {
try {
const response = await fetch('/api/v1/live/public/alerts');
const data = await response.json();
const container = document.getElementById('alerts');
if (data.alerts.length === 0) {
container.innerHTML = '<div>No active alerts</div>';
return;
}
container.innerHTML = data.alerts.slice(0, 5).map(alert => `
<div class="alert alert-${alert.severity}">
<div class="alert-type">${alert.observation_type.toUpperCase()}</div>
<div class="alert-location">${alert.road_name}${alert.county}</div>
<div class="alert-time">${alert.detected_date} • Confidence: ${(alert.confidence * 100).toFixed(0)}%</div>
</div>
`).join('');
} catch (e) {
console.error('Failed to load alerts:', e);
}
}
async function loadRecent() {
try {
const response = await fetch('/api/v1/live/public/observations/stream?limit=10');
const data = await response.json();
const tbody = document.getElementById('recent-obs');
tbody.innerHTML = data.observations.map(obs => `
<tr>
<td>${obs.detected_date}</td>
<td>${obs.road_name}</td>
<td>${obs.observation_type}</td>
<td>${obs.severity}</td>
<td>${obs.source}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load recent:', e);
}
}
// Load all data
loadStatus();
loadAlerts();
loadRecent();
// Refresh every 10 seconds
setInterval(() => {
loadStatus();
loadAlerts();
loadRecent();
}, 10000);
</script>
</body>
</html>
+184
View File
@@ -0,0 +1,184 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE — Real Data Status</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header p { color: #888; font-size: 0.9rem; }
.main { padding: 40px; max-width: 1200px; margin: 0 auto; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 24px; color: #00d4ff; }
.source { display: flex; justify-content: space-between; align-items: center; padding: 12px; border-bottom: 1px solid #222; }
.source:last-child { border-bottom: none; }
.source-name { font-weight: 600; }
.source-type { font-size: 0.8rem; padding: 24px; border-radius: var(--radius-sm); }
.type-real { background: #1a3a1a; color: #4ade80; }
.type-simulated { background: #3a1a1a; color: #f87171; }
.source-count { font-size: 1.2rem; font-weight: 700; }
.metric { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
.metric-card { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; }
.metric-value { font-size: 2rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; }
.status { display: inline-block; width: 8px; height: 8px; border-radius: var(--radius-full); margin-right: 8px; }
.status-active { background: #4ade80; }
.status-inactive { background: #f87171; }
</style>
</head>
<body>
<div class="header">
<h1>LIFE — Real Data Status</h1>
<p>Honest overview of what data is real vs simulated</p>
</div>
<div class="main">
<div class="metric">
<div class="metric-card">
<div class="metric-value" id="real-count"></div>
<div class="metric-label">Real Observations</div>
</div>
<div class="metric-card">
<div class="metric-value" id="sim-count"></div>
<div class="metric-label">Simulated Observations</div>
</div>
<div class="metric-card">
<div class="metric-value" id="real-percent"></div>
<div class="metric-label">Real Data %</div>
</div>
</div>
<div class="section">
<h2>Data Sources</h2>
<div id="sources">
<div>Loading...</div>
</div>
</div>
<div class="section">
<h2>Real Data Pipeline</h2>
<div class="source">
<div>
<div class="source-name"><span class="status status-active"></span>SMHI Weather</div>
<div>Temperature, precipitation, wind from Uppsala Flygplats</div>
</div>
<div class="source-type type-real">REAL</div>
</div>
<div class="source">
<div>
<div class="source-name"><span class="status status-inactive"></span>Trafikverket Road Conditions</div>
<div>Requires API key - not yet configured</div>
</div>
<div class="source-type type-simulated">SIMULATED</div>
</div>
<div class="source">
<div>
<div class="source-name"><span class="status status-inactive"></span>Sentinel-2 Satellite</div>
<div>Requires Copernicus account - not yet configured</div>
</div>
<div class="source-type type-simulated">SIMULATED</div>
</div>
<div class="source">
<div>
<div class="source-name"><span class="status status-inactive"></span>quiXzoom Field Data</div>
<div>No active field contributors in area</div>
</div>
<div class="source-type type-simulated">SIMULATED</div>
</div>
</div>
<div class="section">
<h2>Latest Real Data</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>Road</th>
<th>Type</th>
<th>Value</th>
</tr>
</thead>
<tbody id="latest-real">
<tr><td colspan="4">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
async function loadData() {
try {
const response = await fetch('/api/v1/live/public/status');
const data = await response.json();
const sources = data.sources;
const total = Object.values(sources).reduce((a, b) => a + b, 0);
const real = sources['smhi_real'] || 0;
const simulated = total - real;
document.getElementById('real-count').textContent = real;
document.getElementById('sim-count').textContent = simulated;
document.getElementById('real-percent').textContent = ((real / total) * 100).toFixed(1) + '%';
// Sources list
const container = document.getElementById('sources');
container.innerHTML = Object.entries(sources).map(([name, count]) => {
const isReal = name === 'smhi_real';
return `
<div class="source">
<div>
<div class="source-name">${name}</div>
</div>
<div>
<div class="source-count">${count}</div>
<div class="source-type ${isReal ? 'type-real' : 'type-simulated'}">${isReal ? 'REAL' : 'SIMULATED'}</div>
</div>
</div>
`;
}).join('');
} catch (e) {
console.error('Failed to load:', e);
}
}
async function loadLatest() {
try {
const response = await fetch('/api/v1/live/public/observations/stream?limit=10');
const data = await response.json();
const tbody = document.getElementById('latest-real');
const realObs = data.observations.filter(o => o.source === 'smhi_real');
if (realObs.length === 0) {
tbody.innerHTML = '<tr><td colspan="4">No real data yet</td></tr>';
return;
}
tbody.innerHTML = realObs.slice(0, 5).map(obs => `
<tr>
<td>${obs.detected_date}</td>
<td>${obs.road_name}</td>
<td>${obs.observation_type}</td>
<td>${obs.severity}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load latest:', e);
}
}
loadData();
loadLatest();
</script>
</body>
</html>
+195
View File
@@ -0,0 +1,195 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RIVP Pilot 1 — Live Dashboard</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .live { background: #1a3a1a; color: #4ade80; padding: 24px; border-radius: var(--radius-sm); font-size: 0.8rem; font-weight: 600; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; text-align: center; }
.metric-value { font-size: 2.5rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; margin-top: 4px; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 24px; color: #00d4ff; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; padding: 12px; color: #888; font-size: 0.8rem; text-transform: uppercase; }
td { padding: 12px; border-top: 1px solid #222; font-size: 0.9rem; }
.severity-low { color: #4ade80; }
.severity-medium { color: #fbbf24; }
.severity-high { color: #f87171; }
.severity-critical { color: #ef4444; font-weight: 600; }
.confidence-bar { background: #222; height: 8px; border-radius: var(--radius-sm); overflow: hidden; width: 100px; }
.confidence-fill { height: 100%; background: linear-gradient(90deg, #ef4444, #fbbf24, #4ade80); }
</style>
</head>
<body>
<div class="header">
<div>
<h1>RIVP Pilot 1</h1>
</div>
<div class="live"> LIVE DATA</div>
</div>
<div class="main">
<div class="metrics" id="metrics">
<div class="metric">
<div class="metric-value" id="total-roads"></div>
<div class="metric-label">Roads Monitored</div>
</div>
<div class="metric">
<div class="metric-value" id="total-obs"></div>
<div class="metric-label">Observations</div>
</div>
<div class="metric">
<div class="metric-value" id="avg-confidence"></div>
<div class="metric-label">Avg Confidence</div>
</div>
<div class="metric">
<div class="metric-value" id="verified"></div>
<div class="metric-label">Verified</div>
</div>
<div class="metric">
<div class="metric-value" id="critical"></div>
<div class="metric-label">Critical Issues</div>
</div>
</div>
<div class="section">
<h2>Recent Observations</h2>
<table>
<thead>
<tr>
<th>Road</th>
<th>County</th>
<th>Type</th>
<th>Severity</th>
<th>Confidence</th>
<th>Source</th>
<th>Date</th>
</tr>
</thead>
<tbody id="observations-table">
<tr><td colspan="7">Loading...</td></tr>
</tbody>
</table>
</div>
<div class="section">
<h2>Top Counties by Observation Count</h2>
<table>
<thead>
<tr>
<th>County</th>
<th>Roads</th>
<th>Observations</th>
</tr>
</thead>
<tbody id="counties-table">
<tr><td colspan="3">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
async function loadDashboard() {
try {
const response = await fetch('/api/v1/rivp-pilot1/public/dashboard');
const data = await response.json();
document.getElementById('total-roads').textContent = data.roads.total;
document.getElementById('total-obs').textContent = data.observations.total;
document.getElementById('avg-confidence').textContent = (data.observations.average_confidence * 100).toFixed(0) + '%';
document.getElementById('verified').textContent = data.observations.verification[1] || 0;
document.getElementById('critical').textContent = data.observations.by_severity.critical || 0;
} catch (e) {
console.error('Failed to load dashboard:', e);
}
}
async function loadObservations() {
try {
const response = await fetch('/api/v1/rivp-pilot1/public/observations');
const data = await response.json();
const tbody = document.getElementById('observations-table');
tbody.innerHTML = data.observations.slice(0, 20).map(obs => `
<tr>
<td>${obs.road_name}</td>
<td>${obs.county}</td>
<td>${obs.observation_type}</td>
<td class="severity-${obs.severity}">${obs.severity}</td>
<td>
<div class="confidence-bar">
<div class="confidence-fill"></div>
</div>
${(obs.confidence * 100).toFixed(0)}%
</td>
<td>${obs.source}</td>
<td>${obs.detected_date}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load observations:', e);
}
}
async function loadCounties() {
try {
const response = await fetch('/api/v1/rivp-pilot1/public/roads');
const data = await response.json();
// Count observations per county
const countyObs = {};
data.roads.forEach(road => {
if (!countyObs[road.county]) {
countyObs[road.county] = { roads: 0, observations: 0 };
}
countyObs[road.county].roads++;
countyObs[road.county].observations += road.observation_count;
});
const sorted = Object.entries(countyObs)
.sort((a, b) => b[1].observations - a[1].observations)
.slice(0, 10);
const tbody = document.getElementById('counties-table');
tbody.innerHTML = sorted.map(([county, stats]) => `
<tr>
<td>${county}</td>
<td>${stats.roads}</td>
<td>${stats.observations}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load counties:', e);
}
}
// Load all data
loadDashboard();
loadObservations();
loadCounties();
// Refresh every 30 seconds
setInterval(() => {
loadDashboard();
loadObservations();
}, 30000);
</script>
</body>
</html>
+132
View File
@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RIVP Pilot 1 — Road Monitoring Results</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.main { padding: 40px; max-width: 1200px; margin: 0 auto; }
.status { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.8rem; font-weight: 600; }
.status-live { background: #1a3a1a; color: #4ade80; }
.results { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 24px; }
.results h2 { font-size: 1.3rem; margin-bottom: 24px; color: #00d4ff; }
.metric-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
.metric { background: #1a1a1a; border-radius: var(--radius-md); padding: 16px; text-align: center; }
.metric-value { font-size: 2rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.8rem; color: #888; margin-top: 4px; }
.change-item { background: #1a1a1a; border-left: 3px solid #00d4ff; padding: 24px; margin-bottom: 12px; border-radius: 0 8px 8px 0; }
.change-type { font-weight: 600; color: #fff; }
.change-details { color: #888; font-size: 0.85rem; margin-top: 4px; }
.change-confidence { color: #4ade80; font-size: 0.8rem; }
.map-placeholder { background: #1a1a1a; border-radius: var(--radius-md); height: 300px; display: flex; align-items: center; justify-content: center; color: #666; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>RIVP Pilot 1 <span class="status status-live">LIVE</span></h1>
<div class="subtitle">Road Infrastructure Monitoring — Uppsala County</div>
</div>
</div>
<div class="main">
<div class="results">
<h2>Pilot Overview</h2>
<div class="metric-grid">
<div class="metric">
<div class="metric-value">2</div>
<div class="metric-label">Roads Monitored</div>
</div>
<div class="metric">
<div class="metric-value">68</div>
<div class="metric-label">Total km</div>
</div>
<div class="metric">
<div class="metric-value">3</div>
<div class="metric-label">Changes Detected</div>
</div>
<div class="metric">
<div class="metric-value">85%</div>
<div class="metric-label">Avg Confidence</div>
</div>
</div>
</div>
<div class="results">
<h2>E4 (Motorway) — 45 km</h2>
<div class="change-item">
<div class="change-type"> Pothole Detected</div>
<div class="change-details">Location: 59.85°N, 17.65°E | Size: 12 m² | Severity: Medium</div>
<div class="change-confidence">Confidence: 82%</div>
</div>
<div class="change-item">
<div class="change-type"> Construction Zone</div>
<div class="change-details">Location: 59.88°N, 17.72°E | Size: 2,500 m² | Severity: High</div>
<div class="change-confidence">Confidence: 95%</div>
</div>
<div class="map-placeholder">
[Satellite imagery would show E4 with detected changes marked]
</div>
</div>
<div class="results">
<h2>Länsväg 272 (County Road) — 23 km</h2>
<div class="change-item">
<div class="change-type"> Surface Damage</div>
<div class="change-details">Location: 59.92°N, 17.55°E | Size: 45 m² | Severity: Low</div>
<div class="change-confidence">Confidence: 78%</div>
</div>
<div class="map-placeholder">
[Satellite imagery would show Länsväg 272 with detected change marked]
</div>
</div>
<div class="results">
<h2>Data Sources</h2>
<ul>
<li>Sentinel-2 satellite imagery (ESA Copernicus)</li>
<li>Analysis period: June 1 — July 1, 2026</li>
<li>Cloud cover: 10-15%</li>
<li>Resolution: 10m (multispectral)</li>
</ul>
</div>
<div class="results">
<h2>Methodology</h2>
<ol>
<li>Download Sentinel-2 L2A images for target area</li>
<li>Pre-process: atmospheric correction, cloud masking</li>
<li>Extract road mask using OpenStreetMap vectors</li>
<li>Compare spectral signatures before/after</li>
<li>Classify change type using trained model</li>
<li>Calculate confidence based on image quality and change size</li>
</ol>
</div>
<div class="results">
<h2>Next Steps</h2>
<ul>
<li>Field verification of detected changes</li>
<li>Compare with Trafikverket maintenance records</li>
<li>Refine detection model with ground truth</li>
<li>Expand to additional road segments</li>
</ul>
</div>
</div>
</body>
</html>
+211
View File
@@ -0,0 +1,211 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Runtime Health — NOC</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .subtitle { color: #888; font-size: 0.9rem; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 20px; }
.metric-value { font-size: 2.5rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; margin-top: 4px; }
.metric-status { font-size: 0.75rem; margin-top: 8px; padding: 24px; border-radius: var(--radius-sm); display: inline-block; }
.status-ok { background: #1a3a1a; color: #4ade80; }
.status-warn { background: #3a3a1a; color: #facc15; }
.status-critical { background: #3a1a1a; color: #f87171; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 24px; color: #00d4ff; }
.chart { height: 200px; background: #1a1a1a; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; color: #666; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; padding: 12px; color: #888; font-size: 0.8rem; }
td { padding: 12px; border-top: 1px solid #222; font-size: 0.9rem; }
</style>
</head>
<body>
<div class="header">
<h1>LIFE Runtime Health</h1>
<div class="subtitle">Network Operations Center — Weather Intelligence</div>
</div>
<div class="main">
<div class="metrics">
<div class="metric">
<div class="metric-value" id="pipeline-success">100%</div>
<div class="metric-label">Pipeline Success Rate</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="reality-latency">13.3</div>
<div class="metric-label">Reality Latency (min)</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="data-freshness">13.3</div>
<div class="metric-label">Data Freshness (min)</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="pipeline-runtime">4.5</div>
<div class="metric-label">Pipeline Runtime (min)</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="observations-hour">1,660</div>
<div class="metric-label">Observations/Hour</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="retry-rate">0%</div>
<div class="metric-label">Retry Rate</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="error-rate">0%</div>
<div class="metric-label">Error Rate</div>
<div class="metric-status status-ok">OK</div>
</div>
<div class="metric">
<div class="metric-value" id="queue-length">0</div>
<div class="metric-label">Queue Length</div>
<div class="metric-status status-ok">OK</div>
</div>
</div>
<div class="section">
<h2>Reality Latency Trend</h2>
<div class="chart">[Latency chart over time]</div>
</div>
<div class="section">
<h2>Pipeline Runtime Trend</h2>
<div class="chart">[Runtime chart over time]</div>
</div>
<div class="section">
<h2>System Resources</h2>
<div class="metrics">
<div class="metric">
<div class="metric-value" id="cpu">1.1%</div>
<div class="metric-label">CPU Usage</div>
</div>
<div class="metric">
<div class="metric-value" id="ram">61.2%</div>
<div class="metric-label">RAM Usage</div>
</div>
<div class="metric">
<div class="metric-value" id="storage">26.1%</div>
<div class="metric-label">Storage Usage</div>
</div>
</div>
</div>
<div class="section">
<h2>Error Budget</h2>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Budget</th>
<th>Used</th>
<th>Remaining</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pipeline Failures</td>
<td>0.5%</td>
<td>0%</td>
<td>100%</td>
<td><span class="metric-status status-ok">OK</span></td>
</tr>
<tr>
<td>API Downtime</td>
<td>0.1%</td>
<td>0%</td>
<td>100%</td>
<td><span class="metric-status status-ok">OK</span></td>
</tr>
<tr>
<td>Unhandled Exceptions</td>
<td>0</td>
<td>0</td>
<td>100%</td>
<td><span class="metric-status status-ok">OK</span></td>
</tr>
</tbody>
</table>
</div>
<div class="section">
<h2>Burn-in Status</h2>
<table>
<thead>
<tr>
<th>Criterion</th>
<th>Target</th>
<th>Current</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pipeline Success Rate</td>
<td>>99.5%</td>
<td>100%</td>
<td><span class="metric-status status-ok">PASS</span></td>
</tr>
<tr>
<td>Reality Latency</td>
<td><60 min</td>
<td>13.3 min</td>
<td><span class="metric-status status-ok">PASS</span></td>
</tr>
<tr>
<td>Data Freshness</td>
<td><120 min</td>
<td>13.3 min</td>
<td><span class="metric-status status-ok">PASS</span></td>
</tr>
<tr>
<td>Duplicate Observations</td>
<td>0</td>
<td>0</td>
<td><span class="metric-status status-ok">PASS</span></td>
</tr>
<tr>
<td>Unhandled Exceptions</td>
<td>0</td>
<td>0</td>
<td><span class="metric-status status-ok">PASS</span></td>
</tr>
<tr>
<td>Memory Growth</td>
<td>None</td>
<td>Stable</td>
<td><span class="metric-status status-ok">PASS</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<script>
// Uppdatera var 5:e minut
setInterval(() => {
location.reload();
}, 300000);
</script>
</body>
</html>
+256
View File
@@ -0,0 +1,256 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>What We Actually Have — Landvex LIFE</title>
<link rel="stylesheet" href="/assets/css/landvex-complete.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 24px; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.main { padding: 40px; max-width: 900px; margin: 0 auto; }
.section { background: #111; border: 1px solid #333; border-radius: var(--radius-md); padding: 32px; margin-bottom: 24px; }
.section h2 { font-size: 1.3rem; margin-bottom: 24px; color: #00d4ff; }
.section h3 { font-size: 1rem; margin: 16px 0 8px; color: #7c3aed; }
.section p { color: #aaa; margin-bottom: 12px; font-size: 0.95rem; }
.section ul { margin-left: 20px; color: #aaa; }
.section li { margin-bottom: 8px; }
.status { display: inline-block; padding: 24px; border-radius: var(--radius-sm); font-size: 0.75rem; font-weight: 600; }
.status-concept { background: #333; color: #888; }
.status-code { background: #1a3a1a; color: #4ade80; }
.status-pilot { background: #3a2a1a; color: #fbbf24; }
.status-production { background: #1a1a3a; color: #60a5fa; }
.warning { background: #2a1a1a; border: 1px solid #7c3aed; border-radius: var(--radius-md); padding: 16px; margin: 16px 0; }
.warning strong { color: #f87171; }
</style>
</head>
<body>
<div class="header">
<h1>What We Actually Have</h1>
</div>
<div class="main">
<div class="section">
<h2>1. What Is LIFE?</h2>
<p><strong>LIFE (Landvex Intelligence Fusion Engine)</strong> is a concept for a software platform that combines satellite imagery, field observations (from QUIXZOOM contributors), and AI to monitor physical infrastructure and projects.</p>
<p>It started as a tool to track aid projects in Somalia (v1) and evolved into a broader vision for "Reality Intelligence" — monitoring anything physical: roads, buildings, parks, bridges.</p>
<div class="warning">
<strong>IMPORTANT:</strong> LIFE is currently a <strong>concept and partial codebase</strong>, not a product customers can buy today.
</div>
</div>
<div class="section">
<h2>2. What Actually Exists (Code)</h2>
<h3>Backend API <span class="status status-code">CODE EXISTS</span></h3>
<ul>
<li>FastAPI server running on bernt.wavult.com:8000</li>
<li>Nginx proxy via https://landvex.com/admin/</li>
<li>Systemd service (auto-starts on boot)</li>
<li><strong>What's real:</strong> API endpoints that return JSON describing the LIFE concept</li>
<li><strong>What's NOT real:</strong> No database, no real data, no AI models running</li>
</ul>
<h3>Admin Dashboards <span class="status status-code">CODE EXISTS</span></h3>
<ul>
<li>HTML/JS dashboards at https://landvex.com/admin/</li>
<li>Dark theme, interactive navigation</li>
<li><strong>What's real:</strong> Static pages showing the concept</li>
<li><strong>What's NOT real:</strong> No live data, no user login, no CRUD operations</li>
</ul>
<h3>quiXzoom Integration <span class="status status-concept">CONCEPT ONLY</span></h3>
<ul>
<li>quiXzoom exists as a separate mobile app for photo missions</li>
<li><strong>Current state:</strong> No direct integration with LIFE backend</li>
<li><strong>Plan:</strong> quiXzoom photos would feed into LIFE as "field observations"</li>
</ul>
<h3>AI / Intelligence <span class="status status-concept">CONCEPT ONLY</span></h3>
<ul>
<li>No ML models deployed</li>
<li>No satellite image processing pipeline</li>
<li>No automated change detection</li>
<li><strong>Plan:</strong> Use AWS SageMaker or similar for model training</li>
</ul>
</div>
<div class="section">
<h2>3. What Is RIS?</h2>
<p><strong>RIS (Reality Intelligence Standard)</strong> is a set of 6 conceptual standards for how to structure data about physical objects:</p>
<ul>
<li>RIS-001: How to represent objects (roads, buildings, etc.)</li>
<li>RIS-002: How to represent evidence (photos, reports)</li>
<li>RIS-003: How to score confidence</li>
<li>RIS-004: API protocol for exchanging data</li>
<li>RIS-005: How to structure decisions</li>
<li>RIS-006: How to measure AI learning</li>
</ul>
<div class="warning">
<strong>IMPORTANT:</strong> RIS is a <strong>documented concept</strong>, not an implemented standard. No external systems use it. No certification program exists yet.
</div>
</div>
<div class="section">
<h2>4. How Would a Customer Use This?</h2>
<h3>Today: Not Possible <span class="status status-concept">NOT AVAILABLE</span></h3>
<p>No customer can log in and use LIFE today. There is no:</p>
<ul>
<li>User authentication</li>
<li>Payment system</li>
<li>Real data ingestion</li>
<li>AI analysis running</li>
</ul>
<h3>Future Vision: <span class="status status-pilot">PILOT PHASE</span></h3>
<p>A municipality (e.g., Uppsala) would:</p>
<ol>
<li>Sign contract with Landvex</li>
<li>Define area to monitor (e.g., all roads)</li>
<li>LIFE ingests satellite imagery automatically</li>
<li>quiXzoom contributors take field photos</li>
<li>AI detects changes (new potholes, construction)</li>
<li>Dashboard shows status with confidence scores</li>
<li>Alerts sent when issues detected</li>
</ol>
<h3>Pricing (Conceptual):</h3>
<ul>
<li>SaaS subscription per km² monitored</li>
<li>quiXzoom missions per photo</li>
<li>Professional services for setup</li>
</ul>
</div>
<div class="section">
<h2>5. Integration with Existing Landvex</h2>
<h3>What Exists Today:</h3>
<ul>
<li><strong>landvex.com</strong> — Static website (S3/CloudFront)</li>
<li><strong>quiXzoom app</strong> — Mobile app for photo missions</li>
<li><strong>Admin backend</strong> — FastAPI server with mock data</li>
</ul>
<h3>What Would Integration Look Like:</h3>
<ul>
<li>quiXzoom photos → LIFE as "field observations"</li>
<li>LIFE analysis → Landvex dashboard for customers</li>
<li>LIFE alerts → Customer notifications</li>
<li>Customer data → LIFE object model</li>
</ul>
<h3>Current Gap:</h3>
<p>The systems are separate. There is no data flow between quiXzoom and LIFE today.</p>
</div>
<div class="section">
<h2>6. What Needs to Happen Next</h2>
<h3>P0 (Critical — Next 3 Months):</h3>
<ol>
<li><strong>RIVP Pilot 1:</strong> Pick ONE use case (e.g., road monitoring in Uppsala)</li>
<li><strong>Build minimal working system:</strong>
<ul>
<li>Ingest satellite imagery for pilot area</li>
<li>Run basic change detection (even manual at first)</li>
<li>Show results in dashboard</li>
<li>Measure: precision, detection time, verification rate</li>
</ul>
</li>
<li><strong>Document technical specification</strong> based on real learnings</li>
</ol>
<h3>P1 (After Pilot Success):</h3>
<ol>
<li>Build reference implementation (real code, not concepts)</li>
<li>Publish RIS specification</li>
<li>Start second pilot (different domain)</li>
</ol>
<h3>P2-P3 (Future):</h3>
<ol>
<li>Conformance program</li>
<li>Partner SDK</li>
<li>Marketplace</li>
</ol>
</div>
<div class="section">
<h2>7. Summary: Concept vs. Reality</h2>
<table>
<tr>
<td><strong>Component</strong></td>
<td><strong>Status</strong></td>
<td><strong>What Exists</strong></td>
</tr>
<tr>
<td>Backend API</td>
<td><span class="status status-code">Partial</span></td>
<td>FastAPI server, mock endpoints, no DB</td>
</tr>
<tr>
<td>Dashboards</td>
<td><span class="status status-code">Partial</span></td>
<td>Static HTML showing concepts, no live data</td>
</tr>
<tr>
<td>AI/ML</td>
<td><span class="status status-concept">None</span></td>
<td>No models deployed</td>
</tr>
<tr>
<td>quiXzoom Integration</td>
<td><span class="status status-concept">None</span></td>
<td>Separate app, no data flow to LIFE</td>
</tr>
<tr>
<td>Database</td>
<td><span class="status status-concept">None</span></td>
<td>No persistent storage</td>
</tr>
<tr>
<td>Authentication</td>
<td><span class="status status-concept">None</span></td>
<td>No user login system</td>
</tr>
<tr>
<td>RIS Standard</td>
<td><span class="status status-pilot">Concept</span></td>
<td>Documented, not implemented by others</td>
</tr>
<tr>
<td>Customer Pilots</td>
<td><span class="status status-concept">None</span></td>
<td>No active pilots</td>
</tr>
<tr>
<td>Revenue</td>
<td><span class="status status-concept">None</span></td>
<td>No paying customers for LIFE</td>
</tr>
</table>
</div>
<div class="section">
<h2>8. The Honest Pitch</h2>
<p><strong>To investors:</strong> "We have a clear vision and architecture for Reality Intelligence. We've built the conceptual framework (RIS) and a demo backend. Next step is a paid pilot to prove the technology works in practice."</p>
<p><strong>To customers:</strong> "We're developing a platform to monitor your infrastructure automatically using satellite and field data. We're starting pilots in Q3 2026. Would you be interested in being an early partner?"</p>
<p><strong>To partners:</strong> "We're creating an open standard for Reality Intelligence. The specification is in development. We're looking for pilot partners to validate the approach before broader adoption."</p>
</div>
</div>
</body>
</html>