Docs: Konzepte/Plaene in docs/ mit Typ-Unterordnern buendeln

Root aufgeraeumt: alle Konzept-/Plan-/Fach-Dokumente nach docs/ verschoben,
organisiert nach Typ (wie fuer ein separates Docs-Repo vorgeschlagen, aber bewusst
in diesem Repo, damit Plan->umsetzende-Commits nachvollziehbar bleiben):
- docs/konzepte/       (KONZEPT-*)
- docs/umsetzungsplaene/ (UMSETZUNGSPLAN-*)
- docs/ideen/          (fruehe Ideen, Platzhalter)
- docs/pruefplaene/    (PRUEFPLAN-*)
- docs/steuer/         (Steuer-/Buchhaltungs-Doks, z.B. US-CPA-Fragebogen)
- docs/README.md       (Index/Konventionen)

Getrackte Plaene als Rename verschoben (History erhalten); zuvor untracked Konzept-/
Plan-Dateien jetzt versioniert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-14 10:15:08 +02:00
co-authored by Claude Opus 4.8
parent 1c3a364df2
commit c5f0b1d188
15 changed files with 1004 additions and 0 deletions
@@ -0,0 +1,117 @@
# Umsetzungsplan: On-Chain-Auto-Redeem (modulweise schaltbar)
> Stand: 2026-07-11
> Ziel: Gewonnene Positionen automatisch on-chain einlösen (Shares → USDC), als
> **Core-Baustein** mit **Aktivierung je Modul**. Richards Anforderung: In Testphasen
> neuer Module soll Auto-Redeem gezielt AUS bleiben können, um die Performance der
> Entwicklung manuell nachvollziehen zu können — ohne dass andere, etablierte Module
> ihren Automatismus verlieren.
> ⚠️ Höchste clob.md-Kritikalität: On-Chain-Signing mit echten Private Keys.
> Jede Phase: Backup/Commit vorher, Testmarkt/Kleinstbetrag zuerst.
---
## 1. Architektur: Queue statt Direktaufruf
Module redeemen nie selbst. Sie melden einlösbare Positionen in eine zentrale
Queue; ein Core-Worker arbeitet sie ab — nur für Module, deren Auto-Redeem aktiv ist.
```
Modul (RF-Monitor, CT-Sync, später DD) PolyTrader.Core
│ erkennt „Position gewonnen & aufgelöst" │
├── IRedeemQueue.Enqueue(RedeemRequest) ─────────────▶│ Tabelle core_redeem_queue
│ (immer! unabhängig vom Schalter) │
│ ▼
│ OnChainRedeemWorker (BackgroundService)
│ • nur Requests von Modulen mit AutoRedeemEnabled
│ • Rest bleibt als "Manual" sichtbar (UI-Liste)
▼ • CTF redeemPositions / NegRiskAdapter
UI je Modul: Pending-Redeems-Ansicht • Verifikation über USDC-Balance-Delta
```
**Warum immer enqueuen:** Auch bei deaktiviertem Auto-Redeem entsteht so eine
vollständige, je Modul gefilterte „zum Redeem bereit"-Liste (Dashboard/UI) — genau
die Übersicht, die Richard in Testphasen für die manuelle Betreuung will. Der
Schalter entscheidet nur, ob der Worker sie abarbeitet.
### 1.1 Datenmodell (`core_redeem_queue`)
| Feld | Inhalt |
|---|---|
| Id (auto) | PK |
| ModuleName | "ResolutionFarming" / "CopyTrading" / … |
| AccountId, TokenId, ConditionId | Ziel der Einlösung (ConditionId zwingend — für den Contract-Call) |
| IsNegRisk | Adapter-Wahl |
| SizeShares, ExpectedUsd | erwartete Auszahlung (Shares × 1.00) |
| Status | Pending / Processing / Done / Failed / Manual |
| Attempts, LastError, EnqueuedAt, CompletedAt, TxHash | Betrieb/Nachvollziehbarkeit |
### 1.2 Schalter
- **Je Modul:** `core_module_settings` (oder appsettings-Sektion) —
`AutoRedeem:ResolutionFarming = false`, `AutoRedeem:CopyTrading = false`
(Default IMMER aus; bewusstes Einschalten je Modul).
- **Global-Not-Aus:** `AutoRedeemGlobalEnabled` (analog GlobalTradingPaused,
Quickbar-Toggle) — schlägt alle Modul-Schalter.
- UI: Schalter je Modul in dessen Settings-Tab + Anzeige im Core-Dashboard,
welche Module aktiv sind.
## 2. Der On-Chain-Teil (`OnChainCtfService`, Core)
1. **Bibliothek:** Nethereum (bereits als Abhängigkeit im Projekt für EIP-712-Signing
vorhanden) — Contract-Calls über die bestehende Alchemy-RPC-Anbindung (Polygon).
2. **Aufrufe:** Standard-Markt: ConditionalTokens `redeemPositions(collateral,
parentCollectionId=0x0, conditionId, indexSets)`; NegRisk-Markt: über den
NegRisk-Adapter. **Contract-Adressen + ABI + indexSets-Ermittlung bei Umsetzung
zwingend aus https://docs.polymarket.com (Developer/CTF) verifizieren — nicht aus
dem Gedächtnis kodieren.** Die USDC-/CTF-Adressen als Konstanten mit Quellenangabe.
3. **Gas:** Wallet braucht POL. Vor jedem Call Balance-Check; unter Schwelle
(Setting, z. B. 0.5 POL) → Request auf `Manual` + Threema-Warnung „POL nachfüllen".
Gas-Preis: Standard-Estimation, Cap als Setting.
4. **Verifikation = Wahrheit:** Ein Redeem gilt erst als `Done`, wenn (a) die Tx
bestätigt ist UND (b) das USDC-Balance-Delta ≈ ExpectedUsd (Toleranz) gemessen
wurde. Sonst `Failed` mit Fehlertext.
5. **Retry:** max. 3 Versuche mit Backoff (1/10/60 min), danach `Manual` + Threema.
Idempotenz beachten: vor jedem Versuch prüfen, ob die Position on-chain überhaupt
noch einlösbar ist (bereits redeemte Shares → als Done werten, nicht als Fehler).
## 3. Modul-Integration
### 3.1 ResolutionFarming (erster Nutzer)
`FarmingResolutionMonitorService` setzt heute `RedeemStatus = "Pending"` am
RfClosedTrade. Ergänzung: beim Schließen eines Gewinners → `IRedeemQueue.Enqueue`.
Worker-Callback (oder Status-Poll) aktualisiert `RedeemStatus` (Pending → Redeemed/
Manual/Failed) → sichtbar im Historie-Tab. **Wichtig für Richards Testphasen-
Anforderung:** Der realisierte PnL ist bereits bei Resolution gebucht; der Redeem
ändert nur die Kapitalverfügbarkeit. Die Performance-Auswertung bleibt also mit und
ohne Auto-Redeem identisch — nur die Bankroll-Rotation unterscheidet sich.
### 3.2 CopyTrading (zweiter Nutzer)
Im `TraderMonitorService` existiert die Stelle bereits: der auskommentierte
Python-Redeem-Block im Resolution-Fallback („bereit für manuellen Redeem")
— dort `Enqueue` statt Kommentar. Gleicher PnL-Hinweis wie oben.
### 3.3 Künftige Module
Contract: Ein Modul, das Positionen bis Resolution hält, ruft bei „gewonnen &
aufgelöst" genau einmal `Enqueue` und liest optional den Status zurück. Mehr nicht.
## 4. Phasen & Akzeptanzkriterien
| Phase | Inhalt | Akzeptanz |
|---|---|---|
| RD-1 | Queue-Tabelle + IRedeemQueue + Modul-Schalter + UI-Pending-Liste (noch KEIN On-Chain-Code) | Module enqueuen; Liste zeigt je Modul „bereit zum Redeem"; Schalter sichtbar; 100 % ohne Live-API testbar |
| RD-2 | `OnChainCtfService` gegen Polygon: zuerst READ-only (Balance, Einlösbarkeits-Check) | Balance-/Zustandsabfragen stimmen gegen Polygonscan |
| RD-3 | Erster echter Redeem: EIN Testmarkt, Kleinstbetrag, manuell getriggert (Button an der Pending-Liste) | Tx bestätigt, USDC-Delta verifiziert, Status Done |
| RD-4 | Worker-Automatik scharf für RF (Schalter an), CT folgt nach Beobachtung | 1 Woche fehlerfreier Betrieb, Failed-Quote < 5 %, POL-Warnung getestet |
## 5. Leitplanken
1. `.agents/rules/clob.md` gilt verschärft: Private-Key-Nutzung außerhalb des
erprobten Order-Signing-Pfads. Jede Phase einzeln committen; RD-3 nie
überspringen.
2. Der Worker fasst NUR Queue-Einträge an — er scannt nie selbst Positionen
(klare Verantwortung: Module erkennen, Core löst ein).
3. Alle Beträge/TxHashes loggen; Threema-Tageszusammenfassung „X Redeems, Y USDC
freigesetzt, Z manuell offen".
4. Manuelle Redeems (über die Website) müssen erkannt werden: Einlösbarkeits-Check
in 2.5 markiert extern eingelöste Einträge als Done statt Failed.