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 ────────────────────────────────────────────