diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..35a158b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,104 @@ +# Nebula – Hinweise für Claude Code + +Dashboard für Vibe-Coding-Projekte. Next.js 15 (App Router), TypeScript, +Tailwind 4, Prisma, PostgreSQL. Oberfläche und Texte sind **deutsch**. + +Funktionsumfang: [FEATURES.md](FEATURES.md) · Geplantes: [ROADMAP.md](ROADMAP.md) · +Betrieb: [README.md](README.md) + +## Womit man arbeitet + +```bash +docker compose up -d db # Postgres, muss laufen +npm run dev # Entwicklung +npm test # Unit-Tests (Vitest, ohne DB) +npx tsc --noEmit # Typprüfung +npm run build # Produktionsbau +docker compose --profile full up -d --build # alles im Container +``` + +**Vor dem `npm run build` einen laufenden `npm start`/`npm run dev` beenden.** +Sonst hält der Prozess die Prisma-Engine-DLL und der Bau bricht unter Windows +mit `EPERM … query_engine-windows.dll.node` ab. + +## Nicht verhandelbar + +**Datentrennung.** Jede Abfrage filtert auf den Besitzer, und zwar an erster +Stelle in der `where`-Klausel. Schreiben und Löschen laufen über +`updateMany`/`deleteMany` mit `ownerId`, damit fremde Datensätze gar nicht +erst getroffen werden. Fremde IDs liefern **404, nicht 403** — die Antwort +soll nicht bestätigen, dass es den Datensatz gibt. + +**Jeder Endpunkt prüft selbst.** `requireUserApi()` bzw. `requireUserPage()` +sind die Sicherheitsgrenze. Die Middleware schaut nur, ob überhaupt ein +Cookie mitkommt — im Edge-Runtime gibt es keine Datenbank. + +**Eingaben validieren.** Zod an jeder API-Grenze, Body über `readJsonBody` +(erzwingt `application/json` und begrenzt die Größe). + +**Keine Geheimnisse nach außen.** Git-Tokens verlassen den Server nie; +Verbindungen werden über `connectionSafeSelect` geladen. Projekt-Exporte +enthalten grundsätzlich keine Tokens. + +**Ausgehende Aufrufe nur über `lib/git/http.ts`** — dort greift der +SSRF-Schutz (`lib/security/ssrf.ts`). + +## Fallstricke, die schon zugeschlagen haben + +- **`node:`-Module in Client-Komponenten.** `lib/crypto`, `lib/auth/password`, + `lib/git/index` ziehen `node:crypto`/`node:net` nach. Client-Komponenten + importieren stattdessen `lib/git/meta` bzw. `lib/auth/constants`. +- **`instrumentation.ts` wird auch für Edge übersetzt.** Der dynamische Import + muss *innerhalb* von `if (process.env.NEXT_RUNTIME === "nodejs")` stehen, + sonst scheitert der Bau an `node:crypto`. +- **Eigene CSS-Klassen gehören in `app/components.css`** und dort in + `@layer components`. Außerhalb eines Layers gewinnen sie gegen + Tailwind-Utilities — dann greift `pl-9` neben `.field` nicht mehr. +- **Menüs und Dialoge über Portal.** Karten setzen `overflow-hidden` und + `backdrop-filter`; Letzteres erzeugt einen neuen Bezugsrahmen, in dem + `position: fixed` und `z-index` nicht mehr wie erwartet wirken. Dafür gibt + es `components/ui/Popover.tsx` und `components/ui/Modal.tsx`. +- **Overlays brauchen einen deckenden Hintergrund** (`.popover`), nicht + `.glass` — dessen 3,5 % Deckkraft lassen alles durchscheinen. +- **Datumsangaben** über `lib/utils` formatieren (feste Zeitzone), sonst + weichen Server-Render und Hydration voneinander ab. Relative Zeiten + bekommen `suppressHydrationWarning`. + +## Migrationen + +`prisma migrate dev` ist hier nicht benutzbar (interaktiv). Stattdessen: + +```bash +npx prisma migrate diff --from-schema-datasource prisma/schema.prisma \ + --to-schema-datamodel prisma/schema.prisma --script --output prisma/migrations/_/migration.sql +npx prisma migrate deploy +``` + +**Die erzeugte SQL vor dem Anwenden lesen.** Der Volltextindex +`Note_fulltext_idx` ist ein Ausdrucksindex, den Prisma nicht kennt (er wird +bislang in Ruhe gelassen, aber das ist nicht garantiert). + +## Prüfen, nicht behaupten + +Vor „fertig": `npx tsc --noEmit`, `npm test`, `npm run build`. + +Bei Änderungen an der Oberfläche **hinsehen**. Chrome ist installiert, ein +Skript mit `playwright-core` und `channel: "chrome"` genügt für Screenshots. +Mehrere Anzeigefehler dieses Projekts sind ausschließlich so aufgefallen. + +**Niemals gegen die echte Datenbank testen.** Eine Wegwerf-Datenbank anlegen +und danach löschen: + +```bash +docker exec nebula-db psql -U nebula -d postgres -c "CREATE DATABASE nebula_test" +DATABASE_URL=postgresql://nebula:nebula@localhost:5432/nebula_test npx prisma migrate deploy +``` + +## Sprache + +Code-Kommentare, Commit-Nachrichten und Oberfläche auf Deutsch, **ohne +Umlaute in Bezeichnern und Commit-Nachrichten** (bestehende Konvention). +In Markdown-Dateien und in der Oberfläche sind Umlaute erwünscht. + +Commits: Conventional Commits, Betreff deutsch, Rumpf erklärt **warum** — +nicht was der Diff ohnehin zeigt.