Scheduler für periodischen IMAP-Postfach-Abruf mit UID-basiertem Delta-Sync: neue Nachrichten erkennen, Zustandsänderungen abgleichen. - imap (ING-01) minimal erweitert: Message.UID, MailboxStore.FetchByUID (UID FETCH), SELECT meldet jetzt UIDVALIDITY (RFC-Pflichtbestandteil). Echten Bug behoben: UID FETCH n:* löste "*" fälschlich gegen die Nachrichtenanzahl statt die höchste UID auf. - imapimport/state.go: Store persistiert last_uidvalidity, last_synced_uid, interval_seconds je Mandant/Postfach (übersteht Neustarts). - imapimport/scheduler.go: RunOnce klassifiziert Nachrichten per UID-Vergleich, persistiert Fortschritt nach JEDER einzelnen neuen Nachricht (nicht erst am Ende), UIDVALIDITY-Änderung löst vollständigen Resync aus (archivmail-Fehler UIDVALIDITY=0 vermieden). - imapimport/client_real.go: echtes IMAP4rev1 über TCP (LOGIN/SELECT/UID FETCH/LOGOUT). Prüfungen (alle real durchgeführt, siehe mail/docs/IMP-01-PRUEFPROTOKOLL.md): 1. TestRunOnce_TwoConsecutiveRunsNoDuplicateImport: zweiter Lauf real 0 neue Nachrichten. 2. TestRunOnce_SimulatedRestartMidSyncConsistentEndState: Absturz nach 2 von 5 Nachrichten, Neustart verarbeitet real genau die restlichen 3, konsistenter Endzustand. 3. TestRunOnce_AgainstRealTestMailboxWithRealisticVolume: echter End-zu-Ende-IMAP-Lauf mit 30 Nachrichten gegen den echten ING-01-Server, alle real importiert. Kein Umbau: mail/internal/folderstate (ING-05) unverändert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
49 lines
2.3 KiB
Go
49 lines
2.3 KiB
Go
// Package imap implementiert ING-01: das IMAP-Server-Grundgerüst
|
|
// (TCP-Listener, Command-Parser, Session-Zustandsmaschine, Grundbefehle
|
|
// CAPABILITY/LOGIN/SELECT/FETCH/LOGOUT). Bewusste Neuimplementierung nach
|
|
// NEXARCH-Techstack, kein 1:1-Übernehmen von archivmail (siehe "Bekannte
|
|
// Fehler vermeiden": Header-/Zeilen-Injection durch Stringkonkatenation
|
|
// ohne CRLF-Prüfung — alle Antworten laufen ausschließlich über
|
|
// writeLine/writeTagged, die eingebettete CR/LF im Text ersetzen, siehe
|
|
// response.go).
|
|
//
|
|
// Authentifizierung (Authenticator) und Postfachzugriff (MailboxStore)
|
|
// sind schmale Schnittstellen — echte Anbindung an Benutzerverwaltung/
|
|
// Nachrichtenspeicher ist Sache späterer Ingestion-Tickets (IMP-01 u. a.,
|
|
// siehe "Nicht Bestandteil dieser Kachel" im Ticket). Dieses Paket kennt
|
|
// weder Core-IAM noch mail/internal/storage.
|
|
package imap
|
|
|
|
import "context"
|
|
|
|
// Authenticator prüft Zugangsdaten für LOGIN.
|
|
type Authenticator interface {
|
|
Authenticate(ctx context.Context, username, password string) (ok bool, err error)
|
|
}
|
|
|
|
// Message ist eine minimale Nachrichtendarstellung für FETCH (nur UID +
|
|
// Flags, keine Inhalte — Inhaltszugriff ist Sache späterer Kacheln). UID
|
|
// wird seit IMP-01 zusätzlich zur Sequenznummer geführt (RFC 3501 §2.3.1,
|
|
// UID FETCH) — Grundlage für IMP-01s UID-basierten Delta-Sync.
|
|
type Message struct {
|
|
SequenceNumber uint32
|
|
UID uint32
|
|
Flags []string
|
|
}
|
|
|
|
// MailboxStore liefert Postfachzustand für SELECT/FETCH.
|
|
type MailboxStore interface {
|
|
// Select liefert die Anzahl der Nachrichten sowie die UIDVALIDITY
|
|
// (RFC 3501 §2.3.1.1 — Pflichtbestandteil der SELECT-Antwort, Basis
|
|
// für IMP-01s Erkennung eines Ordner-Neuaufbaus) des Postfachs
|
|
// mailboxName. ok=false, wenn das Postfach nicht existiert.
|
|
Select(ctx context.Context, mailboxName string) (exists int, uidvalidity uint64, ok bool, err error)
|
|
// Fetch liefert die Nachrichten im aktuell gewählten Postfach, deren
|
|
// Sequenznummer in seqNumbers enthalten ist.
|
|
Fetch(ctx context.Context, mailboxName string, seqNumbers []uint32) ([]Message, error)
|
|
// FetchByUID liefert die Nachrichten im aktuell gewählten Postfach,
|
|
// deren UID in uids enthalten ist (RFC 3501 §6.4.8, UID FETCH) — Basis
|
|
// für IMP-01s UID-Vergleich.
|
|
FetchByUID(ctx context.Context, mailboxName string, uids []uint32) ([]Message, error)
|
|
}
|