From bef60aa50017ba8ccf99a501a7bc0ac3816ebfdf Mon Sep 17 00:00:00 2001 From: posimai Date: Fri, 3 Apr 2026 16:00:16 +0900 Subject: [PATCH] feat: cloud sync atlas data via VPS site_config --- index.html | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 38ab3fb..ee965fc 100644 --- a/index.html +++ b/index.html @@ -1524,17 +1524,52 @@ let currentSimEdges = []; // ── Health metrics cache: nodeId → { cpu_pct, mem_pct, status } ── 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() { + // 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); if (saved) { 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() { 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 ────────────────────────────────────────────