fix: Mails vor der Einrichtung waren fuer immer ausserhalb des Suchfensters

Der Zeitstempel des letzten Abrufs wird auch dann gesetzt, wenn ein Abruf
nichts fand – und danach sucht Certain nur noch ab gestern. Wer das Postfach
einrichtet, nachdem die Mails schon da waren, findet sie nie: Der erste,
ergebnislose Abruf schiebt das Fenster an ihnen vorbei.

Jetzt gibt es "Aelteres nachholen": Es sucht die letzten 90 Tage und uebergeht
den Zeitstempel. Dass dabei nichts doppelt ankommt, sichert wie bisher die
Message-ID.

Ausserdem sagt die Meldung jetzt, AB WANN gesucht wurde. Bisher stand dort
"Stimmt der Ordner?" – die Frage war fast immer die falsche.

Und ein latenter Fehler, der im August nicht auffaellt: Das Suchdatum wurde mit
strftime("%b") gebaut, also mit dem Monatskuerzel in der Sprache des Servers.
IMAP verlangt die englischen; auf einem deutschen System haette die Suche im
Maerz, Mai, Oktober und Dezember nichts gefunden. Die Kuerzel stehen jetzt fest
im Code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-27 12:59:08 +02:00
co-authored by Claude Opus 5
parent ca63fef5c4
commit 60b8178c57
7 changed files with 115 additions and 21 deletions
+50
View File
@@ -444,3 +444,53 @@ def test_unklare_vorschlaege_werden_nicht_mitgebucht(admin, fake_imap):
admin.post("/api/inbox/book-all")
danach = admin.get("/api/inbox").json()
assert all(e["status"] == "unclear" for e in danach if e["id"] == unklare[0]["id"])
def test_suchdatum_ist_sprachunabhaengig():
"""IMAP verlangt die englischen Monatskuerzel. strftime("%b") richtet sich
nach der Sprache des Servers – auf Deutsch kaeme "Mär"/"Okt"/"Dez" heraus
und die Suche faende nichts. Im August faellt das nicht auf."""
from datetime import date
from app.services.mail_import import _imap_datum
assert _imap_datum(date(2026, 3, 9)) == "09-Mar-2026"
assert _imap_datum(date(2026, 5, 1)) == "01-May-2026"
assert _imap_datum(date(2026, 10, 31)) == "31-Oct-2026"
assert _imap_datum(date(2026, 12, 24)) == "24-Dec-2026"
def test_zeitraum_uebergeht_den_letzten_abruf(admin, monkeypatch):
"""Der Zeitstempel wird auch gesetzt, wenn ein Abruf nichts fand. Aeltere
Mails waeren danach fuer immer ausserhalb des Fensters – genau deshalb
muss sich der Zeitraum uebersteuern lassen."""
from datetime import date, datetime, timedelta, timezone
from app.database import SessionLocal
from app.models import MailSource
from app.services import mail_import
konto = _konto(admin, name="Nachholkonto", currency="CHF")
quelle = _postfach(admin)
admin.post(f"/api/mail/sources/{quelle['id']}/senders", json={
"from_contains": "raiffeisen", "account_id": konto["id"]})
# Ein Abruf hat schon stattgefunden – ohne Treffer.
db = SessionLocal()
try:
q = db.get(MailSource, quelle["id"])
q.last_poll_at = datetime.now(timezone.utc)
db.commit()
q = db.get(MailSource, quelle["id"])
eng, seit_eng = mail_import._suchkriterium(q)
weit, seit_weit = mail_import._suchkriterium(q, 90)
finally:
db.close()
assert seit_eng >= date.today() - timedelta(days=2), "sucht nur noch ab gestern"
assert seit_weit == date.today() - timedelta(days=90)
assert "SINCE" in eng and "SINCE" in weit
# Und der Endpunkt nimmt den Zeitraum an.
assert admin.post(f"/api/mail/sources/{quelle['id']}/fetch",
params={"tage": 400}).status_code == 400