Files
Predictalytics/docs/archiv/PLAN-Architektur-WebUI-Backend.md
RichardandClaude Opus 5 6975720dc6 Eine Roadmap statt neun Plandokumente; alte Plaene ins Archiv
Die offenen Punkte lagen ueber neun Dokumente verstreut, teils widersprechend,
teils mit Punkten, die laengst umgesetzt waren. ROADMAP.md fuehrt sie zusammen:
sechs Stufen, jeder Punkt gegen den Code geprueft.

Markierung ueber eine Legende, damit Konzepte nicht mit Aufgaben verwechselt
werden: dringend, eingeplant, Backlog, Konzept (durchdacht, aber bewusst nicht
eingeplant), liegt beim Nutzer, verworfen.

Stufen: 0 Sofort (OpenRouter-Key) - 1 Aufraeumen abschliessen (Merge nach main,
Nullable-Warnungen, Startup-Backfill) - 2 Portierung abschliessen (Linux-Erstlauf
und Verifikation, dann Deployment/CI) - 3 Analytik schaerfen (Strategie-
Klassifikation, Backtest-Harness, Track-Record im Score, Ranking) - 4 Daten-
haushalt (SQL des Nutzers) - 5 Ingest skalieren - 6 Monetarisierung vorbereiten.

Ein Anhang haelt fest, was geprueft und bewusst NICHT auf die Roadmap kam, damit
es nicht versehentlich wieder als Aufgabe auftaucht (Azuro/Limitless, die
Marketing-Seiten, Kaltarchiv, EF Core 10).

Archiv: FIXPLAN-DONE, FIXPLAN-G-Speicher, FIXPLAN-TODO, FIXPLAN-UI-Ranglisten,
UMSETZUNGSPLAN sowie ANALYSE-Linux-Portierung, PLAN-Linux-Portierung,
PLAN-Architektur-WebUI-Backend und PLAN-DatenIngest-Skalierung liegen jetzt
unter docs/archiv/ mit einer README, die jedes Dokument einordnet. Sie bleiben
als Begruendungs- und Detailquelle - die Roadmap nennt jeden Punkt knapp, die
Herleitung steht dort.

Dabei aufgefallen: die beiden nie gepflegten Plaene (Architektur, DatenIngest)
zeigten 40 offene Punkte, von denen die Haelfte umgesetzt war - Read/Control-
Split, /api/capabilities, CORS-Whitelist, Egress-Kanaele mit Cooldown und
Per-Kanal-Limiter, Ingest-Tiering. Nachgeprueft, abgehakt und mit Statusblock
eingeordnet, sonst waere das Archiv selbst eine Fehlerquelle.

Was dabei nur teilweise umgesetzt war, ist als Roadmap 5.3 aufgenommen
(Health-Statistik je Kanal, multi-homed pruefen, DB-Guard, Plausibilitaets-
pruefung), ebenso der nie durchgefuehrte Audit auf versteckte Writes in
Read-Endpunkten (6.1). Header-Rotation ist als verworfen markiert statt offen
zu bleiben: Verschleierung gegenueber Polymarket riskiert genau den Zugang, auf
dem das Projekt aufsetzt.

STATUS.md beschreibt jetzt nur noch den Ist-Stand und verweist fuer die offenen
Punkte auf die Roadmap, damit nichts doppelt gepflegt wird. CLAUDE.md nennt
beide Einstiege.

Build gruen, 126 Tests gruen, keine toten Links.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 18:46:00 +02:00

12 KiB
Raw Permalink Blame History

Plan: Drei-Schichten-Architektur (Core / Lokal / Public)

Archiviert am 2026-08-23 — offene Punkte siehe ROADMAP.md, Stufe 6. Dieses Dokument wird nicht mehr gepflegt.

Phase 0 bis 2 sind erledigt, überwiegend als Nebenprodukt der Linux-Portierung, und hier nachträglich abgehakt:

  • Read/Control-Split (ApiConfiguration.MapPredictalyticsReadEndpoints() bzw. MapPredictalyticsControlEndpoints()), /api/dev/* und die Job-Trigger liegen auf der Control-Seite.
  • GET /api/capabilities existiert und meldet den tatsächlichen Zustand; die WebUI koppelt ihre Admin-Aktionen daran (app.js:880,1132).
  • API_BASE ist im SPA konfigurierbar (app.js:2), Trait-Chips sind da.
  • CORS läuft über eine Origin-Whitelist, die Bind-Adresse ist explizit (PredictalyticsHost.cs:177,198-201) — kein 0.0.0.0.

Nicht abgehakt ist der Deep-Dive-Audit auf versteckte Writes in Read-Endpunkten (Phase 0, dritter Punkt): die Trennung steht, ob jeder Read-Endpunkt einzeln daraufhin geprüft wurde, lässt sich im Nachhinein nicht belegen. Vor einem öffentlichen Host nachholen.

Phase 3 und 4 sind offen und bilden Roadmap-Stufe 6 — dort als Konzept markiert, weil über eine Monetarisierung nicht entschieden ist.

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.