Merge branch 'phase/025-zuweisungsmatrix'

This commit is contained in:
2026-10-12 13:06:33 +02:00
16 changed files with 1608 additions and 16 deletions
+69
View File
@@ -0,0 +1,69 @@
import { prisma } from "@/lib/db";
import { matrixAufbauen, type MatrixDaten, type MatrixFilter } from "@/lib/zuweisungsmatrix";
/**
* Lesemodell der Zuweisungsmatrix (#025). Jede angemeldete Rolle darf es sehen – wie die
* Verwendungen auf Schluessel- und Hostseite auch.
*
* Feste `select`-Listen ohne Chiffrat-Felder (CLAUDE.md). Nur aktive Schluessel und nicht
* archivierte Hosts: widerrufene oder rotierte Keys haben keine Zukunft auf einem Host, und
* ein archivierter Host wird nicht mehr abgeglichen.
*/
export async function zuweisungsDaten(): Promise<MatrixDaten> {
const nichtEntfernt = { zustand: { not: "ENTFERNT" as const } };
const [schluessel, hosts, gruppen, oeffentlich, privat] = await Promise.all([
prisma.schluessel.findMany({
where: { status: "AKTIV" },
select: {
id: true,
name: true,
fingerprint: true,
kategorie: true,
person: { select: { id: true, name: true } },
},
orderBy: [{ name: "asc" }, { id: "asc" }],
}),
prisma.host.findMany({
where: { archiviertAm: null },
select: { id: true, name: true, gruppen: { select: { hostgruppeId: true } } },
orderBy: { name: "asc" },
}),
prisma.hostgruppe.findMany({ select: { id: true, name: true }, orderBy: { name: "asc" } }),
prisma.publicVerwendung.findMany({
where: { ...nichtEntfernt, schluessel: { status: "AKTIV" } },
select: {
id: true,
schluesselId: true,
hostId: true,
hostgruppeId: true,
zielbenutzer: true,
optionen: true,
zustand: true,
},
orderBy: { angelegtAm: "asc" },
}),
prisma.privateVerwendung.findMany({
where: { ...nichtEntfernt, schluessel: { status: "AKTIV" } },
select: { id: true, schluesselId: true, hostId: true, zielbenutzer: true, pfad: true, zustand: true },
orderBy: { angelegtAm: "asc" },
}),
]);
return {
schluessel,
hosts: hosts.map((h) => ({ id: h.id, name: h.name, gruppenIds: h.gruppen.map((g) => g.hostgruppeId) })),
gruppen,
oeffentlich,
privat,
};
}
export async function zuweisungsMatrix(filter: MatrixFilter = {}) {
const daten = await zuweisungsDaten();
// Personen fuer den Filter: nur die, denen ein aktiver Schluessel gehoert.
const personen = [
...new Map(
daten.schluessel.flatMap((s) => (s.person ? [[s.person.id, s.person] as const] : [])),
).values(),
].sort((a, b) => a.name.localeCompare(b.name, "de"));
return { matrix: matrixAufbauen(daten, filter), gruppen: daten.gruppen, personen };
}