# 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)

```sql
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
