mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* fix(sentry): add noise filters for 5 non-actionable error patterns Filter dynamic import alt phrasing, script parse errors, maplibre style/WebGL crashes, and CustomEvent promise rejections. Also fix beforeSend to catch short Firefox null messages like "E is null". * fix: cache write race, settings stale key status, yahoo gate concurrency P1: Replace async background thread cache write with synchronous fs::write to prevent out-of-order writes and dirty flag cleared before persistence. P2: Add WorldMonitorTab.refresh() called after loadDesktopSecrets() so the API key badge reflects actual keychain state. P3: Replace timestamp-based Yahoo gate with promise queue to ensure sequential execution under concurrent callers. * feat: add Upstash Redis shared caching to all RPC handlers + fix cache key contamination - Add Redis L2 cache (getCachedJson/setCachedJson) to 28 RPC handlers across all service domains (market, conflict, cyber, economic, etc.) - Fix 10 P1 cache key contamination bugs where under-specified keys caused cross-request data pollution (e.g. filtered requests returning unfiltered cached data) - Restructure list-internet-outages to cache-then-filter pattern so country/timeRange filters always apply after cache read - Add write_lock mutex to PersistentCache in main.rs to prevent desktop cache write-race conditions - Document FMP (Financial Modeling Prep) as Yahoo Finance fallback TODO in market/v1/_shared.ts * fix: cache-key contamination and PizzINT/GDELT partial-failure regression - tech-events: fetch with limit=0 and cache full result, apply limit slice after cache read to prevent low-limit requests poisoning cache - pizzint: restore try-catch around PizzINT fetch so GDELT tension pairs are still returned when PizzINT API is down * fix: remove extra closing brace in pizzint try-catch * fix: recompute conferenceCount/mappableCount after limit slice * fix: bypass WM API key gate for registration endpoint /api/register-interest must reach cloud without a WorldMonitor API key, otherwise desktop users can never register (circular dependency).
63 lines
4.4 KiB
HTML
63 lines
4.4 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>World Monitor Settings</title>
|
|
<script>(function(){try{var t=localStorage.getItem('worldmonitor-theme');if(t==='light')document.documentElement.dataset.theme='light';}catch(e){}document.documentElement.classList.add('no-transition');})()</script>
|
|
<style>.settings-tab-panel{display:none}.settings-tab-panel.active{display:block}.settings-shell{height:100vh;display:flex;flex-direction:column}.settings-tab-panels{flex:1;min-height:0;overflow-y:auto;padding:20px 24px}.settings-footer{display:flex;justify-content:flex-end;gap:10px;padding:12px 24px;border-top:1px solid rgba(255,255,255,0.08)}</style>
|
|
</head>
|
|
<body style="background:#1a1c1e;color:#e8eaed;margin:0">
|
|
<div class="settings-shell">
|
|
<div class="settings-tabs" role="tablist">
|
|
<button class="settings-tab active" role="tab" aria-selected="true" aria-controls="tabPanelWorldMonitor" data-tab="worldmonitor">World Monitor</button>
|
|
<button class="settings-tab" role="tab" aria-selected="false" aria-controls="tabPanelLLMs" data-tab="llms">LLMs</button>
|
|
<button class="settings-tab" role="tab" aria-selected="false" aria-controls="tabPanelKeys" data-tab="keys">API Keys</button>
|
|
<button class="settings-tab" role="tab" aria-selected="false" aria-controls="tabPanelDebug" data-tab="debug">Debug & Logs</button>
|
|
</div>
|
|
<p id="settingsActionStatus" class="settings-action-status" aria-live="polite"></p>
|
|
<div class="settings-tab-panels">
|
|
<div id="tabPanelWorldMonitor" class="settings-tab-panel active" role="tabpanel">
|
|
<main id="worldmonitorApp" class="settings-content"></main>
|
|
</div>
|
|
<div id="tabPanelLLMs" class="settings-tab-panel" role="tabpanel">
|
|
<main id="llmApp" class="settings-content"><div style="display:flex;align-items:center;justify-content:center;padding:60px 0;color:#9aa0a6;font-size:14px;gap:10px"><svg width="20" height="20" viewBox="0 0 24 24" style="animation:spin 1s linear infinite"><style>@keyframes spin{to{transform:rotate(360deg)}}</style><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-dasharray="31 31"/></svg>Loading...</div></main>
|
|
</div>
|
|
<div id="tabPanelKeys" class="settings-tab-panel" role="tabpanel">
|
|
<main id="apiKeysApp" class="settings-content"><div style="display:flex;align-items:center;justify-content:center;padding:60px 0;color:#9aa0a6;font-size:14px;gap:10px"><svg width="20" height="20" viewBox="0 0 24 24" style="animation:spin 1s linear infinite"><style>@keyframes spin{to{transform:rotate(360deg)}}</style><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-dasharray="31 31"/></svg>Loading...</div></main>
|
|
</div>
|
|
<div id="tabPanelDebug" class="settings-tab-panel" role="tabpanel">
|
|
<div class="debug-actions">
|
|
<button id="openLogsBtn" type="button">Open Logs Folder</button>
|
|
<button id="openSidecarLogBtn" type="button">Open API Log</button>
|
|
</div>
|
|
<section class="settings-diagnostics" id="diagnosticsSection">
|
|
<header class="diag-header">
|
|
<h2>Diagnostics</h2>
|
|
<div class="diag-toggles">
|
|
<label><input type="checkbox" id="verboseApiLog"> Verbose Sidecar Log</label>
|
|
<label><input type="checkbox" id="fetchDebugLog"> Frontend Fetch Debug</label>
|
|
</div>
|
|
</header>
|
|
<div class="diag-traffic-bar">
|
|
<h3>API Traffic <span id="trafficCount"></span></h3>
|
|
<div class="diag-traffic-controls">
|
|
<label><input type="checkbox" id="autoRefreshLog" checked> Auto</label>
|
|
<button id="refreshLogBtn" type="button">Refresh</button>
|
|
<button id="clearLogBtn" type="button">Clear</button>
|
|
</div>
|
|
</div>
|
|
<div id="trafficLog" class="diag-traffic-log"></div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
<footer class="settings-footer">
|
|
<button id="cancelBtn" type="button" class="settings-btn settings-btn-secondary">Cancel</button>
|
|
<button id="okBtn" type="button" class="settings-btn settings-btn-primary">OK</button>
|
|
</footer>
|
|
</div>
|
|
|
|
<script type="module" src="/src/settings-main.ts"></script>
|
|
</body>
|
|
</html>
|