diff --git a/custom/apps/mining-checker/assets/js/app.js b/custom/apps/mining-checker/assets/js/app.js index ad5456c8..0a103d35 100644 --- a/custom/apps/mining-checker/assets/js/app.js +++ b/custom/apps/mining-checker/assets/js/app.js @@ -570,6 +570,8 @@ }; } + const OCR_AUTO_SAVE_CONFIDENCE_THRESHOLD = 0.95; + function getOcrStatusMessage(preview) { const flags = Array.isArray(preview && preview.flags) ? preview.flags : []; const missingProviders = flags @@ -1734,8 +1736,37 @@ }; }, [currentSettings.crypto_currency, measurements, payload?.bootstrap_meta?.overview_window_days]); - async function submitMeasurement(fromPreview) { - const preview = normalizeOcrPreview(ocrPreview); + async function saveMeasurement(raw, successMessage) { + setSaving(true); + setError(''); + setMessage(''); + try { + await request(`${apiBase}/projects/${encodeURIComponent(projectKey)}/measurements`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(raw), + }); + invalidateProjectBootstrapCache(projectKey); + setMessage(successMessage); + setMeasurementForm({ + measured_at: '', + coins_total: '', + price_per_coin: '', + price_currency: '', + note: '', + source: 'manual', + }); + setOcrPreview(null); + await reloadBootstrapAfterMutation(successMessage); + } catch (err) { + setError(err.message); + } finally { + setSaving(false); + } + } + + async function submitMeasurement(fromPreview, previewOverride) { + const preview = normalizeOcrPreview(previewOverride || ocrPreview); const raw = fromPreview ? { ...preview.suggested, coin_currency: currentMiningCurrency, @@ -1748,44 +1779,10 @@ coin_currency: currentMiningCurrency, }; - setSaving(true); - setError(''); - setMessage(''); - try { - await request(`${apiBase}/projects/${encodeURIComponent(projectKey)}/measurements`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(raw), - }); - invalidateProjectBootstrapCache(projectKey); - setMessage(fromPreview ? 'OCR-Vorschlag bestaetigt und gespeichert.' : 'Messpunkt gespeichert.'); - setMeasurementForm({ - measured_at: '', - coins_total: '', - price_per_coin: '', - price_currency: '', - note: '', - source: 'manual', - }); - setOcrPreview(null); - await reloadBootstrapAfterMutation(fromPreview ? 'OCR-Vorschlag bestaetigt und gespeichert.' : 'Messpunkt gespeichert.'); - } catch (err) { - setError(err.message); - } finally { - setSaving(false); - } + return saveMeasurement(raw, fromPreview ? 'OCR-Vorschlag bestaetigt und gespeichert.' : 'Messpunkt gespeichert.'); } - async function submitWalletSnapshotFromPreview() { - const preview = normalizeOcrPreview(ocrPreview); - const raw = { - ...preview.suggested_wallet, - image_path: preview.image_path, - ocr_raw_text: preview.raw_text, - ocr_confidence: preview.confidence, - ocr_flags: preview.flags, - }; - + async function saveWalletSnapshot(raw, successMessage) { setSaving(true); setError(''); setMessage(''); @@ -1795,9 +1792,9 @@ headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(raw), }); - setMessage('Wallet-Snapshot gespeichert.'); + setMessage(successMessage); setOcrPreview(null); - await reloadBootstrapAfterMutation('Wallet-Snapshot gespeichert.'); + await reloadBootstrapAfterMutation(successMessage); } catch (err) { setError(err.message); } finally { @@ -1805,6 +1802,19 @@ } } + async function submitWalletSnapshotFromPreview(previewOverride) { + const preview = normalizeOcrPreview(previewOverride || ocrPreview); + const raw = { + ...preview.suggested_wallet, + image_path: preview.image_path, + ocr_raw_text: preview.raw_text, + ocr_confidence: preview.confidence, + ocr_flags: preview.flags, + }; + + return saveWalletSnapshot(raw, 'Wallet-Snapshot gespeichert.'); + } + async function deleteMeasurement(id) { if (!id) { return; @@ -1892,7 +1902,23 @@ body, timeoutMs: 45000, }); - setOcrPreview(normalizeOcrPreview(data)); + const preview = normalizeOcrPreview(data); + const isWalletPreview = preview.kind === 'wallet'; + const hasMiningSuggestion = preview.suggested.coins_total !== '' && preview.suggested.coins_total !== null; + const hasWalletSuggestion = preview.suggested_wallet.wallet_balance !== '' && preview.suggested_wallet.wallet_balance !== null; + const hasUsableOcrSuggestion = isWalletPreview ? hasWalletSuggestion : hasMiningSuggestion; + + setOcrPreview(preview); + + if (hasUsableOcrSuggestion && preview.confidence >= OCR_AUTO_SAVE_CONFIDENCE_THRESHOLD) { + if (isWalletPreview) { + await submitWalletSnapshotFromPreview(preview); + } else { + await submitMeasurement(true, preview); + } + return; + } + setMessage('OCR-Ergebnis geladen. Bei Bedarf direkt speichern.'); } catch (err) { setError(err.message);