helpyourneighbour/docs/dispute-flow.md

3.9 KiB

Vertrags-/Dispute-Flow nach Deal-Abschluss

Diese Doku definiert den verbindlichen Konfliktprozess nach einem abgeschlossenen Deal.

Ziel

  • Streitfaelle standardisiert bearbeiten
  • Entscheidungen nachvollziehbar und auditierbar machen
  • Klare Eskalationspfade fuer User und Moderation

Scope

Gilt fuer alle Deals im Status agreed oder completed, bei denen eine Partei einen Konflikt meldet.

Dispute-Statusmodell

Ein Dispute durchlaeuft genau diese Stati:

  1. open
    Fall wurde erstellt, Basisdaten vorhanden.
  2. evidence
    Evidenzphase aktiv (Dateien, Chatverlauf, Zahlungsbelege, Fotos).
  3. mediation
    Moderierte Klaerung/Schlichtung laeuft.
  4. resolved
    Endentscheid dokumentiert (z. B. refund, partial_refund, reject).
  5. cancelled
    Fall durch Melder zurueckgezogen (nur vor finaler Entscheidung).

Rollen und Rechte

  • requester und helper: duerfen Dispute eroeffnen, Evidenz einreichen, Kommentare hinterlassen.
  • moderator: darf in mediation ueberfuehren und final entscheiden.
  • admin: darf Entscheidungen uebersteuern (mit Pflicht zur Begruendung im Audit-Log).

Mindestdaten pro Streitfall

Beim Erstellen eines Disputes sind mindestens erforderlich:

  • dealId
  • openedByUserId
  • reasonCode (z. B. NO_SHOW, QUALITY_ISSUE, PAYMENT_DISPUTE, ABUSE)
  • summary (kurze, strukturierte Beschreibung)
  • requestedOutcome (refund, partial_refund, complete_work, other)

Evidenzregeln

  • Jede Evidenz wird als Event mit Zeitstempel gespeichert.
  • Dateien werden ueber Referenzen (storageKey, contentHash) protokolliert.
  • Nachtraegliche Aenderungen an Evidenz sind verboten; nur neue Event-Eintraege.

Entscheidungs- und Eskalationsregeln

  • SLA-Vorschlag:
    • Erstreaktion: < 24h
    • Mediation starten: < 72h
    • Finalentscheid: < 7 Tage nach vollstaendiger Evidenz
  • Auto-Eskalation:
    • Falls in evidence > 72h keine Aktivitaet: Reminder
    • Falls in mediation > 7 Tage offen: Escalate an Admin
  • Jeder Finalentscheid braucht:
    • decision
    • decidedByUserId
    • decisionReason
    • decidedAt

Auditierbarkeit und Reproduzierbarkeit

Zur Nachvollziehbarkeit werden zwei Ebenen persistiert:

  1. Current State in disputes
  2. Immutable History in dispute_events

Vorgeschlagenes Datenmodell (SQL-Skizze)

CREATE TABLE disputes (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  deal_id BIGINT NOT NULL,
  opened_by_user_id BIGINT NOT NULL,
  status ENUM(open,evidence,mediation,resolved,cancelled) NOT NULL DEFAULT open,
  reason_code VARCHAR(64) NOT NULL,
  summary TEXT NOT NULL,
  requested_outcome VARCHAR(64) NOT NULL,
  final_decision VARCHAR(64) NULL,
  final_reason TEXT NULL,
  decided_by_user_id BIGINT NULL,
  decided_at TIMESTAMP NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (deal_id) REFERENCES deals(id),
  FOREIGN KEY (opened_by_user_id) REFERENCES users(id)
);

CREATE TABLE dispute_events (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  dispute_id BIGINT NOT NULL,
  event_type VARCHAR(64) NOT NULL,
  actor_user_id BIGINT NOT NULL,
  payload_json JSON NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (dispute_id) REFERENCES disputes(id),
  FOREIGN KEY (actor_user_id) REFERENCES users(id)
);

API-Endpunkte (Plan)

  • POST /disputes -> Dispute erstellen
  • POST /disputes/{id}/evidence -> Evidenz anhängen
  • POST /disputes/{id}/status -> Statuswechsel (rollenbasiert)
  • POST /disputes/{id}/resolve -> Finalentscheid
  • GET /disputes/{id} -> aktueller Fallstatus
  • GET /disputes/{id}/events -> vollstaendige Historie

Definition of Done fuer Implementierung

  • Statusmaschine serverseitig durchgesetzt
  • Jede relevante Aktion erzeugt dispute_events-Eintrag
  • Finalentscheid ist inklusive Begruendung auditierbar
  • OpenAPI um Dispute-Endpunkte erweitert
  • Contract-Tests fuer Happy Path + Eskalation vorhanden