2 Paket Tracking
SurfaceScratcher edited this page 2026-05-19 18:50:15 +02:00

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_accounts mit tracking_scan_enabled = true
  • Pro Konto: IMAP SEARCH SINCE ab last_scan_at (oder Fallback MAIL_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 Dedup
  • order_infos — optionaler Shop-Kontext (shop_domain, order_number)
  • mail_accounts.last_scan_at — Zeitstempel des letzten erfolgreichen IMAP-Scans
  • mail_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.


Verwandte Issues

  • #140TrackingModule + Track17Provider
  • #141 — Status-Sync-Cron
  • #148 — Pro-Konto-Toggle
  • #230 — Web-UI
  • #231 — Tracker-Meta
  • #232 — Mail-Scanner-Glue
  • #233 — Manuelles Anlegen
  • #228 — Event-Historie persistieren + Timeline-UI