feat(db): Datenmodell fuer Benutzer, Sitzungen und Passkeys

Neue Tabellen:
- User        Konto mit Rolle, optionalem Passwort-Hash, Sperrzaehler.
              Das Passwort ist optional, weil ein Konto auch ausschliesslich
              per Passkey nutzbar sein darf.
- Session     serverseitige Sitzung. Gespeichert wird nur der SHA-256-Hash
              des Cookie-Tokens, damit ein Datenbankleck keine uebernehmbaren
              Sitzungen ergibt.
- Credential  ein Passkey je Zeile, mit oeffentlichem Schluessel, Transporten
              und Signaturzaehler.
- WebAuthnChallenge  kurzlebig und einmalig verwendbar, deshalb in der
              Datenbank statt im Cookie.
- AppSettings  Betriebsart und Registrierung, genau eine Zeile.

Project und GitConnection bekommen einen Besitzer. Bewusst nullable: so
ueberstehen Bestandsdaten die Migration und werden beim Anlegen des ersten
Kontos uebernommen. Slug und Verbindungsname sind dadurch nur noch je
Besitzer eindeutig - zwei Personen duerfen beide ein Projekt "dashboard"
haben.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-25 21:30:12 +02:00
co-authored by Claude Opus 5
parent dbcf30efc1
commit 01d42662ca
3 changed files with 272 additions and 4 deletions
+5 -2
View File
@@ -86,9 +86,12 @@ async function main() {
},
];
// Der Slug ist seit der Benutzerverwaltung nur je Besitzer eindeutig.
// Die Seed-Projekte entstehen ohne Besitzer und werden beim Einrichten
// des ersten Kontos uebernommen.
for (const sample of samples) {
const existing = await prisma.project.findUnique({
where: { slug: sample.slug },
const existing = await prisma.project.findFirst({
where: { slug: sample.slug, ownerId: null },
});
if (existing) {
console.log(` · uebersprungen (existiert): ${sample.slug}`);