feat: waterway diamonds, cable corridor zones, cache resilience

- Render 9 strategic waterway chokepoints as cyan diamond markers
  (Hormuz, Malacca, Suez, Panama, Bab-el-Mandeb, Taiwan, Gibraltar,
  GIUK Gap, Bosphorus) with throughput tooltips
- Render 6 submarine cable corridors as dashed blue rectangles
  (transatlantic N/S, transpacific, asia-europe, red sea, med)
- Add waterways + cable_corridors to /api/static and SSE payloads
- Make cache.set() and evict_expired() swallow sqlite3 write errors
  instead of crashing callers (fixes "readonly database" in dashboard)
- Infrastructure layer: 134 → 173 items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Marc Shade
2026-02-24 10:37:03 -05:00
parent 95b149ad55
commit 71fbb1cda4
3 changed files with 76 additions and 15 deletions
+23 -12
View File
@@ -70,14 +70,21 @@ class Cache:
return json.loads(row[0])
def set(self, key: str, value: Any, ttl_seconds: int) -> None:
"""Store a value with TTL in seconds."""
conn = self._get_conn()
now = time.time()
conn.execute(
"INSERT OR REPLACE INTO cache (key, value, expires_at, created_at) VALUES (?, ?, ?, ?)",
(key, json.dumps(value, default=str), now + ttl_seconds, now),
)
conn.commit()
"""Store a value with TTL in seconds.
Write failures (readonly DB, locked) are logged and swallowed —
the cache is best-effort and must never crash the caller.
"""
try:
conn = self._get_conn()
now = time.time()
conn.execute(
"INSERT OR REPLACE INTO cache (key, value, expires_at, created_at) VALUES (?, ?, ?, ?)",
(key, json.dumps(value, default=str), now + ttl_seconds, now),
)
conn.commit()
except sqlite3.OperationalError as exc:
logger.warning("Cache write failed for %s: %s", key, exc)
def delete(self, key: str) -> None:
"""Delete a specific key."""
@@ -87,10 +94,14 @@ class Cache:
def evict_expired(self) -> int:
"""Remove all expired entries. Returns count removed."""
conn = self._get_conn()
cursor = conn.execute("DELETE FROM cache WHERE expires_at < ?", (time.time(),))
conn.commit()
return cursor.rowcount
try:
conn = self._get_conn()
cursor = conn.execute("DELETE FROM cache WHERE expires_at < ?", (time.time(),))
conn.commit()
return cursor.rowcount
except sqlite3.OperationalError as exc:
logger.warning("Cache evict failed: %s", exc)
return 0
def stats(self) -> dict[str, Any]:
"""Cache statistics."""
+18 -1
View File
@@ -46,8 +46,9 @@ from world_intel_mcp.analysis.alerts import fetch_alert_digest, fetch_weekly_tre
from world_intel_mcp.analysis.posture import fetch_strategic_posture
from world_intel_mcp.analysis.exposure import fetch_population_exposure
from world_intel_mcp.sources.fleet import fetch_fleet_report
from world_intel_mcp.config.countries import INTEL_HOTSPOTS
from world_intel_mcp.config.countries import INTEL_HOTSPOTS, STRATEGIC_WATERWAYS
from world_intel_mcp.config.geospatial import MILITARY_BASES, STRATEGIC_PORTS, PIPELINES, NUCLEAR_FACILITIES
from world_intel_mcp.sources.infrastructure import CABLE_CORRIDORS
logger = logging.getLogger(__name__)
@@ -173,6 +174,14 @@ async def _fetch_overview() -> dict:
result["strategic_ports"] = {"ports": STRATEGIC_PORTS, "count": len(STRATEGIC_PORTS)}
result["pipelines"] = {"pipelines": PIPELINES, "count": len(PIPELINES)}
result["nuclear_facilities"] = {"facilities": NUCLEAR_FACILITIES, "count": len(NUCLEAR_FACILITIES)}
result["waterways"] = {"waterways": STRATEGIC_WATERWAYS, "count": len(STRATEGIC_WATERWAYS)}
result["cable_corridors"] = {
"corridors": [
{"name": n, "lat_range": c["lat_range"], "lon_range": c["lon_range"], "cables": c["cables"]}
for n, c in CABLE_CORRIDORS.items()
],
"count": len(CABLE_CORRIDORS),
}
# Attach source health + timestamp
result["source_health"] = _breaker.status() if _breaker else {}
@@ -236,6 +245,14 @@ async def api_static(request):
"strategic_ports": {"ports": STRATEGIC_PORTS, "count": len(STRATEGIC_PORTS)},
"pipelines": {"pipelines": PIPELINES, "count": len(PIPELINES)},
"nuclear_facilities": {"facilities": NUCLEAR_FACILITIES, "count": len(NUCLEAR_FACILITIES)},
"waterways": {"waterways": STRATEGIC_WATERWAYS, "count": len(STRATEGIC_WATERWAYS)},
"cable_corridors": {
"corridors": [
{"name": n, "lat_range": c["lat_range"], "lon_range": c["lon_range"], "cables": c["cables"]}
for n, c in CABLE_CORRIDORS.items()
],
"count": len(CABLE_CORRIDORS),
},
}, headers={"Access-Control-Allow-Origin": "*"})
+35 -2
View File
@@ -393,6 +393,14 @@ a { color: var(--accent); text-decoration: none; }
.mk-nuke-fac.hot { animation: glow-gold 2s ease-in-out infinite; }
.pipeline-line { cursor: pointer; transition: opacity 0.15s; }
.pipeline-line:hover { opacity: 1 !important; stroke-width: 3 !important; }
.mk-waterway {
width: 10px; height: 10px; background: var(--accent); opacity: 0.8;
transform: rotate(45deg); border: 1.5px solid rgba(0,229,255,0.6);
cursor: pointer; transition: transform 0.15s, opacity 0.15s;
}
.mk-waterway:hover { transform: rotate(45deg) scale(1.5); opacity: 1; }
.cable-corridor { cursor: pointer; transition: fill-opacity 0.15s; }
.cable-corridor:hover { fill-opacity: 0.1 !important; stroke-opacity: 0.5 !important; }
@keyframes glow-gold {
0%,100% { box-shadow: 0 0 4px rgba(240,184,64,0.3); }
50% { box-shadow: 0 0 16px rgba(240,184,64,0.7); }
@@ -597,8 +605,8 @@ $('#drawerToggle').addEventListener('click', function() {
});
// ════════════ DETAIL MODAL ════════════
var COLORS = { earthquake: 'var(--red)', military: 'var(--blue)', conflict: 'var(--amber)', fire: 'var(--gold)', convergence: 'var(--purple)', nuclear: 'var(--green)', military_base: 'var(--teal)', port: 'var(--blue)', nuclear_facility: 'var(--gold)', pipeline: 'var(--purple)', exposure: '#e040fb' };
var LABELS = { earthquake: 'EARTHQUAKE', military: 'MILITARY AIRCRAFT', conflict: 'CONFLICT EVENT', fire: 'WILDFIRE CLUSTER', convergence: 'SIGNAL CONVERGENCE', nuclear: 'NUCLEAR MONITOR', military_base: 'MILITARY BASE', port: 'STRATEGIC PORT', nuclear_facility: 'NUCLEAR FACILITY', pipeline: 'PIPELINE', exposure: 'POPULATION EXPOSURE' };
var COLORS = { earthquake: 'var(--red)', military: 'var(--blue)', conflict: 'var(--amber)', fire: 'var(--gold)', convergence: 'var(--purple)', nuclear: 'var(--green)', military_base: 'var(--teal)', port: 'var(--blue)', nuclear_facility: 'var(--gold)', pipeline: 'var(--purple)', exposure: '#e040fb', waterway: 'var(--accent)', cable: 'var(--blue)' };
var LABELS = { earthquake: 'EARTHQUAKE', military: 'MILITARY AIRCRAFT', conflict: 'CONFLICT EVENT', fire: 'WILDFIRE CLUSTER', convergence: 'SIGNAL CONVERGENCE', nuclear: 'NUCLEAR MONITOR', military_base: 'MILITARY BASE', port: 'STRATEGIC PORT', nuclear_facility: 'NUCLEAR FACILITY', pipeline: 'PIPELINE', exposure: 'POPULATION EXPOSURE', waterway: 'STRATEGIC WATERWAY', cable: 'CABLE CORRIDOR' };
function showDetail(type, d) {
var title = '', subtitle = '', fields = [], link = '';
@@ -1155,6 +1163,31 @@ function updateMapInfra(data) {
});
line.addTo(mapLayers.infra);
});
// Strategic waterways (diamond markers at chokepoints)
var wws = (data.waterways && data.waterways.waterways) || [];
wws.forEach(function(w) {
if (w.lat == null || w.lon == null) return;
total++;
var mk = L.marker([w.lat, w.lon], {
icon: L.divIcon({ className: 'mk-waterway', iconSize: [10, 10], iconAnchor: [5, 5] })
});
mk.bindTooltip('<b>' + esc(w.name) + '</b><br><span style="opacity:0.7">' + esc(w.throughput || '') + '</span>', { className: 'mk-tip', direction: 'top', offset: [0, -6] });
mk.addTo(mapLayers.infra);
});
// Submarine cable corridors (shaded rectangles)
var cables = (data.cable_corridors && data.cable_corridors.corridors) || [];
cables.forEach(function(c) {
if (!c.lat_range || !c.lon_range) return;
total++;
var bounds = [[c.lat_range[0], c.lon_range[0]], [c.lat_range[1], c.lon_range[1]]];
var rect = L.rectangle(bounds, {
color: '#4da8ff', weight: 1, opacity: 0.2,
fillColor: '#4da8ff', fillOpacity: 0.04,
dashArray: '4 3', className: 'cable-corridor'
});
rect.bindTooltip('<b>' + esc(c.name.replace(/_/g, ' ')) + '</b><br><span style="opacity:0.7">' + (c.cables || []).join(', ') + '</span>', { className: 'mk-tip', sticky: true });
rect.addTo(mapLayers.infra);
});
$('#cntInfra').textContent = total;
}