Files
Predictalytics/docs/PLAN-Architektur-WebUI-Backend.md
T

11 KiB
Raw Permalink Blame History

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 02 begleiten das neue Design sofort. Phase 3 kann jederzeit vorgezogen werden (billig). Phase 4 erst zum Release — aber durch 03 ist dann nichts mehr umzubauen, nur zu ergänzen.