fix(web): при недоступном сервере показывался чужой пример как живые данные

Если /api/snapshot не отвечал, клиент молча загружал snapshot.example.json —
63 профиля с почтами user@example.test — и ставил индикатор источника в
зелёное через setSourceIndicator(true, ...). На экране появлялась полная
здоровая панель, не имеющая отношения к этому серверу.

Дефект становится опасным ровно в том сценарии, ради которого делался вход с
другой машины: при работе через SSH-туннель достаточно промахнуться портом
или потерять туннель, чтобы принять пример за собственные данные и,
например, решать по нему, у какого аккаунта кончилась квота.

Осознанная работа с фикстурой сохранена: ?fixture=1 и открытие страницы
файлом. Подстановка вместо ответа сервера убрана — отсутствие данных теперь
читается как отсутствие данных.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hermes Team 2026-08-25 10:14:04 +07:00
parent 3287565773
commit e8aa60b982

View file

@ -198,18 +198,17 @@ async function fetchSnapshot() {
setSourceIndicator(true, 'Live API (/api/snapshot)');
applySnapshot(data);
} catch (err) {
console.warn('Live API unavailable, attempting snapshot.example.json fallback:', err);
try {
const fallbackRes = await fetch('snapshot.example.json');
if (fallbackRes.ok) {
const fallbackData = await fallbackRes.json();
setSourceIndicator(true, 'Фикстура (fallback)');
applySnapshot(fallbackData);
return;
}
} catch (e) {}
// Раньше здесь при недоступном API молча подставлялась
// snapshot.example.json — 63 чужих профиля с почтами user@example.test —
// и индикатор ставился в зелёное. Экран выглядел здоровой панелью,
// которая не имеет отношения к этому серверу: при работе через SSH-туннель
// достаточно промахнуться портом или потерять туннель, чтобы принять
// пример за свои данные. Осознанная работа с фикстурой осталась —
// ?fixture=1 и открытие файлом, — но подставлять её вместо ответа сервера
// нельзя: отсутствие данных должно читаться как отсутствие данных.
console.warn('Live API unavailable:', err);
setSourceIndicator(false, 'Сервер недоступен');
showToast('Сервер не отвечает. Данные на экране могут быть устаревшими.', 'error');
}
}