feat: cloud sync atlas data via VPS site_config

This commit is contained in:
posimai 2026-04-03 16:00:16 +09:00
parent 3e43c10845
commit bef60aa500
1 changed files with 37 additions and 2 deletions

View File

@ -1524,17 +1524,52 @@ let currentSimEdges = [];
// ── Health metrics cache: nodeId → { cpu_pct, mem_pct, status } ── // ── Health metrics cache: nodeId → { cpu_pct, mem_pct, status } ──
const nodeHealthCache = new Map(); const nodeHealthCache = new Map();
const VPS_API = 'https://api.soar-enrich.com/brain/api';
const VPS_GET = VPS_API + '/site/config/public?user=maita';
const VPS_SET = VPS_API + '/site/config/atlas_data';
const APIKEY_KEY = 'posimai_api_key';
async function loadData() { async function loadData() {
// 1. VPS から取得を試みる(クラウドが正)
try {
const res = await fetch(VPS_GET, { signal: AbortSignal.timeout(5000) });
if (res.ok) {
const data = await res.json();
const cloud = data.config?.atlas_data;
if (cloud && cloud.nodes) {
atlasData = cloud;
localStorage.setItem(STORAGE_KEY, JSON.stringify(atlasData));
return;
}
}
} catch { /* fallthrough to local cache */ }
// 2. ローカルキャッシュ
const saved = localStorage.getItem(STORAGE_KEY); const saved = localStorage.getItem(STORAGE_KEY);
if (saved) { if (saved) {
try { atlasData = JSON.parse(saved); return; } catch (e) {} try { atlasData = JSON.parse(saved); return; } catch (e) {}
} }
// No saved data — wizard will handle initialization // 3. No saved data — wizard will handle initialization
} }
let _saveTimer = null;
function saveData() { function saveData() {
atlasData.meta.updated = new Date().toISOString().slice(0, 10); atlasData.meta.updated = new Date().toISOString().slice(0, 10);
localStorage.setItem(STORAGE_KEY, JSON.stringify(atlasData)); const payload = JSON.stringify(atlasData);
localStorage.setItem(STORAGE_KEY, payload);
// VPS に debounce 保存3s
clearTimeout(_saveTimer);
_saveTimer = setTimeout(async () => {
const key = localStorage.getItem(APIKEY_KEY);
if (!key) return;
try {
await fetch(VPS_SET, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + key },
body: JSON.stringify({ value: atlasData }),
signal: AbortSignal.timeout(6000)
});
} catch { /* silent — local is still saved */ }
}, 3000);
} }
// ── Graph rendering ──────────────────────────────────────────── // ── Graph rendering ────────────────────────────────────────────