Files
sshkeyvault/src/server/actions/formular.ts
T
florian.wildeandClaude Opus 5.5 4f9d5d9680 feat(hosts): Services, Lesemodelle und Aktionen fuer Hosts (#008)
Hosts und Hostgruppen brauchen eine Schreibschicht, bevor Host-Key-Pruefung
(#009) und Bootstrap (#010) darauf aufsetzen. Die Regeln (Name, Adresse wie
der DB-CHECK, Port, Tags, Anmeldeart) liegen framework-frei in src/lib/hosts.ts,
damit Action (Feldmeldungen) und Service (Schutz fuer Seed und Assistenten)
dieselben pruefen.

Archivieren statt Loeschen haelt Protokollbezuege lesbar; dabei fallen die
Gruppenmitgliedschaften weg, damit Zuweisungen an eine Gruppe nie einen
archivierten Host treffen. Jede Aenderung landet mit den geaenderten Feldern
im Protokoll, Eindeutigkeitsverletzungen kommen als deutsche HostFehler.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:42:56 +02:00

38 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Benutzer } from "@/generated/prisma/client";
import { BestaetigungFehler, RechteFehler } from "@/server/auth/sitzungspflicht";
import { HostFehler, type Akteur } from "@/server/services/hosts";
/**
* Gemeinsames fuer Formular-Aktionen (#008). Kein "use server": diese Datei exportiert
* Hilfen, keine Aktionen – sonst waeren sie vom Browser aus aufrufbar.
*/
export type FormularZustand = {
readonly fehler?: string;
readonly feldfehler?: Record<string, string>;
};
/** Fachliche Fehler werden zur Meldung im Formular; alles andere bleibt ein echter Fehler. */
export function fehlerZustand(fehler: unknown): FormularZustand {
if (fehler instanceof HostFehler) {
return { fehler: fehler.message, feldfehler: fehler.feldfehler };
}
if (fehler instanceof RechteFehler || fehler instanceof BestaetigungFehler) {
return { fehler: fehler.message };
}
throw fehler;
}
export function akteurVon(benutzer: Pick<Benutzer, "id" | "name">): Akteur {
return { id: benutzer.id, name: benutzer.name };
}
/** Einzelnes Textfeld; fehlend bleibt `undefined`, damit Standardwerte des Schemas greifen. */
export function textfeld(formular: FormData, name: string): string | undefined {
const wert = formular.get(name);
return typeof wert === "string" && wert !== "" ? wert : undefined;
}
export function listenfeld(formular: FormData, name: string): string[] {
return formular.getAll(name).filter((w): w is string => typeof w === "string" && w !== "");
}