Table of Contents
- Paket-Tracking
- Überblick
- Komponenten
- TrackingParser (apps/api/src/modules/tracking-parser)
- MailScannerService (apps/api/src/modules/tracking/mail-scanner.service.ts)
- TrackingProvider-Abstraktion
- TrackingSyncService + Cron
- TodoGenerator → TrackingTodoWriter
- Manuelles Anlegen
- Konfiguration
- Datenbank
- Pro Mail-Konto an-/abschalten
- Verwandte Issues
Paket-Tracking
Das Tracking-Modul erkennt automatisch Versandbestätigungen in IMAP-Postfächern, ruft den Lieferstatus über externe Tracking-Provider ab und legt Todos an, sobald sich ein Paket bewegt.
Überblick
IMAP-Konto ─► MailScanner ─► TrackingParser ─► parcel_trackings
│
▼
TrackingSync (Cron)
│
▼ Status-Update
TodoGenerator ─► Todo
Drei eigenständige Cron-Jobs treiben den Flow:
| Cron | Intervall (Default) | Zuständigkeit |
|---|---|---|
MailScannerCron |
alle 15 min | Neue Mails nach Tracking-Nummern durchsuchen |
TrackingSyncCron |
konfigurierbar | Status der bekannten Sendungen aktualisieren |
TodoGeneratorService |
im Sync-Lauf | Aus Status-Änderungen Todos erzeugen |
Manuelle Anlage ist über POST /trackings jederzeit möglich.
Komponenten
TrackingParser (apps/api/src/modules/tracking-parser)
Regelbasierter Parser über Body/Subject einer Mail. Erkennt Carrier (DHL, UPS, DPD, Hermes, FedEx, GLS, Amazon, …) anhand von Absender-Domain plus Tracking-Nummer-Patterns. Optional liefert er orderNumber und shopDomain, die in order_infos landen.
MailScannerService (apps/api/src/modules/tracking/mail-scanner.service.ts)
- Iteriert über alle
mail_accountsmittracking_scan_enabled = true - Pro Konto:
IMAP SEARCH SINCEablast_scan_at(oder FallbackMAIL_SCAN_INITIAL_DAYS) - Pro Treffer: Parser → Dedup
(owner_sub, tracking_number)→INSERT parcel_trackings - Nach erfolgreichem Lauf:
last_scan_at = NOW() - Per-Account-Isolation: ein kaputter Account stoppt den Lauf nicht
TrackingProvider-Abstraktion
Interface TrackingProvider mit zwei Implementationen:
| Provider | Env-Var | Hinweis |
|---|---|---|
Track17Provider |
TRACK17_API_KEY |
Standard, eigene Tracking-Nummern registrieren |
AfterShipProvider |
AFTERSHIP_API_KEY |
Alternative, Carrier-Slugs werden gemappt |
Auswahl per TRACKING_PROVIDER=17track\|aftership (Default 17track).
TrackingSyncService + Cron
Holt für jede aktive Sendung den aktuellen Status beim Provider, schreibt last_status, last_event_at, delivered_at. Persistiert zusätzlich die vollständige Event-Historie (parcel_tracking_events, Dedup über UNIQUE (tracking_id, occurred_at, description)). Triggert anschließend den TodoGeneratorService für Statusänderungen, die für den User relevant sind.
TodoGenerator → TrackingTodoWriter
Beispiele für erzeugte Todos:
- „📦 Paket bei Nachbar abgeben“ (Status
delivered_neighbour) - „📬 Paket abholen“ (Status
available_for_pickup) - „⚠ Zustellung fehlgeschlagen“ (Status
failed_attempt)
Manuelles Anlegen
POST /trackings über die Web-/Mobile-App oder direkt per API. Die UI hat dafür ein klappbares „+ Paket"-Formular auf der Tracking-Übersicht. Felder:
trackingNumber(Pflicht)carrier(optional, sonst Auto-Detect über Provider)note(optional, freier Text)
Dedup wie beim Scanner: doppelte (owner_sub, trackingNumber) → 409 Conflict.
Konfiguration
| Env-Var | Default | Zweck |
|---|---|---|
TRACKING_PROVIDER |
17track |
Provider-Auswahl |
TRACK17_API_KEY |
— | API-Key 17track |
AFTERSHIP_API_KEY |
— | API-Key AfterShip |
MAIL_SCAN_CRON |
*/15 * * * * |
Cron-Expression Mail-Scanner |
MAIL_SCAN_DISABLED |
false |
Mail-Scanner komplett ausschalten |
MAIL_SCAN_INITIAL_DAYS |
7 |
Fallback-Fenster wenn last_scan_at NULL |
TRACKING_SYNC_CRON |
konfigurierbar | Cron-Expression Status-Sync |
Die Vault-Werte für die API-Keys liegen im server-stack-Repo unter inventory/host_vars/<host>/vault.yml und werden über templates/<host>.env.j2 in die .env gerendert.
Datenbank
Relevante Tabellen (Drizzle):
parcel_trackings— eine Zeile pro Sendung; UNIQUE(owner_sub, tracking_number)parcel_tracking_events— Event-Historie pro Sendung; UNIQUE(tracking_id, occurred_at, description)zur Deduporder_infos— optionaler Shop-Kontext (shop_domain,order_number)mail_accounts.last_scan_at— Zeitstempel des letzten erfolgreichen IMAP-Scansmail_accounts.tracking_scan_enabled— Pro Konto an-/abschaltbar
Migrationen: 0010_previous_purple_man.sql (note-Feld), 0011_overjoyed_expediter.sql (last_scan_at) und 0014_freezing_madelyne_pryor.sql (Event-Historie).
Pro Mail-Konto an-/abschalten
In der Web-/Mobile-UI unter Mail → Konto lässt sich das Auto-Scannen pro Konto über einen Switch deaktivieren. Backend-seitig setzt das mail_accounts.tracking_scan_enabled = false und schließt den Account aus dem nächsten Scanner-Lauf aus.