// consistency.js import { API_BASE_URL, CONSISTENCY_POLL_INTERVAL, setInconsistencyData, inconsistencyData } from './global.js'; import { hideConsistencyModal, showConsistencyModal } from './modals.js'; import { loadAllData } from './data_loader.js'; // Will be imported later /** * Core function to resolve consistency by making a POST call to a sync endpoint. * @param {string} action - 'flush' (Cache -> DB) or 'rollback' (DB -> Cache). */ async function resolveConsistency(action) { let url = ''; let message = ''; if (action === 'flush') { url = `${API_BASE_URL}/flush-to-db`; message = 'Flushing cache to DB...'; } else if (action === 'rollback') { url = `${API_BASE_URL}/load-from-db`; message = 'Rolling back cache from DB...'; } else { return; } if (!confirm(`Are you sure you want to perform the action: ${action.toUpperCase()}? This will overwrite the target configuration.`)) { return; } const modal = document.getElementById('consistencyModal'); if (modal) modal.style.display = 'none'; const button = document.getElementById('consistency-button'); if (button) { button.textContent = message; button.classList.remove('consistent', 'inconsistent', 'error'); button.classList.add('loading'); button.disabled = true; } try { const response = await fetch(url, { method: 'POST' }); if (!response.ok) { const errorBody = await response.text(); throw new Error(`HTTP Error ${response.status}: ${errorBody}`); } alert(`Sync successful via ${action.toUpperCase()}. Reloading data.`); loadAllData(); checkConsistency(); } catch (error) { alert(`Failed to sync via ${action}. Check console for details.`); console.error(`Sync operation (${action}) failed:`, error); checkConsistency(); } } /** * Periodically checks the consistency status with the backend. */ export async function checkConsistency() { const button = document.getElementById('consistency-button'); if (!button) return; // Save previous state before fetch const hadConflict = inconsistencyData !== null && inconsistencyData.inconsistent === true; const isCurrentlyError = button.classList.contains('error'); button.textContent = 'Checking...'; button.classList.add('loading'); button.classList.remove('consistent', 'inconsistent', 'error'); button.disabled = true; try { const response = await fetch(`${API_BASE_URL}/is-consistent`); if (!response.ok) throw new Error(response.statusText); const data = await response.json(); const consistencyStatus = data.consistent; const hasConflict = consistencyStatus.inconsistent === true; setInconsistencyData(hasConflict ? consistencyStatus : null); button.classList.remove('loading'); button.disabled = !hasConflict; // Only enable if inconsistent if (hasConflict) { button.textContent = '🚨 CONFLICT'; button.classList.remove('consistent', 'error'); button.classList.add('inconsistent'); // If conflict is new or if we recovered from an error, show the modal if (!hadConflict || isCurrentlyError) { // Optionally show the modal automatically here, or leave it to user click } } else { button.textContent = '✅ Consistent'; button.classList.remove('inconsistent', 'error'); button.classList.add('consistent'); hideConsistencyModal(); } } catch (error) { button.classList.remove('loading', 'consistent', 'inconsistent'); button.classList.add('error'); button.textContent = '❌ Error'; button.disabled = true; setInconsistencyData(null); console.error("Consistency check failed:", error); } } // Exported functions must be attached to 'window' if called from inline HTML attributes export function manualFlush() { resolveConsistency('flush'); } export function manualRollback() { resolveConsistency('rollback'); }