feat(seed): mitgelieferte Vorlagen am Schluessel erkennen (#42)
This commit was merged in pull request #42.
This commit is contained in:
@@ -68,11 +68,61 @@ export type GesaeteVorlage = {
|
||||
readonly neu: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sucht die mitgelieferte Vorlage – zuerst am Schluessel, dann am Namen.
|
||||
*
|
||||
* Der Schluessel ueberlebt ein Umbenennen, der Name nicht: genau daran legte der
|
||||
* Seed eine umbenannte Vorlage ein zweites Mal an, und der Schnellstart stand
|
||||
* auf der Geraeteseite doppelt (#021). Der Rueckfall auf den Namen bleibt, weil
|
||||
* eine Installation von vor diesem Feld noch keinen Schluessel hat — ohne ihn
|
||||
* bekaeme sie beim ersten Lauf danach genau die Dubletten, die das Feld
|
||||
* verhindern soll. Wird sie so gefunden, traegt der Seed den Schluessel nach.
|
||||
*
|
||||
* Auch eine **archivierte** Vorlage gilt als vorhanden: eine zweite gleichen
|
||||
* Namens danebenzustellen waere keine Hilfe, sondern eine Dublette in jeder
|
||||
* Liste. Wer die Beispielvorlage zurueck will, holt sie aus dem Archiv.
|
||||
*/
|
||||
async function mitgelieferteFinden(db: PrismaClient, dokument: Austausch) {
|
||||
const mitVersion = {
|
||||
versionen: {
|
||||
where: { status: VersionStatus.VEROEFFENTLICHT },
|
||||
orderBy: { version: "desc" as const },
|
||||
take: 1,
|
||||
},
|
||||
};
|
||||
|
||||
if (dokument.seedSchluessel !== undefined) {
|
||||
const amSchluessel = await db.vorlage.findFirst({
|
||||
where: { seedSchluessel: dokument.seedSchluessel },
|
||||
include: mitVersion,
|
||||
});
|
||||
if (amSchluessel) return amSchluessel;
|
||||
}
|
||||
|
||||
const amNamen = await db.vorlage.findFirst({
|
||||
// Nur eine Zeile **ohne** Schluessel darf hier zugeordnet werden. Sonst
|
||||
// koennte eine fremde Vorlage, die zufaellig so heisst wie die mitgelieferte,
|
||||
// deren Schluessel bekommen - und der naechste Lauf wuerde sie fuer das
|
||||
// Original halten.
|
||||
where: { name: dokument.name, kundeId: null, seedSchluessel: null },
|
||||
include: mitVersion,
|
||||
});
|
||||
if (amNamen && dokument.seedSchluessel !== undefined) {
|
||||
await db.vorlage.update({
|
||||
where: { id: amNamen.id },
|
||||
data: { seedSchluessel: dokument.seedSchluessel },
|
||||
});
|
||||
console.log(` Vorlage „${amNamen.name}“: Schlüssel ${dokument.seedSchluessel} nachgetragen`);
|
||||
}
|
||||
return amNamen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Vorlagen als veroeffentlichte Version 1 an.
|
||||
*
|
||||
* Idempotent ueber den **Namen**: gibt es die Vorlage schon, bleibt sie
|
||||
* unangetastet — auch dann, wenn jemand sie inzwischen bearbeitet hat. Ein
|
||||
* Idempotent ueber den **Schluessel** (Rueckfall: Name, siehe
|
||||
* `mitgelieferteFinden`): gibt es die Vorlage schon, bleibt sie unangetastet —
|
||||
* auch dann, wenn jemand sie inzwischen bearbeitet oder umbenannt hat. Ein
|
||||
* zweiter Seed-Lauf darf die Arbeit eines Redakteurs nicht zurueckdrehen, und
|
||||
* eine veroeffentlichte Version wird ohnehin nie veraendert.
|
||||
*/
|
||||
@@ -82,19 +132,7 @@ export async function vorlagenSaeen(db: PrismaClient): Promise<readonly GesaeteV
|
||||
let uebersprungen = 0;
|
||||
|
||||
for (const { dokument } of vorlagenLesen()) {
|
||||
const vorhanden = await db.vorlage.findFirst({
|
||||
// Auch eine **archivierte** Vorlage gilt als vorhanden: eine zweite gleichen
|
||||
// Namens danebenzustellen waere keine Hilfe, sondern eine Dublette in jeder
|
||||
// Liste. Wer die Beispielvorlage zurueck will, holt sie aus dem Archiv.
|
||||
where: { name: dokument.name, kundeId: null },
|
||||
include: {
|
||||
versionen: {
|
||||
where: { status: VersionStatus.VEROEFFENTLICHT },
|
||||
orderBy: { version: "desc" },
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
const vorhanden = await mitgelieferteFinden(db, dokument);
|
||||
const veroeffentlichte = vorhanden?.versionen[0];
|
||||
if (vorhanden && veroeffentlichte) {
|
||||
ergebnis.push({
|
||||
@@ -131,6 +169,7 @@ export async function vorlagenSaeen(db: PrismaClient): Promise<readonly GesaeteV
|
||||
beschreibung: dokument.beschreibung ?? null,
|
||||
kategorie: dokument.kategorie ?? null,
|
||||
schlagworte: [...dokument.schlagworte],
|
||||
seedSchluessel: dokument.seedSchluessel ?? null,
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "PC Neuinstallation",
|
||||
"seedSchluessel": "pc-neuinstallation",
|
||||
"beschreibung": "Vollständige Neuinstallation eines Arbeitsplatzrechners: von der Datensicherung des alten Systems über Installation, Einbindung und Verschlüsselung bis zur Übergabe an den Benutzer.",
|
||||
"kategorie": "Client",
|
||||
"schlagworte": ["windows", "client", "neuinstallation", "bitlocker"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "Mitarbeiter-Onboarding",
|
||||
"seedSchluessel": "mitarbeiter-onboarding",
|
||||
"beschreibung": "Neues Benutzerkonto im Active Directory oder in Entra ID anlegen, Hardware bereitstellen und den ersten Arbeitstag begleiten.",
|
||||
"kategorie": "Benutzer",
|
||||
"schlagworte": ["onboarding", "eintritt", "benutzerkonto", "active directory", "entra id"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "Mitarbeiter-Offboarding",
|
||||
"seedSchluessel": "mitarbeiter-offboarding",
|
||||
"beschreibung": "Konto sperren, Postfach und Daten übergeben, Hardware und Zugänge einsammeln, wenn jemand das Haus verlässt.",
|
||||
"kategorie": "Benutzer",
|
||||
"schlagworte": ["offboarding", "austritt", "benutzerkonto", "sperrung"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "Server-Inbetriebnahme Windows-VM",
|
||||
"seedSchluessel": "server-inbetriebnahme",
|
||||
"beschreibung": "Inbetriebnahme einer neuen Windows-Server-VM: Planung und Adressvergabe, Installation, Domänenbeitritt, Absicherung sowie Aufnahme in Backup und Monitoring.",
|
||||
"kategorie": "Server",
|
||||
"schlagworte": ["windows", "server", "vm", "inbetriebnahme"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "Firewall-Rollout OPNsense",
|
||||
"seedSchluessel": "firewall-rollout-opnsense",
|
||||
"beschreibung": "Austausch oder Neuaufbau einer OPNsense-Firewall: von den Providerdaten über Regelwerk und VPN bis zur Abnahme und zur außer Betrieb genommenen Altfirewall.",
|
||||
"kategorie": "Netzwerk",
|
||||
"schlagworte": ["firewall", "opnsense", "netzwerk", "vpn", "rollout"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "Monatlicher Patchday",
|
||||
"seedSchluessel": "monatlicher-patchday",
|
||||
"beschreibung": "Der wiederkehrende Ablauf für Updates an Servern, Hypervisor, Netzgeräten und Clients: ankündigen, einspielen, kontrollieren und berichten.",
|
||||
"kategorie": "Wartung",
|
||||
"schlagworte": ["patchday", "updates", "wartung", "monatlich"],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"format": 1,
|
||||
"name": "Backup-Restore-Test",
|
||||
"seedSchluessel": "backup-restore-test",
|
||||
"beschreibung": "Der regelmäßige Nachweis, dass sich eine Sicherung wirklich zurückholen lässt: Wiederherstellungspunkt prüfen, in einer isolierten Umgebung zurückspielen, Funktion und Dauer festhalten.",
|
||||
"kategorie": "Wartung",
|
||||
"schlagworte": ["backup", "restore", "wiederherstellung", "test", "wartung"],
|
||||
|
||||
Reference in New Issue
Block a user