Mail-Graveyard/Codex-Briefing.md
2026-07-05 22:30:32 +02:00

115 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Codex-Briefing — Mail-Graveyard
Du baust ein Go-Single-Binary im Hausstil (wie WatchDove): `main.go` als
Orchestrator, nummerierte `backend/NN-*.go`, Server-gerendertes HTML + HTMX,
`config.json`, SQLite via `modernc.org/sqlite` (kein cgo). Das Gerüst steht;
fülle die `// TODO Codex`-Stellen. **Lies zuerst `Projektbeschreibung.md` die
5 harten Regeln sind bindend.**
## Bibliotheken (lean, keine Lawine)
- IMAP: `github.com/emersion/go-imap/v2` (+ `imapclient`)
- Parsen (Message-ID, Header, Text/HTML für Viewer): `github.com/emersion/go-message`
- SQLite: `modernc.org/sqlite`
- POP3-Fallback: `github.com/knadh/go-pop3`
- SMTP-Weiterleiten: `net/smtp` (stdlib) — keine Extra-Dependency
`go mod tidy` + `go mod vendor` (Offline-Bunker, wie im Template).
## Modul-Landkarte
| Datei | Inhalt |
|---|---|
| `main.go` | Flags (`--run`, `--watch`), LoadConfig→ConnectDB→InitAuth, Web oder CLI |
| `backend/00-router.go` | Routen + `renderShell` (Outlook-2013-Dreispalter) — **da steht schon das Layout** |
| `backend/01-config.go` | `config.json` (App + Forward-SMTP). Konten NICHT hier, sondern DB |
| `backend/02-database.go` | Schema + Account-CRUD + `copied`-Cache (Idempotenz) |
| `backend/03-auth.go` | Login + `AuthMiddleware` |
| `backend/04-imap-source.go` | Quelle: Ordnerbaum + Fetch `BODY[] FLAGS INTERNALDATE` |
| `backend/05-imap-target.go` | Ziel: `EnsureFolder` + `Append` (Flags + INTERNALDATE) |
| `backend/06-mbox.go` | mbox schreiben (Umzug) **und** lesen (Viewer) |
| `backend/07-migrate.go` | Motor: pro Konto/Ordner/Mail, Dedup, Doppel-Write, Fortschritt |
| `backend/08-viewer.go` | mbox im Browser: Liste, Lesen, Weiterleiten |
| `backend/09-smtp.go` | SMTP nur fürs Weiterleiten |
| `backend/10-pop3.go` | POP3-Fallback-Quelle (nur INBOX, nie DELE) |
## DB-Schema (SQLite)
```
accounts(id, name,
src_host, src_port, src_security, src_insecure, src_user, src_pass, src_proto,
dst_host, dst_port, dst_security, dst_insecure, dst_user, dst_pass,
mbox_dir, active)
folder_map(id, account_id, src_folder, dst_folder) -- optional, Vorrang vor Rollen-Automatik
copied(account_id, folder, message_id UNIQUE) -- Delta-Cache
jobs(id, account_id, started, finished, total, done, errors, state)
```
`src_security`/`dst_security` = `"tls"` | `"starttls"` | `"none"`.
`src_insecure`/`dst_insecure` = ungültige Zerts akzeptieren.
## Der Umzugs-Kern (07-migrate.go), Schritt für Schritt
1. Quelle öffnen: `src_proto=imap``OpenIMAPSource`, sonst `OpenPOP3Source`.
2. `Folders()` → rekursiver Ordnerbaum.
3. Pro Ordner: Zielordner via `MapSourceToTarget` (11-folders.go) bestimmen —
Rollen-Zuordnung gegen die vorhandenen Ziel-Ordner (keine Dubletten),
Trenner umhängen, `folder_map` als Override. Dann `EnsureFolder`.
4. `Fetch(folder)` streamend. Pro Mail: `AlreadyCopied(id,folder,msgID)`?
→ ja: überspringen. Nein: **beide** schreiben — `TargetMailbox.Append`
(IMAP, mit Flags+INTERNALDATE) **und** `MboxWriter.Append` (lokal), dann
`MarkCopied`. Fehler pro Mail zählen, nicht den ganzen Lauf abbrechen.
5. `jobs` fortschreiben (Browser pollt `/migrate/status` alle 3 s).
6. `--watch`: Schleife mit Pause; dank `copied` kopiert jeder Durchlauf nur Neues.
## UI — Outlook 2013 (Vorlage)
Look sitzt schon in `frontend-js/dist/style.css` + `renderShell`:
**Ribbon** (Outlook-Blau `#0072c6`) mit Reitern *Umzug · Postfächer · Betrachten
· Einstellungen*, darunter **Dreispalter**: links Ordnerbaum (Konto → Ordner),
Mitte Nachrichtenliste (ungelesen = fett blau), rechts Lesebereich; unten
Statusleiste. Flach, Segoe UI, blaue Auswahlzeile `#cde6f7`. Panes per HTMX
nachladen (`#tree` / `#list` / `#read`). Klassen stehen im CSS: `.tree-node`,
`.msg-row(.unread/.active)`, `.read-*`, `.grid/.input/.btn`.
Reiter **Postfächer** = Konten-CRUD (Formular wie WatchDove `targetForm`, Quelle-
und Ziel-Block, „Test"-Button prüft beide Logins). Reiter **Umzug** = Konten
starten + Fortschritt. Reiter **Betrachten** = mbox-Viewer, im Lesebereich ein
„Weiterleiten"-Button (öffnet Formular → `09-smtp.go`).
`frontend-js/dist/htmx.min.js` per Bun holen (wie Template) und mit einchecken.
## Sonderfälle — die drei Umzugs-Fallen (zwingend)
1. **Unverschlüsselte Alt-Provider.** Verbinden nach `src_security`:
`tls`=DialTLS (993), `starttls`=DialStartTLS (143), `none`=Dial (reiner
Klartext). `src_insecure``tls.Config{InsecureSkipVerify:true}` für
kaputte/selbstsignierte Zerts. Muss ohne TLS funktionieren — alte Hoster
können oft nichts anderes. (04/05-imap-*.go, POP3 analog 110/995.)
2. **Sonderzeichen in Ordnernamen.** IMAP-Ordner sind auf der Leitung
modified-UTF-7 (`Gelöschte``Gel&APY-schte`). go-imap dekodiert/kodiert das —
intern IMMER mit dem Klartext-Namen arbeiten, **nie doppelt kodieren**.
Hierarchie-Trenner (`.` vs `/`) je Server aus LIST lesen und beim Umhängen
übersetzen (`11-folders.go`).
3. **Standardordner nicht doppeln.** `11-folders.go` bildet jeden Ordner auf
eine Rolle ab (SPECIAL-USE `\Sent \Drafts \Junk \Trash \Archive`, sonst
mehrsprachige Namensliste). `MapSourceToTarget` sortiert Gesendet/Entwürfe/
Spam/Papierkorb/Archiv/Posteingang in den **vorhandenen** Rollen-Ordner des
Ziels statt „Gesendete Objekte" **neben** „Gesendete Elemente" zu legen.
Manuelles `folder_map` schlägt die Automatik.
## Sicherheit
Tool hält fremde IMAP-Passwörter und kann Mails senden. Default `bind=127.0.0.1`
+ Login. Falls je remote (hinter Caddy): `/vadmin`-Mail-2FA-Muster aus dem
Web-Deploy-Kit vorschalten. `config.json`/DB nie committen (`.gitignore` steht).
## Fertig-Kriterien (Durchstich zuerst)
1. **Durchstich:** ein Konto, nur `INBOX`, Quelle→Ziel-`APPEND` + mbox,
Message-ID-Dedup, zweimal laufbar ohne Dubletten.
2. Alle Ordner rekursiv + `EnsureFolder` im Ziel.
3. Konten-CRUD + Test-Button im Browser.
4. Viewer (Liste/Lesen) + Weiterleiten.
5. `--watch`-Delta-Schleife.
6. Optional: POP3-Fallback.