diff --git a/app/routers/filters.py b/app/routers/filters.py index 8fc36b8..c99e8cb 100644 --- a/app/routers/filters.py +++ b/app/routers/filters.py @@ -1,10 +1,10 @@ from fastapi import APIRouter, Depends, HTTPException -from sqlalchemy import func +from sqlalchemy import func, text from sqlalchemy.orm import Session import logging -from app.database import get_db +from app.database import engine, get_db from app.models.db_models import ( Account, FilterAction, @@ -33,6 +33,27 @@ def _reset_processed_for_rule(db: Session, rule_id: int) -> int: router = APIRouter(prefix="/api/filters", tags=["filters"]) +@router.post("/reset-all-processed") +def reset_all_processed(db: Session = Depends(get_db)): + """Setzt den 'verarbeitet'-Status ALLER Mails zurück — alle Regeln bewerten + beim nächsten Poll wieder jede Mail im Ordner neu. Sicher, weil schon + verschobene Mails nicht mehr in der Quelle liegen und daher nicht erneut + verschoben werden können. Nutzt DROP+CREATE statt DELETE, damit auch + bei Millionen Zeilen sekundenschnell.""" + try: + row_count = db.query(ProcessedMail).count() + db.close() # Sitzung freigeben, damit DDL nicht am Lock hängt + with engine.begin() as conn: + ProcessedMail.__table__.drop(conn, checkfirst=True) + ProcessedMail.__table__.create(conn, checkfirst=True) + conn.execute(text("PRAGMA wal_checkpoint(TRUNCATE)")) + logger.info("ProcessedMail vollständig zurückgesetzt (%d Einträge entfernt)", row_count) + return {"reset": row_count} + except Exception as e: + logger.exception("reset-all-processed fehlgeschlagen") + raise HTTPException(500, f"Fehler beim Zurücksetzen: {e}") + + @router.post("/retry-failed") def retry_failed_fetches(account_id: int | None = None, db: Session = Depends(get_db)): """Löscht ProcessedMail-Einträge für UIDs, für die es einen ERROR-Log diff --git a/app/templates/filters.html b/app/templates/filters.html index bb5b605..2c931ab 100644 --- a/app/templates/filters.html +++ b/app/templates/filters.html @@ -224,6 +224,8 @@ function renderFilters() { let html = `
+