yyxx
All checks were successful
Deploy / deploy-staging (push) Successful in 6s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-05-05 23:46:23 +02:00
parent e335a8d5bf
commit 48b7583f19
9 changed files with 528 additions and 277 deletions

View File

@@ -26,20 +26,7 @@
return [];
}
})();
const initialDebugMode = (() => {
try {
return window.localStorage.getItem('mining-checker-debug-enabled') === '1';
} catch (error) {
return false;
}
})();
const initialDebugConsoleOpen = (() => {
try {
return window.localStorage.getItem('mining-checker-debug-console-open') === '1';
} catch (error) {
return false;
}
})();
const initialDebugMode = document.body && document.body.dataset.nexusDebugEnabled === '1';
function getCookie(name) {
const pattern = `; ${document.cookie}`;
const parts = pattern.split(`; ${name}=`);
@@ -52,20 +39,12 @@
function setCookie(name, value, maxAgeSeconds) {
document.cookie = `${name}=${encodeURIComponent(value)}; path=/; max-age=${maxAgeSeconds}; samesite=lax`;
}
const initialDebugView = (() => {
try {
const value = window.localStorage.getItem('mining-checker-debug-view');
return value === 'text' ? 'text' : 'structured';
} catch (error) {
return 'structured';
}
})();
const debugBus = window.__miningCheckerDebugBus || {
const debugBus = window.__nexusDebugBus || {
enabled: initialDebugMode,
listener: null,
sequence: 0,
};
window.__miningCheckerDebugBus = debugBus;
window.__nexusDebugBus = debugBus;
function emitDebug(entry) {
debugBus.sequence += 1;
@@ -80,11 +59,6 @@
}
}
function persistDebugCookie(enabled) {
const value = enabled ? '1' : '0';
document.cookie = `mining_checker_debug=${value}; path=/; max-age=31536000; samesite=lax`;
}
function emitServerTraceEntries(trace, meta) {
if (!Array.isArray(trace) || !trace.length) {
emitDebug({
@@ -585,10 +559,6 @@
const [saving, setSaving] = useState(false);
const [error, setError] = useState('');
const [message, setMessage] = useState('');
const [debugEnabled, setDebugEnabled] = useState(initialDebugMode);
const [debugConsoleOpen, setDebugConsoleOpen] = useState(initialDebugConsoleOpen);
const [debugView, setDebugView] = useState(initialDebugView);
const [debugEntries, setDebugEntries] = useState([]);
const [schemaStatus, setSchemaStatus] = useState(normalizeSchemaStatus(null));
const [initForm, setInitForm] = useState({ drop_existing: false });
const [sqlImportFile, setSqlImportFile] = useState(null);
@@ -706,43 +676,12 @@
});
useEffect(() => {
debugBus.enabled = debugEnabled;
debugBus.listener = (entry) => {
setDebugEntries((current) => [entry].concat(current).slice(0, 250));
};
try {
window.localStorage.setItem('mining-checker-debug-enabled', debugEnabled ? '1' : '0');
} catch (error) {
// Ignore localStorage write failures.
}
persistDebugCookie(debugEnabled);
debugBus.enabled = initialDebugMode;
emitDebug({
type: 'debug:mode',
enabled: debugEnabled,
enabled: initialDebugMode,
});
return () => {
debugBus.listener = null;
};
}, [debugEnabled]);
useEffect(() => {
try {
window.localStorage.setItem('mining-checker-debug-console-open', debugConsoleOpen ? '1' : '0');
} catch (error) {
// Ignore localStorage write failures.
}
}, [debugConsoleOpen]);
useEffect(() => {
try {
window.localStorage.setItem('mining-checker-debug-view', debugView);
} catch (error) {
// Ignore localStorage write failures.
}
}, [debugView]);
}, []);
const measurements = Array.isArray(payload?.measurements) ? payload.measurements : [];
const latest = payload?.summary?.latest_measurement || null;
@@ -1765,46 +1704,10 @@
}
}
async function copyDebugConsole() {
const content = debugEntries
.slice()
.reverse()
.map((entry) => `${entry.time} · ${entry.type}\n${JSON.stringify(entry, null, 2)}`)
.join('\n\n');
if (!content) {
setMessage('Keine Debug-Ausgaben zum Kopieren vorhanden.');
return;
}
try {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(content);
} else {
const textarea = document.createElement('textarea');
textarea.value = content;
textarea.setAttribute('readonly', 'readonly');
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
setMessage('Debug-Inhalt wurde in die Zwischenablage kopiert.');
} catch (err) {
setError('Debug-Inhalt konnte nicht kopiert werden.');
}
}
function resetReportCurrencyOverride() {
setReportCurrencyOverride('');
setCookie('mining_checker_report_currency', '', 0);
}
const debugConsoleText = debugEntries
.map((entry) => `${entry.time} · ${entry.type}\n${JSON.stringify(entry, null, 2)}`)
.join('\n\n');
return h('div', {
className: 'mc-grid-bg',
}, [
@@ -1813,78 +1716,6 @@
message ? h('div', { key: 'message', className: 'mc-alert mc-alert--success' }, message) : null,
loading ? h('div', { key: 'loading', className: 'mc-empty' }, 'Lade Mining-Checker Daten …') : null,
payload ? renderTab() : null,
h('div', { key: 'debug-tools', className: 'mc-debug-tools' }, [
h('button', {
key: 'debug-toggle',
type: 'button',
className: cx('mc-button', debugEnabled ? 'mc-button--secondary' : 'mc-button--ghost'),
onClick: () => {
const next = !debugEnabled;
setDebugEnabled(next);
if (next) {
setDebugConsoleOpen(true);
}
},
}, debugEnabled ? 'Debug aktiv' : 'Debug einschalten'),
h('button', {
key: 'console-toggle',
type: 'button',
className: 'mc-button mc-button--ghost',
onClick: () => setDebugConsoleOpen((current) => {
const next = !current;
if (next) {
setDebugEnabled(true);
}
return next;
}),
}, debugConsoleOpen ? 'Online-Konsole ausblenden' : 'Online-Konsole einblenden'),
debugEntries.length ? h('button', {
key: 'debug-clear',
type: 'button',
className: 'mc-button mc-button--ghost',
onClick: () => setDebugEntries([]),
}, 'Konsole leeren') : null,
debugEntries.length ? h('button', {
key: 'debug-copy',
type: 'button',
className: 'mc-button mc-button--ghost',
onClick: copyDebugConsole,
}, 'Copy content') : null,
]),
debugConsoleOpen ? h('section', { key: 'debug-console', className: 'mc-panel mc-debug-console' }, [
h(SectionTitle, {
key: 'debug-title',
title: 'Online-Konsole',
subtitle: 'Zeigt API-, Provider- und DB-Debugspuren direkt aus dem Modul.',
action: h(Badge, { tone: debugEnabled ? 'success' : 'warn' }, debugEnabled ? 'Debug aktiv' : 'Debug aus'),
}),
h('div', { key: 'debug-body', className: 'mc-panel-body' }, [
h('div', { key: 'debug-view-switch', className: 'mc-debug-view-switch' }, [
h('button', {
key: 'view-structured',
type: 'button',
className: cx('mc-button', debugView === 'structured' ? 'mc-button--tab-active' : 'mc-button--tab'),
onClick: () => setDebugView('structured'),
}, 'Strukturiert'),
h('button', {
key: 'view-text',
type: 'button',
className: cx('mc-button', debugView === 'text' ? 'mc-button--tab-active' : 'mc-button--tab'),
onClick: () => setDebugView('text'),
}, 'Text-Konsole'),
]),
debugView === 'text'
? h('pre', { className: 'mc-code-block mc-debug-text-console' }, debugConsoleText || 'Noch keine Debug-Ausgaben vorhanden.')
: h('div', { className: 'mc-debug-log' },
debugEntries.length
? debugEntries.map((entry) => h('div', { key: entry.id, className: 'mc-debug-entry' }, [
h('div', { key: 'meta', className: 'mc-kicker' }, `${entry.time} · ${entry.type}`),
h('pre', { key: 'payload', className: 'mc-code-block' }, JSON.stringify(entry, null, 2)),
]))
: h('div', { className: 'mc-empty' }, 'Noch keine Debug-Ausgaben vorhanden.')
),
]),
]) : null,
]),
]);

View File

@@ -44,14 +44,7 @@ final class Router
$this->config = ModuleConfig::load($this->moduleBasePath);
$requestUri = (string) ($_SERVER['REQUEST_URI'] ?? '');
$requestPath = (string) (parse_url($requestUri, PHP_URL_PATH) ?: '');
$debugConfig = $this->config->debug();
$debugEnabled = filter_var(
$_GET['debug']
?? $_SERVER['HTTP_X_MINING_DEBUG']
?? $_COOKIE['mining_checker_debug']
?? ($debugConfig['enabled'] ?? false),
FILTER_VALIDATE_BOOL
);
$debugEnabled = function_exists('nexus_debug_enabled') ? nexus_debug_enabled() : false;
$latestDebugFilePath = rtrim($this->config->debugDir(), '/') . '/latest-server.json';
$isLatestDebugRequest = str_ends_with($requestPath, '/api/mining-checker/v1/debug/latest')
|| $requestPath === 'api/mining-checker/v1/debug/latest'