Warnung vor doppelt abgelegten statischen Codes
Ein statischer Code traegt seinen Inhalt selbst — zweimal derselbe Inhalt ergibt zweimal exakt dasselbe Bild. Bisher entstand der zweite Eintrag stillschweigend. Das Anlegen antwortet nun mit 409 und nennt den vorhandenen Eintrag samt Namen und Datum; die Oberflaeche zeigt das als Warnung mit dem Knopf "Trotzdem ablegen". Eine Rueckfrage, keine Sperre — zwei Fassungen desselben Codes koennen gewollt sein. Verglichen wird Typ und Inhalt innerhalb der Gruppe, nicht die Gestaltung. Dynamische Codes bleiben aussen vor: zwei Kurz-Links auf dasselbe Ziel sind der Normalfall, sobald getrennt gezaehlt werden soll. ApiError traegt dafuer jetzt Status und Antwortkoerper — eine gemeldete Dublette ist keine Sackgasse, sondern eine Rueckfrage. Refs #6
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import "server-only";
|
||||
|
||||
import { toJsonInput } from "@/lib/codes";
|
||||
import { prisma } from "@/lib/db";
|
||||
|
||||
/**
|
||||
* Dublettenprüfung für statische Codes.
|
||||
*
|
||||
* Ein statischer Code trägt seinen Inhalt selbst — zweimal derselbe Inhalt
|
||||
* ergibt zweimal exakt dasselbe Bild. Solche Einträge sind nicht falsch, aber
|
||||
* sie fluten die Liste, und beim Wiederfinden weiß niemand mehr, welcher der
|
||||
* beiden gemeint war.
|
||||
*
|
||||
* Bewusst **nur** für statische Codes: Zwei dynamische Codes mit demselben
|
||||
* Ziel sind ein üblicher Fall — zwei Kampagnen, zwei Kurz-Links, getrennte
|
||||
* Zähler. Da wäre eine Warnung nur lästig.
|
||||
*
|
||||
* Bewusst **ohne** die Gestaltung: Verglichen wird der Inhalt. Derselbe Inhalt
|
||||
* einmal in Schwarz-Weiß für den Druck und einmal in Hausfarben ist zwar
|
||||
* bewusst zweimal angelegt — aber eben auch zweimal derselbe Code. Die
|
||||
* Warnung sagt das und lässt sich übergehen.
|
||||
*/
|
||||
export type StaticDuplicate = {
|
||||
id: string;
|
||||
label: string | null;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sucht einen bereits abgelegten statischen Code mit gleichem Typ und
|
||||
* gleichem Inhalt in derselben Gruppe — den zuletzt angelegten.
|
||||
*
|
||||
* Die Gruppe grenzt bewusst ein: Ein Treffer aus einer fremden Gruppe wäre
|
||||
* nicht bloß nutzlos, er verriete auch deren Bestand.
|
||||
*/
|
||||
export async function findStaticDuplicate(
|
||||
groupId: string,
|
||||
type: string,
|
||||
data: Record<string, unknown>,
|
||||
): Promise<StaticDuplicate | null> {
|
||||
const treffer = await prisma.qrCode.findFirst({
|
||||
where: {
|
||||
mode: "static",
|
||||
type,
|
||||
groupId,
|
||||
// Postgres vergleicht jsonb nach Struktur, nicht nach Schreibweise —
|
||||
// Schlüsselreihenfolge und Leerzeichen spielen keine Rolle.
|
||||
data: { equals: toJsonInput(data) },
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
select: { id: true, label: true, createdAt: true },
|
||||
});
|
||||
|
||||
if (!treffer) return null;
|
||||
|
||||
return {
|
||||
id: treffer.id,
|
||||
label: treffer.label,
|
||||
createdAt: treffer.createdAt.toISOString(),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user