Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

BetAssist LITE Wiki

Zentrales Projekt-“Gehirn” - alle wichtigen Infos auf einen Blick.

ThemaDatei
Architektur & Pipelinearchitecture.md
Datenmodellemodels.md
Scraping (Neobet + Flashscore)scraping.md
Scoring-Algorithmusscoring.md
API Endpointsapi.md
Export (CSV + Excel)export.md
Staking & Leben-Systemstaking.md
Produkt-Vision & Roadmaproadmap.md

Tech Stack

KomponenteTechnologie
APIRust / Axum (Port 3030)
Scrapingthirtyfour (WebDriver) + scraper (HTML)
BrowserHeadless Chrome via ChromeDriver (:9515)
ExportCSV (csv crate) + Excel (rust_xlsxwriter)
Schedulertokio-cron-scheduler (01:00 Uhr daily)
Deploymentsystemd Services, Nginx Reverse Proxy

Verzeichnisstruktur

/home/hlorenz/lite/
├── api/                  # Rust API (dieses Projekt)
│   ├── src/
│   │   ├── main.rs       # Entry Point, Server, Scheduler
│   │   ├── api/          # Axum Routes + Handler
│   │   ├── models/       # Datenstrukturen
│   │   ├── scrapers/     # Browser, Flashscore, Neobet
│   │   ├── services/     # Matcher, Scoring, Pipeline
│   │   └── export/       # CSV + Excel Export
│   └── Cargo.toml
├── exports/              # Generierte CSV/Excel Dateien
├── frontend/             # (geplant)
├── wiki/                 # Diese Wiki
└── oldVersionRef/        # Referenz-Dateien

Pipeline (Kurzfassung)

Neobet (Heute+Morgen) → Flashscore (Matches) → League-Matcher
    → H2H (3 Seiten) → Odds (7 Seiten) → Scoring → Export

Mehr Details: architecture.md

Architektur & Pipeline

Gesamtablauf

Die Pipeline wird entweder per API-Call oder Scheduler (01:00 Uhr) ausgeloest.

┌─────────────┐     ┌──────────────────┐     ┌───────────────┐
│  1. Neobet  │────>│  2. Flashscore   │────>│  3. Matcher   │
│  Ligen      │     │  Matches         │     │  (Dice-Sim.)  │
└─────────────┘     └──────────────────┘     └───────┬───────┘
                                                     │
                                             gematchte Spiele
                                                     │
                    ┌──────────────────┐     ┌───────▼───────┐
                    │  5. Odds         │<────│  4. H2H       │
                    │  (7 Seiten)      │     │  (3 Seiten)   │
                    └────────┬─────────┘     └───────────────┘
                             │
                    ┌────────▼─────────┐     ┌───────────────┐
                    │  6. Scoring      │────>│  7. Export     │
                    │  (12 Kriterien)  │     │  CSV + Excel   │
                    └──────────────────┘     └───────────────┘

Schritt-Detail

1. Neobet Ligen

  • URL: https://neobet.de/de/Sportwetten/Heute+Morgen/Fussball/Alle
  • Liefert: Liste aller Ligen mit Spielen (Land, Liga)
  • Deckt Heute + Morgen in einem Aufruf ab

2. Flashscore Matches

  • URL: https://www.flashscore.com/
  • Date Picker Navigation via Pfeil-Buttons (URL-Parameter ?d= wird ignoriert!)
  • Liefert: Match-Liste mit IDs, Teams, Zeiten, Ligen

3. League Matcher

  • Algorithmus: Soerensen-Dice Bigram-Aehnlichkeit
  • Gewichtung: 30% Land + 70% Liga
  • Schwellwert: 0.6 Confidence
  • Ergebnis: Flashscore-Matches die auch auf Neobet verfuegbar sind

4. H2H Scraping (pro Match)

  • 3 Seiten: Home, Away, Overall
  • Extrahiert: letzte 15 Ergebnisse pro Seite
  • Berechnet: Intervalle (o1.5-o4.5, u0.5-u1.5, BTS, 1TS), Durchschnitte, Streaks

5. Odds Scraping (pro Match)

  • 7 Seiten: O/U FT, O/U 1H, O/U 2H, BTTS, 1X2, DC, DNB
  • Quoten aller Buchmacher gemittelt
  • Graceful Handling: Fehler = None, Match wird trotzdem gespeichert

6. Scoring

  • 12 Kriterien, Rang-basiertes Punktesystem
  • Top 4 Matches pro Kriterium bekommen +1 Punkt
  • Ergebnis: max 4 Over-Picks (max 7 Punkte) + max 4 Under-Picks (max 5 Punkte)

7. Export

  • CSV: 56 Spalten, flach
  • Excel: 3 Worksheets (Daten, Quoten, Wunschliste)
  • Pfad: /home/hlorenz/lite/exports/

Technische Besonderheiten

ProblemLoesung
eval_js() gibt null zurueckdriver.source() + scraper crate fuer HTML-Parsing
Flashscore ignoriert ?d= URL-ParamDate Picker Pfeil-Buttons klicken
Neobet Heute vs MorgenKombinierte URL Heute+Morgen
Rate Limiting500ms Delay zwischen H2H-Requests, 2.5s Warte nach Odds-Navigation

Key Files

DateiVerantwortung
src/main.rsServer, Logging, Scheduler
src/services/scraper_service.rsPipeline-Orchestrierung
src/services/matcher.rsLiga-Matching (Dice)
src/services/scoring.rsScoring-Algorithmus
src/scrapers/flashscore.rsFlashscore Scraper (~1000 Zeilen)
src/scrapers/neobet.rsNeobet Scraper
src/scrapers/browser.rsWebDriver Management

Datenmodelle

Alle Modelle in src/models/. Jedes Modul hat eigene Datei.

NeobetMatch / NeobetLeague

NeobetLeague { country, league, first_match_time?, match_count? }
NeobetMatch  { country, league, home_team, away_team, kickoff_time?, date }

Quelle: Neobet Scraper. Verwendet fuer Liga-Matching.

FlashscoreMatch / FlashscoreLeague

FlashscoreMatch {
    match_id, home_team, away_team,
    home_team_id, away_team_id,       // fuer URL-Konstruktion
    kickoff_time?, date,
    country, league, h2h_url,
    final_score?                       // nur bei beendeten Spielen
}
FlashscoreLeague { country, league, league_id? }
MatchScore { home, away }             // Methods: total_goals(), is_over(), is_btts()

AnalyzedMatch (Hauptstruktur)

Das zentrale Datenobjekt nach H2H-Analyse. Wird fuer Scoring + Export verwendet.

AnalyzedMatch {
    h2h_url, kickoff_time, match_name, country, league,

    // Durchschnitte (venue-specific)
    home_avg_scored?, home_avg_conceded?,
    away_avg_scored?, away_avg_conceded?,
    sum_conceded?, sum_scored?,

    // Backtesting
    backtesting_result?,               // "2:1" bei beendeten Spielen

    // Spiele seit letztem Event
    games_since_o15_home?, games_since_o15_away?,
    games_since_o25_home?, games_since_o25_away?,
    games_since_zero_home?, games_since_zero_away?,

    // Intervall-Daten (venue + overall)
    intervals: MatchIntervals,

    // Quoten (alle Maerkte)
    odds?: MatchOdds,
}

MatchIntervals

32 Felder: 16 venue-specific + 16 overall. Jedes Feld ist Option<IntervalData>.

Venue-specific: o15_home/away, o25_home/away, o35_home/away, o45_home/away, u05_home/away, u15_home/away, bts_home/away, ots_home/away

Overall: gleiche 8 Typen mit _overall Suffix.

IntervalData {
    intervals: Vec<u32>,     // Spiele zwischen Events [3,1,2,5]
    current_streak: u32,     // Spiele seit letztem Event
    raw: String,             // "3,1,2,5 (2)" fuer CSV
}
// Methods: parse(s), average(), max(), min()

MatchOdds

MatchOdds {
    ou_full_time:   Vec<OverUnderOdds>,    // pro Schwellwert (0.5-4.5)
    ou_first_half:  Vec<OverUnderOdds>,
    ou_second_half: Vec<OverUnderOdds>,
    btts?:          BttsOdds,
    one_x_two?:     OneXTwoOdds,
    double_chance?: DoubleChanceOdds,
    draw_no_bet?:   DrawNoBetOdds,
}
// Lookup: ou_ft(2.5), ou_1h(1.5), ou_2h(1.5)

Quoten-Typen:

TypFelder
OverUnderOddsthreshold, over, under, bookmaker_count
OneXTwoOddshome, draw, away, bookmaker_count
BttsOddsyes, no, bookmaker_count
DoubleChanceOddshome_draw, home_away, draw_away, bookmaker_count
DrawNoBetOddshome, away, bookmaker_count

Scoring-Modelle

ScoringResult { date, total_matches, over_picks, under_picks, over_criteria_count=7, under_criteria_count=5 }
Pick { match_name, kickoff_time, country, league, score, max_score, criteria: Vec<ScoringCriterion> }
ScoringCriterion { name, value, rank }

Export-Modelle

ExportConfig { directory="../exports", csv=true, excel=true, filename_prefix="match_data" }
ExportResult { date, match_count, csv_path?, excel_path?, exported_at, scoring? }

Scraping

Browser-Setup

  • WebDriver: thirtyfour 0.35
  • ChromeDriver: localhost:9515 (systemd Service)
  • Modus: Headless (konfigurierbar via HEADLESS env)
  • Navigation: 4 Versuche mit exponentiellem Backoff
  • HTML-Parsing: driver.source() + scraper crate (eval_js gibt null zurueck!)

Neobet

URL: https://neobet.de/de/Sportwetten/Heute+Morgen/Fussball/Alle

Ablauf:

  1. Seite laden, bis zu 30s auf Rendering warten
  2. HTML-Source holen
  3. Liga-Links parsen: a[href*="/Fussball/"]
  4. Land + Liga aus Breadcrumbs extrahieren

Ergebnis: Vec<NeobetLeague> mit Land, Liga, Spielanzahl

Einzelne Liga-Matches: URL Sportwetten/{Heute|Morgen}/Fussball/{Land}/{Liga}

  • Team-Paare aus Match-Containern extrahieren

Flashscore

Base URL: https://www.flashscore.com/

Match-Liste

Date Picker Navigation (URL-Param ?d= wird von der SPA ignoriert!):

  1. Flashscore laden, Cookies wegklicken
  2. Tage-Differenz berechnen (Heute = 0)
  3. Overlay-iFrames verstecken (display:none)
  4. Pfeil-Button klicken: button[data-day-picker-arrow="next"] oder "prev"
  5. 1.5s Pause nach jedem Klick
  6. Validierung: button[data-testid="wcl-dayPickerButton"] Text pruefen (Format “DD/MM Tag”)

Match-Extraktion aus HTML:

  • Laender-Header: div.event__header mit span.event__title--type
  • Match-Rows: div.event__match
  • Match-ID: id="g_1_{matchId}"
  • Team-IDs: a.event__participant → href /team/{name}/{teamId}/
  • Zeiten: div.event__time
  • Scores (beendete Spiele): span.event__score

H2H (3 Seiten pro Match)

URL-Schema: /match/football/{homeId}/{awayId}/h2h/{tab}/?mid={matchId}

TabWas
homeNur Heimspiele des Heimteams + Auswaertsspiele des Auswaertsteams
awayUmgekehrt
overallAlle Spiele beider Teams

Ablauf pro Seite:

  1. Navigieren, 3s warten
  2. “Show more” Buttons in allen Sektionen klicken
  3. HTML-Source holen
  4. Score-Elemente: span.h2h__result > span > span (2 Child-Spans!)
  5. Letzte 15 Ergebnisse pro Team extrahieren

Berechnungen aus Ergebnissen:

  • Durchschnitte: avg_scored, avg_conceded (Tore erzielt/kassiert)
  • Intervalle: Spiele zwischen Events fuer o1.5, o2.5, o3.5, o4.5, u0.5, u1.5, BTS, 1TS
  • Streaks: Aktuelle Serie seit letztem Event

Odds (7 Seiten pro Match)

URL-Schema: Aus h2h_url die Match-Base ableiten, dann /odds/{suffix}/

SeiteURL-SuffixSpalten
O/U Full Timeodds/over-under/full-time/2 + Threshold
O/U 1st Halfodds/over-under/1st-half/2 + Threshold
O/U 2nd Halfodds/over-under/2nd-half/2 + Threshold
BTTSodds/both-teams-to-score/2
1X2odds/1x2-odds/full-time/3
Double Chanceodds/double-chance/3
Draw No Betodds/draw-no-bet/2

HTML-Selektoren:

  • Zeile: .ui-table__row
  • Buchmacher: img[class*="logoImage"] → alt
  • Schwellwert (O/U): [class*="oddsValue"] → Text
  • Quoten: .oddsCell__odd → Text

Averaging: Alle Buchmacher-Quoten pro Schwellwert gemittelt.

Error Handling: Graceful - Fehler bei einer Odds-Seite = warn-Log, Match wird ohne diese Quoten gespeichert.

Scoring-Algorithmus

Prinzip

Rang-basiertes Punktesystem. Alle Matches des Tages werden gegeneinander gerankt. Pro Kriterium bekommen die Top 4 Matches je +1 Punkt. Am Ende: Top 4 nach Gesamtpunkten.

Kriterien

Over 2.5 (7 Kriterien, max 7 Punkte)

#KriteriumRichtungErklaerung
1SUM ErzieltDESCHohe Torproduktion = gut fuer Over
2SUM KassiertDESCViele kassierte Tore = gut fuer Over
3Seit o2.5 H+AASCKuerzer = kuerzlich passiert = gut
4Seit o1.5 H+AASCKuerzer = gut
5o2.5 IntervallASCNiedriger Composite = haeufiger
6o1.5 IntervallASCNiedriger Composite = haeufiger
7o3.5 IntervallASCNiedriger Composite = haeufiger

Under 2.5 (5 Kriterien, max 5 Punkte)

#KriteriumRichtungErklaerung
8SUM ErzieltASCWenig Tore = gut fuer Under
9SUM KassiertASCWenig kassiert = gut fuer Under
10Seit 0 Tore H+AASCKuerzlich 0 Tore = gut
11u0.5 IntervallASCHaeufig unter 0.5 = gut
12u1.5 IntervallASCHaeufig unter 1.5 = gut

Intervall-Composite Score

composite = avg(home_streak, away_streak) + avg(home_avg_interval, away_avg_interval)

Niedrigerer Wert = Event passiert haeufiger UND ist aktueller = besser.

Ablauf

  1. Fuer jedes Kriterium: Werte aller Matches extrahieren, sortieren
  2. Top TOP_N = 4 Matches bekommen +1 Punkt
  3. Nach allen Kriterien: Matches nach Gesamtpunkten sortieren
  4. Top 4 Over-Picks + Top 4 Under-Picks (Score > 0) ausgeben

Ergebnis

ScoringResult {
    over_picks:  max 4 Picks mit score/7
    under_picks: max 4 Picks mit score/5
}

Jeder Pick enthaelt die einzelnen Kriterien-Details (Name, Wert, Rang).

API Endpoints

Server: Axum auf 0.0.0.0:3030 CORS: GET/POST/OPTIONS, alle Origins Binary: /home/hlorenz/lite/api/target/release/betassist-lite

Endpoints

Health Check

GET /health
→ { "status": "ok", "version": "0.1.0" }

Scraping ausloesen

POST /api/v1/scrape/today      # Heute scrapen
POST /api/v1/scrape/tomorrow   # Morgen scrapen
POST /api/v1/scrape/:date      # Beliebiges Datum (YYYY-MM-DD)

Response:

{
  "success": true,
  "date": "2026-02-22",
  "matches_found": 42,
  "csv_path": "../exports/match_data_2026-02-22.csv",
  "excel_path": "../exports/match_data_2026-02-22.xlsx",
  "predictions": { "over_picks": [...], "under_picks": [...] }
}

Predictions abrufen

GET /api/v1/predictions/:date

Liest CSV vom Dateisystem, fuehrt Scoring erneut aus, gibt Ergebnis zurueck.

{
  "success": true,
  "date": "2026-02-22",
  "predictions": {
    "over_picks": [...],
    "under_picks": [...],
    "total_matches": 42
  }
}

Noch nicht implementiert (TODO)

GET /api/v1/matches/today     # → []
GET /api/v1/matches/:date     # → []
GET /api/v1/exports           # → []
GET /api/v1/exports/:date     # → 404

Scheduler

  • Cron: 0 0 1 * * * (taeglich 01:00 Uhr)
  • Fuehrt aus: run_today() + run_tomorrow()
  • Konfigurierbar: ENABLE_SCHEDULER=true/false

AppState

#![allow(unused)]
fn main() {
AppState {
    scraper: RwLock<Option<Arc<ScraperService>>>,  // lazy init
    config: ScraperConfig,
}
}

ScraperService wird beim ersten API-Call initialisiert (Lazy Pattern).

Export

Verzeichnis: /home/hlorenz/lite/exports/ Dateiname: match_data_{YYYY-MM-DD}.{csv|xlsx}

CSV (56 Spalten)

BereichSpaltenAnzahl
Match-InfoURL, Zeit, Spiel, Land, Liga5
DurchschnitteHeim/Ausw Erzielt/Kassiert, SUM6
BacktestingErgebnis1
Spiele-seito1.5/o2.5/0-Tore H+A6
Intervalle (venue)o1.5-o4.5, u0.5-u1.5, BTS, 1TS je H+A16
Intervalle (overall)gleiche 8 Typen je H+A16
QuotenO/U 2.5 FT, BTTS, 1X26

Intervall-Format in Zellen: "3,1,2,5 (2)" (Intervalle + aktuelle Serie)

Excel (3 Worksheets)

Sheet 1: Hauptdaten

  • 50 Spalten (wie CSV ohne Quoten-Spalten)
  • Numerische Werte als Zahlen (nicht Strings)
  • Fett-Header, angepasste Spaltenbreiten

Sheet 2: “Quoten” (34 Spalten)

BereichSpalten
Spiel, Zeit2
1X2Heim, Unent., Ausw. (3)
BTTSJa, Nein (2)
Double Chance1X, 12, X2 (3)
Draw No BetHeim, Ausw. (2)
O/U Full Time0.5-4.5 je Over+Under (10)
O/U 1st Half0.5-2.5 je Over+Under (6)
O/U 2nd Half0.5-2.5 je Over+Under (6)

Nur erstellt wenn mindestens ein Match Quoten hat.

Sheet 3: “Wunschliste”

Over 2.5 Picks (gruen) + Under 2.5 Picks (rot).

SpalteInhalt
#Rang
SpielMatchname
ZeitAnstosszeit
LandLand
LigaLiga
Scorez.B. “5/7”
DetailsKriterien-Aufschluesselung

Nur erstellt wenn Scoring-Ergebnisse vorhanden.

Staking Tables & Leben-System

Referenz: /home/hlorenz/bet-assist-core/app/v0/

Leben (Lives) = Safe Rounds

Maximale Anzahl aufeinanderfolgender Verluste bevor Totalverlust.

Berechnung:

maxLives = quote + RISK_OFFSET
RisikostufeOffsetBei Quote 4
risky04 Leben
medium+15 Leben
safe+26 Leben
ultra_safe+37 Leben
marathon+48 Leben
immortal+59 Leben
eternal+610 Leben

Verhalten:

  • GEWINN: Lives werden auf maxLives ZURUECKGESETZT, Loop startet bei Runde 1
  • VERLUST: 1 Leben weg, naechste Runde (hoeherer Einsatz), Bankroll bleibt gleich
  • 0 Leben: Plan deaktiviert (Totalverlust)

Run Table (Staking Table)

Modifiziertes Martingale: Jede Runde garantiert den GLEICHEN Netto-Gewinn bei Sieg.

Kernformel:

r = quote / (quote - 1)
profit = bankroll / (r^maxRounds - 1)

stake_runde_1 = profit / (quote - 1)
stake_runde_n = (total_gesetzt + profit) / (quote - 1)
stake_letzte  = bankroll - total_gesetzt   (exakter Rest)

Invariante: potential_win - total_staked = profit (KONSTANT fuer alle Runden!)

Beispiel (Quote=4, medium/5 Runden, Bankroll=100EUR):

RundeEinsatzGesamtGewinnNetto-Profit
110.3710.3741.4831.11
213.8324.2055.3231.12
318.4442.6473.7631.12
424.5867.2298.3231.10
532.78100.00131.1231.12

Skalierung: Basistabelle immer fuer 100 EUR, dann proportional auf tatsaechliche Bankroll.

Ueberlebenswahrscheinlichkeit

win_prob_per_runde = 1 / quote
survival_pro_loop = 1 - (1 - win_prob)^maxRounds
erwartete_loops_bis_totalverlust = 1 / (1 - survival)
StufeLeben (Q=4)Profit%Survival/LoopLoops bis Verlust
risky4~46%~68%~3
medium5~31%~76%~4
safe6~22%~82%~5.5
ultra_safe7~15%~87%~7.5
marathon8~11%~90%~10
immortal9~8%~93%~14
eternal10~6%~95%~20

Wettplan (Instance)

Drei Bankroll-Werte:

originalBankroll  → aendert sich NIE (Referenzwert)
bankroll          → Basis fuer Skalierung, steigt nach jedem Gewinn
currentBankroll   → Aktuell verfuegbar, sinkt wenn Wette platziert

Eingaben bei Erstellung:

  • Name, Buchmacher, Bankroll (min 10 EUR), Quote (2-30)
  • Risikostufe, Ziel-Multiplikator (2x, 3x, 5x, 10x)
  • Kategorie: standard oder longterm

Gewinn-Pfad:

gewinn = stake * quote
currentBankroll += gewinn
bankroll = currentBankroll    (neue Basis)
livesRemaining = maxLives     (Reset)
currentLoopRound = 0          (Neustart mit groesserer Bankroll)
→ Ziel pruefen (currentBankroll >= targetAmount?)

Verlust-Pfad:

livesRemaining -= 1
currentLoopRound bleibt (naechste Runde = +1 im Table)
bankroll UNVERAENDERT
→ livesRemaining <= 0? Plan tot.

Alte DB-Felder (Supabase Postgres)

betting_instances:

id, user_id, bookmaker_id, name,
original_bankroll_cents, bankroll_cents, current_bankroll_cents,
target_multiplier, target_amount_cents, target_achieved, final_profit_cents,
quote, risk_factor, run_table_id, category, risk_modifier,
survival_probability, max_lives, lives_remaining, lives_used,
active, locked, current_round, created_at, updated_at

betting_sessions:

id, instance_id, user_id,
current_round, lives_remaining, max_lives,
total_rounds, total_wins, total_losses,
current_loop_active, current_loop_round, current_loop_total_staked_cents,
current_loop_id, can_close, level, total_xp,
created_at, last_updated

Betraege in Cent (Integer) fuer Praezision.

Frontend

Tech Stack

KomponenteTechnologie
FrameworkReact 19 + TypeScript
Build ToolVite 7
RoutingReact Router DOM 7
AuthSupabase (managed)
StateReact Hooks + localStorage
StylingCustom CSS (Glassmorphic Design)

Seiten / Routen

RouteSeiteBeschreibung
/loginLoginAnmeldung / Registrierung via Supabase
/DashboardAktiver Plan, Tages-Predictions
/setup/bookmakerBookmaker SetupWizard: Anbieter waehlen + Einzahlung
/setup/planPlan SetupWizard: Risiko, Ziel, Budget, Quote
/plan/:idPlan DetailRun Table, aktive Wetten, Historie

Auth Flow

  1. User landet auf /login (oeffentliche Route)
  2. Registrierung (Name, Email, Passwort) oder Login
  3. Supabase verwaltet Auth-State via JWT
  4. Geschuetzte Routen per AuthGuard (redirect zu Login wenn nicht eingeloggt)
  5. Sign-out loescht Session

Design System

  • Farben: Deep Blue Background (#070b14), Cyan Glow (#00d4ff), Purple (#8b5cf6), Green (#00ff88), Red (#ff3366), Gold (#ffd700)
  • Fonts: Inter (Body), JetBrains Mono (Zahlen/Betraege)
  • Komponenten: Glass Cards (blur + backdrop filter), Pill Buttons, Risk Cards
  • Animationen: Fade-in, Heart Break/Gain, Confetti bei Gewinn
  • Responsive: Breakpoint bei 640px, Flex/Grid Layouts

State Management

Kein globaler Store - jeder Feature-Bereich hat einen eigenen Hook:

HooklocalStorage KeyFunktion
useBookmakers()ba_bookmakersWettanbieter verwalten
usePlans()ba_plansWettplaene CRUD
useBets()ba_betsWetten + Ergebnisse

Jeder Hook bietet refresh() zum Neuladen nach Aenderungen.

Betting Flow

  1. Dashboard zeigt Tages-Predictions von API (/api/v1/predictions/{date})
  2. User klickt Pick → Modal mit Details (Match, Liga, Tipp, Quote, Einsatz, Gewinn)
  3. Bestaetigung → Wette in localStorage gespeichert
  4. Plan-Detail zeigt aktive Wette mit Win/Loss Buttons
  5. Win: Lives Reset + Bankroll waechst, Loss: 1 Leben weniger

Run Table

Mathematische Einsatz-Berechnung:

  • r = quote / (quote - 1) (Martingale-Faktor)
  • Konstanter Profit pro Runde
  • Rekursive Berechnung ueber alle Runden
  • Visualisierung mit Fortschrittsbalken zum Ziel

Build & Deployment

# Development
cd /home/hlorenz/lite/frontend
npm run dev          # Vite Dev Server auf :5173, Proxy zu API :3030

# Production Build
npm run build        # Output in dist/

# Deployment
# Static Files in dist/ werden von Nginx served
# API Proxy ueber Nginx location /api/ → localhost:3030

Verzeichnisstruktur

frontend/
├── src/
│   ├── main.tsx          # Entry Point
│   ├── App.tsx           # Router Setup
│   ├── pages/            # Seiten-Komponenten
│   ├── components/       # Shared Components
│   ├── hooks/            # Custom Hooks (useStore, useAuth)
│   ├── styles/           # CSS Dateien
│   └── lib/              # Utilities, Supabase Client
├── dist/                 # Production Build Output
├── vite.config.ts        # Vite Config mit API Proxy
└── package.json

Produkt-Vision & Roadmap

Vision

Minimalistische Wett-Assistent App:

  1. Login (einmalig)
  2. Wettkonto einrichten (Anbieter, Bankroll)
  3. Wettplan definieren (Ziel, Strategie)
  4. Dashboard: Top-Auswahl passend zum aktiven Plan
  5. Staking Tables mit “Leben”-System

Geplante Architektur

┌────────────┐     ┌─────────────┐     ┌──────────┐
│  Frontend  │────>│  Rust API   │────>│  SQLite   │
│  (SPA)     │<────│  (Axum)     │<────│           │
└────────────┘     └──────┬──────┘     └──────────┘
                          │
                   ┌──────▼──────┐
                   │  Scraping   │
                   │  Engine     │
                   └─────────────┘

Datenbank (SQLite)

Geplante Tabellen:

TabelleInhalt
usersLogin, Auth
betting_plansZiel, Strategie, Bankroll, Status
matchesTagesergebnisse (AnalyzedMatch Daten)
oddsQuoten pro Match
picksScoring-Ergebnisse, Empfehlungen

Warum SQLite: Kein separater DB-Server noetig, eingebettet, perfekt fuer Single-Server Setup.

Staking / “Leben”-System

Vollstaendig analysiert! Siehe staking.md fuer Details.

Kurzfassung:

  • Leben = quote + risk_offset (4-10 je nach Stufe)
  • Martingale-Staking mit konstantem Profit pro Runde
  • Gewinn = Lives Reset + Bankroll waechst, Verlust = 1 Leben weg
  • 7 Risikostufen: risky bis eternal

Roadmap

Phase 1: Scraping Engine (erledigt)

  • Neobet + Flashscore Scraping
  • League Matching
  • H2H Analyse mit Intervallen
  • Odds Scraping (alle 7 Maerkte)
  • Scoring-Algorithmus
  • CSV + Excel Export
  • REST API
  • Scheduler (01:00 daily)
  • Heute + Morgen Unterstuetzung
  • Projekt-Wiki

Phase 2: Frontend (erledigt)

  • Alte bet-assist App analysieren (Staking/Leben)
  • React + TypeScript + Vite Setup
  • Supabase Auth (Login/Registration)
  • Wettkonto Setup (Bookmaker + Einzahlung)
  • Wettplan Setup (Risiko, Ziel, Budget, Quote)
  • Dashboard mit Tages-Predictions
  • Betting Flow (Pick → Modal → Bestaetigung)
  • Run Table mit Martingale-Berechnung
  • Leben-System mit Heart-Visualisierung
  • Glassmorphic Design System
  • Responsive Layout
  • Deployment (Nginx Static Files)
  • Wiki Dokumentation

Phase 3: Datenbank + Backend

  • SQLite Integration
  • Match-Daten in DB speichern
  • User-Daten serverseitig (aktuell localStorage)
  • Wettplan-Management API

Phase 4: Intelligence

  • Plan-basierte Filterung
  • Personalisierte Empfehlungen
  • Ergebnis-Tracking
  • Statistiken/Historie