Schema-Aenderungen als eigene Migration nachziehen

Die erste Migration wurde nachtraeglich mehrfach erweitert, statt Aenderungen
anzuhaengen. Auf einer bestehenden Installation gilt sie als angewendet und
wird uebersprungen - die seither hinzugekommenen Tabellen fehlten dort also
schlicht, ohne dass beim Start etwas auffiel. Die Antragsseite lief dadurch
in einen internen Fehler.

Die neue Migration ergaenzt alles Fehlende und ist durchgehend mit
IF NOT EXISTS geschrieben, weil bestehende Datenbanken je nach Zeitpunkt der
Einrichtung unterschiedliche Staende haben. Geprueft gegen eine frische
Datenbank, gegen eine auf altem Stand und auf mehrfaches Anwenden.

Der Testharness wendet jetzt alle Migrationen der Reihe nach an statt nur der
ersten - sonst faellt so etwas beim naechsten Mal wieder nicht auf.

Ausserdem scheiterte das Buchen komplett, wenn eine Bestellung zwischenzeitlich
ueber einen anderen Import gebucht worden war: die eindeutige Bestell-ID kippte
die gesamte Transaktion. Solche Zeilen werden jetzt uebersprungen und gezaehlt,
die uebrigen laufen durch.

Dazu fehlten in der Oberflaeche die Wege zum Bearbeiten und Loeschen eines
Spielers, obwohl es die Endpunkte gab. Beides ist jetzt auf der Spielerseite
erreichbar; das Loeschen verlangt den Namen als Bestaetigung und benennt
vorher, was mit verschwindet.
This commit is contained in:
2026-09-18 17:43:25 +02:00
parent 664a0fd5ee
commit 751f8bfe8e
6 changed files with 374 additions and 11 deletions
+18 -1
View File
@@ -378,8 +378,24 @@ export async function commitImport(importId: number, ctx: ActionContext) {
// Mehrere Zeilen können denselben neuen Spieler betreffen.
const createdPlayers = new Map<string, number>();
let booked = 0;
let skipped = 0;
for (const row of bookable) {
// Zwischen Vorschau und Bestätigung kann dieselbe Bestellung über einen
// anderen Import gebucht worden sein. Dann diese Zeile überspringen,
// statt den gesamten Import an der eindeutigen Bestell-ID scheitern zu
// lassen - die übrigen Zeilen sind ja in Ordnung.
if (row.externalId) {
const bereitsGebucht = await tx.importedOrder.findUnique({
where: { externalId: row.externalId },
select: { id: true },
});
if (bereitsGebucht) {
skipped += 1;
continue;
}
}
const key = (row.playerKey ?? '').trim();
let playerId = row.resolvedPlayerId;
@@ -444,11 +460,12 @@ export async function commitImport(importId: number, ctx: ActionContext) {
details: {
filename: record.filename,
booked,
skipped,
createdPlayers: createdPlayers.size,
},
});
return { booked, createdPlayers: createdPlayers.size, import: updated };
return { booked, skipped, createdPlayers: createdPlayers.size, import: updated };
});
// Nach dem Buchen werden die ungenutzten Spalten der Datei nicht mehr gebraucht.