Files
nebula/prisma/seed.ts
T
florian.wildeandClaude Opus 5 01d42662ca 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>
2026-07-25 21:30:12 +02:00

122 lines
3.2 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 { PrismaClient, ProjectStatus } from "@prisma/client";
const prisma = new PrismaClient();
interface SampleNote {
title?: string | null;
content: string;
pinned?: boolean;
}
interface SampleProject {
name: string;
slug: string;
summary: string;
description: string;
status: ProjectStatus;
priority: number;
progress: number;
accent: string;
tags: string[];
favorite: boolean;
notes: SampleNote[];
}
/**
* Legt ein paar Beispielprojekte an, damit das Dashboard nach dem ersten
* Start nicht leer ist. Idempotent: bereits vorhandene Slugs werden
* uebersprungen.
*/
async function main() {
const samples: SampleProject[] = [
{
name: "Nebula",
slug: "nebula",
summary: "Dieses Dashboard – Uebersicht ueber alle Vibe-Coding Projekte.",
description:
"Meta: Nebula verwaltet sich selbst. Notizen, Status und Git-Infos an einem Ort.",
status: ProjectStatus.IN_DEVELOPMENT,
priority: 3,
progress: 65,
accent: "violet",
tags: ["next.js", "prisma", "dashboard"],
favorite: true,
notes: [
{
title: "Naechste Schritte",
content:
"- Kanban-Ansicht ergaenzen\n- Webhook-Endpoint fuer Push-Events\n- Export als Markdown",
pinned: true,
},
],
},
{
name: "Synthwave CLI",
slug: "synthwave-cli",
summary: "Terminal-Tool, das Projektgeruest inkl. CI in Sekunden erzeugt.",
description:
"Idee: ein `npx synthwave init` das Repo, Lint, Tests, Container und Pipeline vorkonfiguriert.",
status: ProjectStatus.PLANNING,
priority: 2,
progress: 15,
accent: "cyan",
tags: ["cli", "typescript", "dx"],
favorite: false,
notes: [
{
title: null,
content: "Konkurrenz pruefen: create-t3-app, degit, plop.",
pinned: false,
},
],
},
{
name: "Pixelgarten",
slug: "pixelgarten",
summary: "Browser-Spiel: ein Garten, der aus Commit-Aktivitaet waechst.",
description:
"Rohe Idee. Jeder Commit pflanzt eine Pflanze, Streaks lassen sie bluehen.",
status: ProjectStatus.IDEA,
priority: 1,
progress: 0,
accent: "emerald",
tags: ["spiel", "canvas", "fun"],
favorite: false,
notes: [],
},
];
// 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.findFirst({
where: { slug: sample.slug, ownerId: null },
});
if (existing) {
console.log(` · uebersprungen (existiert): ${sample.slug}`);
continue;
}
const { notes, ...project } = sample;
await prisma.project.create({
data: {
...project,
notes: notes.length ? { create: notes } : undefined,
},
});
console.log(` ✓ angelegt: ${sample.slug}`);
}
}
main()
.then(async () => {
console.log("Seed abgeschlossen.");
await prisma.$disconnect();
})
.catch(async (error) => {
console.error("Seed fehlgeschlagen:", error);
await prisma.$disconnect();
process.exit(1);
});