WebUI Redesign and Component 1: category mapper fixes
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# Plan: Drei-Schichten-Architektur (Core / Lokal / Public)
|
||||
|
||||
> Stand: 2026-07-12 · Status: **Architektur bestätigt** (Nutzer-Entscheidung), Implementierung
|
||||
> schrittweise. Kein Code in diesem Schritt.
|
||||
> Kontext: Neues WebUI-Design (mit Claude Design vorbereitet) wird nach der Schicht-Trennung
|
||||
> schrittweise implementiert. Public-Release ist noch fern, aber alles wird dafür vorbereitet.
|
||||
|
||||
## 0. Bestätigte Architektur
|
||||
|
||||
Drei Schichten mit **genau einer** Integrationsschnittstelle zwischen intern und öffentlich:
|
||||
**der Datenbank**.
|
||||
|
||||
```
|
||||
┌─────────────────────────── LOKAL (eigener Rechner/LAN) ───────────────────────────┐
|
||||
│ │
|
||||
│ Schicht 1: CORE Schicht 2: LOKALE API + WebUI │
|
||||
│ ───────────────── ─────────────────────────── │
|
||||
│ Crawler, Worker, PnL-Engine, volle API (Read + Control), │
|
||||
│ Analyse, Ingest keine Auth (localhost), │
|
||||
│ │ schreibt serviert WebUI-SPA, │
|
||||
│ ▼ zum Testen von Analysen & Design │
|
||||
│ ┌──────────────────┐ liest/schreibt ▲ │
|
||||
│ │ Analyse-DB │◄────────────────────────┘ │
|
||||
│ └────────┬─────────┘ │
|
||||
│ │ (nur SELECT-Grant) │
|
||||
└────────────┼──────────────────────────────────────────────────────────────────────┘
|
||||
│ ← EINZIGE Verbindung nach außen: read-only DB-Zugriff
|
||||
┌────────────┼──────────────────────── EXTERNER WEBSERVER ───────────────────────────┐
|
||||
│ ▼ │
|
||||
│ Schicht 3: PUBLIC API + WebUI │
|
||||
│ ──────────────────────────── │
|
||||
│ nur Read-Endpunkte (identisch zur lokalen Read-Seite), │
|
||||
│ Auth + Accounts, öffentliches Rate-Limiting, TLS, │
|
||||
│ serviert dasselbe WebUI-SPA │
|
||||
│ │ read-only │ read/write │
|
||||
│ ▼ ▼ │
|
||||
│ [Analyse-DB, RO] [User-DB (Accounts), separat] │
|
||||
└────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Kernprinzipien (aus der Nutzer-Entscheidung):**
|
||||
- **Core ist rein lokal** und die einzige Instanz, die in die Analyse-DB **schreibt**.
|
||||
- **Public spricht ausschließlich mit der Datenbank** — nie mit dem Core-Prozess, nie mit der
|
||||
lokalen API. Public bekommt einen **read-only** DB-User auf die Analyse-DB und eine
|
||||
**separate User-DB** für Accounts.
|
||||
- **Lokale und Public WebUI sind optisch UND funktional gleich** (auf der Analyse-/Ansichtsseite),
|
||||
damit neue Analysen und Designs lokal getestet werden und 1:1 öffentlich aussehen.
|
||||
|
||||
## 1. Wie „identisch" technisch erreicht wird
|
||||
|
||||
Damit beide WebUIs garantiert gleich sind, wird die **Read-/Analyse-Seite genau einmal** gebaut
|
||||
und von beiden Hosts wiederverwendet — kein Duplizieren:
|
||||
|
||||
1. **Geteilte Read-API-Library.** `Predictalytics.Api` ist bereits eine Library. Die
|
||||
Endpoint-Registrierung wird in zwei Gruppen gespalten:
|
||||
- `MapReadEndpoints()` — **die Analyse-/Ansichts-Endpunkte** (Trader-Liste/-Detail/-Profil/
|
||||
-Positionen, Markets, Dashboard, Search, Watchlist-Ansicht, Traits). Wird von **beiden**
|
||||
Hosts registriert.
|
||||
- `MapControlEndpoints()` — **schreibende/steuernde** Endpunkte (Jobs-Trigger, `/api/dev`,
|
||||
Trader-Anlage, Watchlist-Mutation, Priority, AI-Analyse-Trigger). Wird **nur lokal**
|
||||
registriert.
|
||||
2. **Ein einziges WebUI-SPA-Artefakt.** Dasselbe Build wird von der lokalen und der öffentlichen
|
||||
Schicht ausgeliefert. Es ist reiner API-Client (kein Server-Code, keine DB-Kenntnis).
|
||||
3. **Capability-gesteuerte Admin-Bedienelemente.** Da die Control-Endpunkte öffentlich fehlen,
|
||||
fragt das SPA beim Start eine `GET /api/capabilities` ab (`{ canControl: bool, authRequired: bool }`)
|
||||
und blendet Admin-Aktionen (Sync/Analyze/Deep-Resync/Trader-Anlegen) nur ein, wenn vorhanden.
|
||||
→ Analyse-Ansichten sind überall identisch; nur die lokalen Steuer-Buttons fehlen öffentlich.
|
||||
|
||||
> **Wichtiger Audit-Punkt vor dem Teilen:** Manche „Read"-Endpunkte haben heute versteckte
|
||||
> Nebenwirkungen. Beispiel: `GET /api/traders/{id}/deep-dive` **holt Preis-Historie vom Provider
|
||||
> und speichert Snapshots** — also ein Schreibzugriff **und** ein externer API-Call. Solche
|
||||
> Endpunkte sind **nicht** public-tauglich (read-only DB verbietet den Write, und Public darf
|
||||
> Polymarket nicht anrufen). Vor dem Aufnehmen in `MapReadEndpoints()` jeden Endpunkt auf
|
||||
> versteckte Writes/Provider-Calls prüfen; die Public-Read-Seite muss **rein aus persistierten
|
||||
> Daten** bedienbar sein (das `/profile`-Design aus FIXPLAN E ist genau deshalb „persisted-only").
|
||||
|
||||
## 2. Was heute wo läuft (Ist → Ziel)
|
||||
|
||||
- **Heute:** Core + Lokale API + WebUI sind **ein** Prozess (WinFormsHost/EmbeddedWebServer:
|
||||
Worker + volle API + `wwwroot`-SPA, localhost, keine Auth, CORS `*`). Public existiert nicht.
|
||||
- **Ziel Lokal:** bleibt bequem **ein** Prozess (Core-Worker + Lokale API + WebUI zusammen ist
|
||||
zum Testen praktisch). Wichtig ist nur die **Code-Schichtung** (Read-Library getrennt von
|
||||
Control/Core), damit Public die Read-Library **ohne** Core/Worker/Control referenzieren kann.
|
||||
- **Ziel Public:** eigener schlanker Host (neues Projekt `Predictalytics.PublicApi`), der
|
||||
`MapReadEndpoints()` + Auth registriert, das SPA ausliefert, und **nur** die read-only
|
||||
Analyse-DB + die User-DB kennt.
|
||||
|
||||
## 3. Implementierungsplan (schrittweise)
|
||||
|
||||
### Phase 0 — Endpunkte klassifizieren & Read/Control trennen (Fundament, klein)
|
||||
- [ ] Jeden Endpunkt in `docs/API.md` als **Read** (public-tauglich) oder **Control** (nur lokal)
|
||||
markieren. Kandidaten Control: alle `POST/PUT/DELETE`, `/api/dev/*`, Job-Trigger.
|
||||
- [ ] Auf **versteckte Writes/Provider-Calls** in Read-Endpunkten prüfen (Deep-Dive!) und
|
||||
bereinigen oder als Control einstufen.
|
||||
- [ ] `MapPredictalyticsEndpoints()` in `MapReadEndpoints()` + `MapControlEndpoints()` splitten
|
||||
(rein struktureller Refactor, Verhalten unverändert; bestehende Tests bleiben grün).
|
||||
- [ ] `GET /api/capabilities` einführen.
|
||||
|
||||
### Phase 1 — WebUI als sauberes, gemeinsames SPA (parallel zum neuen Design)
|
||||
- [ ] Neues Design als **ein statisches Artefakt** bauen, reiner API-Client, `API_BASE`
|
||||
konfigurierbar (heute `''` = gleiche Origin bleibt lokal gültig).
|
||||
- [ ] Admin-Aktionen an `capabilities.canControl` koppeln.
|
||||
- [ ] Trait-Chips/-Filter im Design vorsehen — **erscheinen erst, wenn Backend-D2 steht**
|
||||
(kein UI-Bug, das Backend liefert Traits noch nicht).
|
||||
|
||||
### Phase 2 — Lokale Grenze härten (klein, jetzt schon sinnvoll)
|
||||
- [ ] CORS von `AllowAnyOrigin` auf konfigurierte Origin-Whitelist umstellen.
|
||||
- [ ] Bind-Adresse explizit (localhost/LAN), nie `0.0.0.0` ohne Firewall; Konfig-Kommentar
|
||||
„NIEMALS ins Internet — das ist die interne Schicht".
|
||||
|
||||
### Phase 3 — DB für Public vorbereiten (mittel, kann früh passieren)
|
||||
- [ ] **Read-only DB-User** auf der Analyse-DB anlegen (nur `SELECT`). Der Nutzer führt das SQL
|
||||
selbst aus (Grant-Statements liefern wir).
|
||||
- [ ] `AppDbContext` public-seitig read-only konfigurieren (read-only Connection; keine
|
||||
Migrations, kein SaveChanges). Sicherstellen, dass die Read-Endpunkte ohne Writes auskommen.
|
||||
- [ ] **Schema-Kopplung dokumentieren:** Weil Public direkt auf der Analyse-DB liest, ist das
|
||||
DB-Schema jetzt eine **Vertragsfläche**. Schema-Änderungen im Core müssen die Public-Read-
|
||||
Views berücksichtigen (Views/stabile Spalten als Puffer erwägen, damit interne
|
||||
Refactorings die öffentliche Sicht nicht brechen).
|
||||
|
||||
### Phase 4 — Public-Host bauen (groß, wenn Release näher rückt)
|
||||
- [ ] Neues Projekt `Predictalytics.PublicApi` (eigener Host, TLS, öffentliche Bind-Adresse).
|
||||
- [ ] `MapReadEndpoints()` + **Auth/Accounts** (separate **User-DB**; Passwörter/Sessions nach
|
||||
Stand der Technik — Secret-Handling lebt **nur hier**, nie im Core).
|
||||
- [ ] Öffentliches **Rate-Limiting & Quotas pro Account** (getrennt vom internen Polymarket-Limiter).
|
||||
- [ ] Mandanten-Sicht: Kunde sieht seine Watchlist/kopierten Master, nicht das gesamte Universum.
|
||||
- [ ] Dasselbe WebUI-SPA ausliefern.
|
||||
|
||||
## 4. Explizite Nicht-Ziele / Fallen
|
||||
- ❌ Public bekommt **keinen** Zugriff auf Core-Prozess, lokale API oder Control-Endpunkte.
|
||||
- ❌ Public bekommt **keinen** Schreibzugriff auf die Analyse-DB (nur `SELECT`).
|
||||
- ❌ **Kein** Nachrüsten von Kunden-Auth auf die lokale Vollschicht — Auth lebt nur im Public-Host.
|
||||
- ❌ Read-Endpunkte machen **keine** Provider-Calls und **keine** Writes (sonst public-untauglich).
|
||||
- ❌ WebUI kennt die DB nicht — immer nur über die API.
|
||||
|
||||
## 5. Reihenfolge / Aufwand
|
||||
1. **Phase 0** (klein): Read/Control-Split + Capabilities + Deep-Dive-Audit. **Jetzt** — es ist
|
||||
die Voraussetzung dafür, dass das neue Design von Anfang an sauber sitzt.
|
||||
2. **Phase 1+2** (klein, parallel): neues SPA als gemeinsames Artefakt, lokale Grenze härten.
|
||||
3. **Phase 3** (mittel): read-only DB-User + Schema-als-Vertrag dokumentieren.
|
||||
4. **Phase 4** (groß, später): Public-Host mit Auth/User-DB.
|
||||
|
||||
Phase 0–2 begleiten das neue Design sofort. Phase 3 kann jederzeit vorgezogen werden (billig).
|
||||
Phase 4 erst zum Release — aber durch 0–3 ist dann nichts mehr umzubauen, nur zu ergänzen.
|
||||
Reference in New Issue
Block a user