No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
sebastian 4dc572b706 Sicherung wieder einspielen, mit oracle_id als Kartenreferenz
Der Export hatte keine Gegenseite: eine Sicherung, die sich nicht
zurücklesen lässt, ist keine.

Einlesen (backup_parser.dart, rein und getestet) prüft App-Kennung und
Formatversion und sagt im Klartext, was mit einer falschen Datei nicht
stimmt, statt sie halb einzulesen. Einzelne kaputte Kartenzeilen werden
übersprungen, nicht die ganze Datei verworfen.

BackupRepository.restore ersetzt Decks, Guides und alle Bestände
vollständig in einer Transaktion. Kein Merge: eine Sicherung ist ein
Zeitpunkt, Zusammenführen ergäbe einen dritten Zustand, den es nie gab.
Der Kartencache bleibt stehen — er gehört Scryfall, nicht dem Nutzer.
Bestätigt wird das vorher ausdrücklich, mit Vorschau der Datei.

Karten stehen jetzt doppelt in der Datei: oracleId und Name (Format 3).
Die ID ist eindeutig, übersteht Umbenennungen (Æther Vial -> Aether
Vial) und braucht kein Fuzzy-Matching für Split-Karten in voller
Schreibweise. Der Name bleibt daneben, damit die Datei im Texteditor
lesbar ist und als Rückfall für Format-2-Dateien. Aufgelöst wird in zwei
Stufen: ensureCachedByIds per Bulk-Lookup über oracle_id, erst für den
Rest resolveManyAndCache über die Namen. Sind alle Karten im Cache,
kommt eine Wiederherstellung ohne Netz aus. Was auch der Name nicht
auflöst, wird übersprungen und namentlich gemeldet.

Zwei Wege hinein: Menü "Sicherung einspielen" und die Datei per
Teilen-Dialog. Dafür nimmt das Manifest zusätzlich application/json —
ohne Speicherberechtigung, weil ein Share eine content://-URI mit
temporärem Leserecht mitliefert. Achtung beim Empfang:
receive_sharing_intent bestimmt den Typ allein am MIME-Type, eine
geteilte .txt kommt darum als "text" an, aber mit einem Pfad im Payload.
app.dart prüft deshalb über looksLikeFilePath, ob eine Datei geteilt
wurde, und liest sie erst dann — womit auch geteilte Decklisten-Dateien
funktionieren.

145 Tests, flutter analyze ohne Befund, Build 018.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 18:35:42 +02:00
android Sicherung wieder einspielen, mit oracle_id als Kartenreferenz 2026-08-22 18:35:42 +02:00
lib Sicherung wieder einspielen, mit oracle_id als Kartenreferenz 2026-08-22 18:35:42 +02:00
test Sicherung wieder einspielen, mit oracle_id als Kartenreferenz 2026-08-22 18:35:42 +02:00
.gitignore Initialer Stand: Deck-, Sammlungs- und Bedarfsverwaltung mit Import 2026-08-18 15:56:36 +02:00
.metadata Initialer Stand: Deck-, Sammlungs- und Bedarfsverwaltung mit Import 2026-08-18 15:56:36 +02:00
analysis_options.yaml Initialer Stand: Deck-, Sammlungs- und Bedarfsverwaltung mit Import 2026-08-18 15:56:36 +02:00
CLAUDE.md Sicherung wieder einspielen, mit oracle_id als Kartenreferenz 2026-08-22 18:35:42 +02:00
pubspec.lock Deck-Import per Teilen-Dialog 2026-08-19 16:55:05 +02:00
pubspec.yaml Sicherung wieder einspielen, mit oracle_id als Kartenreferenz 2026-08-22 18:35:42 +02:00
README.md Initialer Stand: Deck-, Sammlungs- und Bedarfsverwaltung mit Import 2026-08-18 15:56:36 +02:00

simplemtgmanager

Android-App zur Verwaltung von Magic-the-Gathering-Decks: Decklisten, Sideboard-Guides, eigene Sammlung und eine Übersicht, welche Karten noch fehlen. Alles wird lokal gespeichert, ohne Cloud-Sync.

Funktionen

  • Decks anlegen, umbenennen, Karten pflegen — mit Kartenbild, Anzahl und Wechsel zwischen Main- und Sideboard.
  • Import kompletter Decklisten, entweder als eingefügter Text (MTGO, Arena, Moxfield, Archidekt, MTGGoldfish …) oder über einen öffentlichen Moxfield-Link. Main- und Sideboard werden automatisch getrennt; vor dem Speichern zeigt eine Vorschau, was erkannt wurde und wie die Aufteilung zustande kam.
  • Sammlung mit der vorhandenen Stückzahl je Karte. Karten, deren Bedarf gedeckt ist, rutschen unter eine eigene Überschrift ans Ende.
  • Bedarfsübersicht „Was muss ich noch besorgen?" samt Teilen-Funktion.
  • Sideboard-Guides je Deck und Matchup.

Die zentrale Rechenregel

Der Bedarf an physischen Karten wird für Main- und Sideboard unterschiedlich ermittelt:

  • Mainboard: Summe über alle Decks. Jedes Deck gilt als dauerhaft gebaut und braucht eigene Exemplare.
  • Sideboard: Maximum über alle Decks — nicht die Summe. Sideboard-Karten werden nur zwischen den Spielen eines Matches gewechselt, also nie von zwei Decks gleichzeitig gebraucht. Zwei Decks mit je 2x derselben Karte kommen mit 2 Exemplaren aus.

Implementiert in lib/features/needs/needs_calculator.dart und durch Tests abgesichert.

Technik

Flutter (Android), Riverpod für State, Drift/SQLite für die lokale Datenbank, Kartendaten von der Scryfall-API.

Entwicklung

flutter pub get
flutter test
flutter build apk --release

Nach Änderungen am Datenbankschema:

dart run build_runner build --delete-conflicting-outputs

Weitere Hinweise zu Architektur, Konventionen und Fallstricken stehen in CLAUDE.md.