# Einheiten: backend/tft/matches/extract.py stand: f41ac76b5789 ## backend/tft/matches/extract.py::patch_of beschreibung: Leitet den zweistelligen Versions-Patch (z. B. „16.14") aus einem beliebigen `game_version`-String ab. input: Ein `game_version`-String mit beliebigen Präfixen oder Trennzeichen. output: Der Patch-Anteil als String der Form „x.y". entscheidungen: - Iteriert über Tokens statt blind zu splitten, um an einen tatsächlichen `x.y`-Token zu gelangen. beleg: "for token in game_version.replace(\"(\", \" \").split():" - Übernimmt nur die ersten beiden Punkt-Segmente und ignoriert alles dahinter. beleg: "return \".\".join(digits.split(\".\")[:2])" - Bevorzugt ein gefundes numerisches Token gegenüber dem Fallback auf das letzte whitespace-getrennte Wort. beleg: "digits = token" kanten: - wird-genutzt-von: backend/tft/matches/extract.py::extract_match ## backend/tft/matches/extract.py::extract_match beschreibung: Überführt ein einzelnes rohes Match-Diktat in eine Liste von Endboard-Zeilen, indem es pro Teilnehmer die relevanten Felder in ein Tupel schreibt. input: Ein `match`-Dictionary gemäß Riot-Match-Schema. output: Eine Liste von Tupeln mit Match-ID, PUUID, Set-Nummer, Patch, Platzierung, Level, letzter Runde, Restgold und JSON-serialisierten Units/Traits/Augments. entscheidungen: - Serialisiert verschachtelte Strukturen (Units, Traits, Augments) vor dem Schreiben als JSON-String, um eine flache Tupel-Form zu behalten. beleg: "json.dumps(p[\"units\"])," - Liefert bei fehlendem `augments`-Feld eine leere Liste statt einen Fehler. beleg: "json.dumps(p.get(\"augments\", []))," - Bezieht den Patch je Match zentral aus `info` und nicht pro Teilnehmer neu berechnet. beleg: "patch = patch_of(info[\"game_version\"])" kanten: - ruft-auf: backend/tft/matches/extract.py::patch_of - wird-genutzt-von: backend/tft/matches/extract.py::extract_all ## backend/tft/matches/extract.py::validate_ids beschreibung: Zählt in den Endboard-Zeilen IDs (Units, Items, Traits, Augments), die nicht in den statischen Daten vorkommen, als Patch-Drift-Kanarienvogel. input: Eine Liste von Endboard-Zeilen-Tupeln und ein `static`-Dictionary mit bekannten IDs. output: Ein `Counter` mit Präfix-Schlüsseln `unit:`, `item:`, `trait:` und `augment:`, das unbekannte IDs samt Häufigkeit führt. entscheidungen: - Filtert Unit-Drift um erwartbar unbekannte Beschwörungen/PvE-Einheiten anhand von Namenshinweisen heraus. beleg: "if not any(h in api.lower() for h in BENIGN_UNIT_HINTS):" - Vereinigt Items und Augments zu einem einzigen `known_items`-Set, um Doppellookups zu vermeiden. beleg: "known_items = set(static[\"items\"]) | set(static[\"augments\"])" - Zählt bei Items nur Drift, wenn das Item dem aktuellen Set oder dem generischen `TFT_Item_`-Schema angehört. beleg: "if item.startswith(\"TFT_Item_\") or item.startswith(set_prefix):" kanten: - nutzt: backend/tft/matches/extract.py::BENIGN_UNIT_HINTS - wird-genutzt-von: backend/tft/matches/extract.py::extract_all ## backend/tft/matches/extract.py::extract_all beschreibung: Liest alle noch nicht verarbeiteten Roh-Matches aus der Datenbank, extrahiert ihre Endboard-Zeilen, prüft sie gegen die statischen Daten und schreibt sie persistent in die `endboards`-Tabelle. input: Eine geöffnete DB-`connection` mit Schema `matches`/`endboards` und ein `static`-Dictionary mit bekannten IDs. output: Ein Tupel `(n, total_unknown)` mit Anzahl geschriebener Zeilen und aggregiertem Drift-Counter. entscheidungen: - Selektiert nur Matches, deren `match_id` noch nicht in `endboards` vorkommt, um Doppelverarbeitung zu vermeiden. beleg: "SELECT raw FROM matches WHERE match_id NOT IN (SELECT DISTINCT match_id FROM endboards)" - Verwendet `INSERT OR IGNORE`, damit Wiederholungsläufe keine Duplikatfehler erzeugen. beleg: "\"INSERT OR IGNORE INTO endboards VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\"" - Sammelt Drift in einem einzigen Counter statt pro Match, damit das Endergebnis meldbar bleibt. beleg: "total_unknown.update(validate_ids(rows, static))" kanten: - ruft-auf: backend/tft/matches/extract.py::extract_match - ruft-auf: backend/tft/matches/extract.py::validate_ids