diff --git a/app/templates/index.html b/app/templates/index.html
index 2aeb638..0c06336 100644
--- a/app/templates/index.html
+++ b/app/templates/index.html
@@ -889,6 +889,33 @@
+
+
+
+
π¦ Batch-Analyse
+
+ Analysiert automatisch die neuesten ungeprΓΌften AntrΓ€ge eines Bundeslandes.
+
+
+
+
+
+
+
+
@@ -1318,6 +1345,64 @@
}
}
+ // βββ Batch-Analyse ββββββββββββββββββββββββββββββββββββββββββ
+ async function startBatch() {
+ const bl = document.getElementById('batch-bundesland').value;
+ const limit = document.getElementById('batch-limit').value;
+ const btn = document.getElementById('batch-btn');
+ const status = document.getElementById('batch-status');
+
+ btn.disabled = true;
+ btn.textContent = 'β³ Wird gestartet...';
+ status.innerHTML = '';
+
+ try {
+ const resp = await fetch('/api/batch-analyze', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/x-www-form-urlencoded'},
+ body: `bundesland=${bl}&limit=${limit}`
+ });
+ if (resp.status === 401) {
+ status.innerHTML = 'π Bitte zuerst anmelden.';
+ btn.disabled = false; btn.textContent = 'π Batch starten';
+ return;
+ }
+ const data = await resp.json();
+ if (data.status === 'batch_enqueued') {
+ status.innerHTML = `
+ β ${data.enqueued} AntrΓ€ge in die Queue eingereiht
+ ${data.skipped_existing > 0 ? `
${data.skipped_existing} bereits bewertet (ΓΌbersprungen)` : ''}
+
Die Analyse lΓ€uft im Hintergrund. Ergebnisse erscheinen nach und nach in der Liste.
+ `;
+ // Queue-Status pollen
+ pollBatchQueue(status);
+ } else {
+ status.innerHTML = `β ${data.detail || 'Fehler'}`;
+ }
+ } catch (e) {
+ status.innerHTML = `β ${e.message}`;
+ }
+ btn.disabled = false; btn.textContent = 'π Batch starten';
+ }
+
+ async function pollBatchQueue(statusEl) {
+ for (let i = 0; i < 200; i++) {
+ await new Promise(r => setTimeout(r, 5000));
+ try {
+ const qs = await fetch('/api/queue/status').then(r => r.json());
+ if (qs.pending === 0) {
+ statusEl.innerHTML += `
β Alle Jobs abgeschlossen (${qs.processed_total} verarbeitet)`;
+ loadAssessments(); // Liste aktualisieren
+ return;
+ }
+ statusEl.querySelector('.queue-progress')?.remove();
+ statusEl.insertAdjacentHTML('beforeend',
+ `
β³ ${qs.pending} Jobs in der Queue, ~${Math.round(qs.estimated_wait_seconds/60)} Min. verbleibend`
+ );
+ } catch { break; }
+ }
+ }
+
// βββ Merkliste (#94) ββββββββββββββββββββββββββββββββββββββββ
async function loadBookmarksList() {
const container = document.getElementById('bookmarks-content');