Prämien-Claim und Abgabe
Dies ist der vollständige Lebenszyklus einer einzelnen Prämie aus Juicer-Sicht – inklusive dessen, was die Plattform an jedem Schritt validiert.
Die fünf Phasen
open → claimed → picked_up → charging → ready_to_drop → completed
↓
payout
Eine Prämie kann auch in expired (Claim-TTL erreicht), canceled (Betreiberaktion) oder disputed (Betrugsflag plus Betreiberprüfung) fallen.
Phase 1: Open
Die Prämien-Engine läuft alle 5 Minuten. Für jedes aktivierte Unterkonto durchläuft sie jedes Kandidatenfahrzeug (niedriger SoC, Peak-Shortfall, SoH-Rotation) und entscheidet, ob eine Prämienzeile erstellt oder aktualisiert wird. Die Prämie hat:
- Auszahlungsbetrag in Cent
- Surge-Multiplikator
- Ablaufzeitstempel (TTL)
- Aktuelle Fahrzeugposition (GIST-indexiert)
- Status
open - Prognostizierter Peak-Shortfall (Phase 4)
Offene Prämien erscheinen auf der Karte des Juicers.
Phase 2: Claim
Der Juicer tippt Beanspruchen auf einem Pin.
Die Plattform ruft die DB-Funktion claim_bounty(p_bounty_id, p_juicer_id, p_claim_ttl_seconds) auf. Diese nimmt eine FOR UPDATE-Sperre auf Prämie und Juicer und validiert alle:
- Juicer
status = 'active' - Juicer
kyc_status = 'verified' - Juicer unter
max_concurrent_claims - Prämie
openund nicht abgelaufen - Fahrzeug hat frische Telemetrie (letzte Meldung in 30 Min)
- Fahrzeug nicht in aktiver Fahrt
- Installierter Pack nicht
maintenance/recalled - Juicer innerhalb
claim_radius_m(Standard 5 Mi, pro Unterkonto konfigurierbar) - Unterkonto stimmt überein (Cross-Tenant-Claims abgelehnt)
Bei Fehlschlag rollt die ganze Transaktion zurück und der Juicer erhält eine spezifische Fehlermeldung. Zwei Juicer können nicht beide gewinnen.
Bei Erfolg:
bounties.status = 'claimed',claimed_by,claimed_at,expires_at(60 Min TTL Standard)- Neue
juicer_sessions-Zeile im Statusclaimed - Best-effort-IoT-Befehl zur Drosselsperre wird gefeuert
Das Fahrzeug verschwindet sofort von allen anderen Juicer-Karten.
Phase 3: Aufnahme (Foto + GPS-Validierung)
Der Juicer fährt zum Fahrzeug und macht ein Aufnahmefoto mit sichtbarer Fahrzeug-ID. Er tippt Habe es.
Die Plattform validiert:
| Prüfung | Grenze | Falls fehlgeschlagen |
|---|---|---|
| Foto-GPS-Drift | ≤50 m sauber 50–200 m Warnung (+5 Fraud-Score) >200 m Block | Aufnahme abgelehnt, Claim bleibt offen bis TTL |
| Foto-Zeitstempel | innerhalb 5 Min vom Claim | Warnung, +3 |
| Foto-Hash-Kollision | Hash darf kein vorheriges Foto sein | Block – +20 |
| Fahrzeug-ID OCR | Fahrzeugnummer lesbar | Soft-Prüfung heute (Phase 4 wird härten) |
Bei Erfolg wechselt die Session zu picked_up. URL und Hash des Aufnahmefotos werden auf der juicer_sessions-Zeile gespeichert.
Warum zweimal validieren
Aufnahme-Validierung verhindert drei Fehlermuster gleichzeitig: (1) Claim ohne Anwesenheit (Radius-Spoof), (2) Stockfoto-Upload (Hash-Kollision), (3) Tage zwischen Claim und Aufnahme (Zeitstempel-Drift).
Phase 4: Transport und Laden
Der Juicer transportiert das Fahrzeug nach Hause oder zur Station. An Standard-Wandsteckdose anschließen.
Die Juicer-App fragt periodisch: Lädt noch?. Standard alle 30 Minuten. Endpunkt: POST /api/juicer/bounties/[id]/charge-checkin mit current_soc.
- Zwei verpasste Check-ins hintereinander → Claim läuft ab, Demerit.
- Check-in mit
current_soc < previous_soc→ markiert, manuelle Prüfung. - Check-in bei ≥95% → Status zu
ready_to_drop, Abgeben wird aktiv.
Die Session verfolgt pickup_soc, jüngsten SoC und Ladezeit in Sekunden.
Phase 5: Abgabe (Foto + GPS-Validierung)
Der Juicer fährt zu einer Abgabezone und parkt das Fahrzeug. Er macht ein Abgabefoto und tippt Abschließen.
Die Plattform validiert:
| Prüfung | Inhalt | Falls fehlgeschlagen |
|---|---|---|
| Abgabezonen-Polygon | GPS muss in aktiver Zone (PostGIS ST_Contains) sein | Block – Abgabe abgelehnt |
| Ladezeit-Plausibilität | Ladezeit vs. SoC-Delta mind. 0,6 Min/% | Block + manuelle Prüfung |
| Abgabefoto-Hash | Darf kein vorheriges Foto sein | Warnung, +20 |
Pack nicht maintenance | Pack darf nicht während Session markiert sein | Block + Anfechtung |
Die Zonen-Prüfung nutzt eine zones_containing_point-PostGIS-RPC über die aktiven Abgabezonen des Unterkontos. Abgabezonen sind eine Teilmenge des bestehenden Zonenmodells.
Bei allen bestandenen Prüfungen:
bounties.status = 'completed'juicer_sessions.state = 'completed',drop_soc,drop_gps,drop_photo_urlgespeichertjuicer_payouts-Zeile im Statusqueued(oderon_hold, falls Betrugsflag)- Drosselsperre wird aufgehoben – Fahrzeug normalisiert sich
Phase 6: Auszahlung
Auszahlungen werden alle 15 Minuten von juicer-payouts zu Stripe Connect ausgespült. Idempotenzschlüssel sichern Retries.
Für den Auszahlungsablauf siehe Juicer-Auszahlungen.
Was der Betreiber sieht
Die Juicer-Seite zeigt Live-Sessions pro Juicer mit Status und Dauer. Die Auszahlungen-Seite zeigt das Buch:
| Spalte | Bedeutung |
|---|---|
| Status | queued / paid / on_hold / reversed / canceled |
| Betrag | Netto an Juicer in Cent |
| Plattformgebühr | Levys Anteil |
| Stripe-Transfer-ID | Nach Auszahlung; Link zur Stripe |
| Session-ID | Klicken für vollständigen Claim → Abgabe |
Betreiber können halten, freigeben, stornieren oder rückbuchen.
Wie ein abgelaufener Claim aussieht
- TTL (Standard 60 Min nach Claim) →
bounties.statuszurück aufopen, Session aufexpired, 3-Punkte-Demerit. - Zwei verpasste Lade-Check-ins → gleiches Ergebnis, plus Notiz.
- Der
lifetime_no_shows-Zähler steigt.
Häufige Probleme
- "GPS zu weit" – Juicer mehr als 200 m vom Fahrzeug entfernt.
- "Abgabe außerhalb Zone" – GPS außerhalb erlaubter Abgabezone.
- "Ladezeit unplausibel" – weniger als 0,6 Min pro % SoC-Delta.
- "Prämie bereits beansprucht" – atomarer Claim sicherte nur einen.
- "Fahrzeug in Fahrt" – Miete startete zwischen Claim und Aufnahme. Claim läuft ab.