docs: README und Funktionsuebersicht
README als Einstieg: was Nebula ist, drei Wege zur Inbetriebnahme (Standalone, komplett Docker, eigene PostgreSQL), Tabelle aller Umgebungsvariablen, Anleitung fuer die Git-Verbindung inklusive der noetigen Token-Scopes je System, Projektstruktur, npm-Skripte, API-Uebersicht, Sicherheitshinweise und eine Fehlersuchtabelle. FEATURES.md listet den Funktionsumfang vollstaendig nach Bereichen auf: Projekte und Status, Dashboard, Notizen, Git-Anbindung inklusive der beim Sync geholten Daten, Oberflaeche sowie Datenmodell, Sicherheit und Betrieb. Am Ende stehen bewusst nicht umgesetzte Ideen fuer spaeter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+207
@@ -0,0 +1,207 @@
|
|||||||
|
# Funktionsübersicht
|
||||||
|
|
||||||
|
Vollständige Auflistung dessen, was Nebula kann — gegliedert nach Bereichen.
|
||||||
|
Für Installation und Betrieb siehe [README.md](README.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Projekte
|
||||||
|
|
||||||
|
### 1.1 Anlegen und Verwalten
|
||||||
|
|
||||||
|
- **Idee genügt.** Ein Projekt braucht nur einen Namen. Alles Weitere — Beschreibung,
|
||||||
|
Repository, Tags — lässt sich jederzeit nachtragen. Neue Projekte starten deshalb
|
||||||
|
standardmäßig im Status *Idee*.
|
||||||
|
- **Bearbeiten** über einen Dialog, der auf dem Dashboard und der Projektseite
|
||||||
|
identisch funktioniert.
|
||||||
|
- **Löschen** mit Rückfrage; zugehörige Notizen und der Repo-Snapshot verschwinden mit
|
||||||
|
(Fremdschlüssel mit `ON DELETE CASCADE`).
|
||||||
|
- **Slug** wird automatisch aus dem Namen erzeugt (umlautfest) und bei Namenskollision
|
||||||
|
durchnummeriert.
|
||||||
|
|
||||||
|
### 1.2 Felder
|
||||||
|
|
||||||
|
| Feld | Beschreibung |
|
||||||
|
| --- | --- |
|
||||||
|
| Name | Pflichtfeld |
|
||||||
|
| Kurzbeschreibung | Ein Satz für die Karte im Board |
|
||||||
|
| Beschreibung | Ausführliche Ideenskizze, Zeilenumbrüche bleiben erhalten |
|
||||||
|
| Status | Idee · In Planung · Offen · In Entwicklung · Fertig · Archiviert |
|
||||||
|
| Priorität | Niedrig · Normal · Hoch · Kritisch |
|
||||||
|
| Fortschritt | 0–100 %, per Regler |
|
||||||
|
| Akzentfarbe | Sechs Farbverläufe, prägen Karte und Detailseite |
|
||||||
|
| Tags | Kommagetrennt, bis zu 12 Stück, kleingeschrieben und dedupliziert |
|
||||||
|
| Favorit | Anpinnen — Favoriten stehen im Board immer oben |
|
||||||
|
| Git-Verbindung | Optionale Zuordnung zu einem Git-System |
|
||||||
|
| Repository | URL sowie Owner/Name (werden aus der URL abgeleitet) |
|
||||||
|
|
||||||
|
### 1.3 Status
|
||||||
|
|
||||||
|
Sechs Zustände, jeder mit eigener Farbe und Erklärung im Auswahlmenü:
|
||||||
|
|
||||||
|
| Status | Bedeutung |
|
||||||
|
| --- | --- |
|
||||||
|
| **Idee** | Noch ein Gedanke — nichts gebaut, nichts entschieden |
|
||||||
|
| **In Planung** | Scope, Stack und Schnitt werden festgelegt |
|
||||||
|
| **Offen** | Startklar, liegt aber gerade still |
|
||||||
|
| **In Entwicklung** | Wird aktiv gebaut |
|
||||||
|
| **Fertig** | Ausgeliefert und abgeschlossen |
|
||||||
|
| **Archiviert** | Ruht — bleibt erhalten, ist im Board aber ausgeblendet |
|
||||||
|
|
||||||
|
Der Status ist **direkt auf der Projektkarte** umschaltbar, ohne den Detailbereich zu
|
||||||
|
öffnen. Die Änderung wird optimistisch angezeigt und bei einem Fehler zurückgerollt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Dashboard
|
||||||
|
|
||||||
|
- **Kennzahlen** oben: Anzahl Projekte mit Ø-Fortschritt, offene Ideen, aktive
|
||||||
|
Entwicklungen, fertige Projekte, verknüpfte Repositories.
|
||||||
|
- **Volltextsuche** über Name, Kurzbeschreibung, Beschreibung, Tags und Repo-Pfad.
|
||||||
|
- **Statusfilter** als Chips mit Trefferzähler, mehrere gleichzeitig kombinierbar.
|
||||||
|
- **Sortierung** nach zuletzt geändert, Anlagedatum, Name, Fortschritt oder Priorität —
|
||||||
|
Favoriten bleiben stets oben.
|
||||||
|
- **Zwei Ansichten**: freies Raster oder nach Status gruppierte Abschnitte.
|
||||||
|
- **Archiv** ist standardmäßig ausgeblendet und per Schalter einblendbar.
|
||||||
|
- **Leerzustände** mit direktem Einstieg statt einer leeren Fläche.
|
||||||
|
|
||||||
|
### Projektkarte auf einen Blick
|
||||||
|
|
||||||
|
Name und Favoritenstern · Kurzbeschreibung · Fortschrittsbalken · Provider-Badge ·
|
||||||
|
Default-Branch samt Anzahl weiterer Branches · letzter Tag · Alter des letzten Commits ·
|
||||||
|
Anzahl Notizen · Warnung bei Sync-Fehler · Tags · Statusauswahl · Priorität.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Notizen
|
||||||
|
|
||||||
|
- **Beliebig viele Notizen pro Projekt**, mit optionalem Titel und mehrzeiligem Text.
|
||||||
|
- **Anpinnen** — angepinnte Notizen stehen oben und sind farblich hervorgehoben.
|
||||||
|
- **Bearbeiten und Löschen** direkt in der Liste; Löschen fragt nach.
|
||||||
|
- **Zeitstempel**: Anlagedatum immer, „bearbeitet vor …" nur bei echter Änderung.
|
||||||
|
- Zeilenumbrüche und Einrückungen bleiben erhalten — Checklisten und Code-Schnipsel
|
||||||
|
überleben das Speichern.
|
||||||
|
- Eine neue Notiz aktualisiert die Änderungszeit des Projekts, damit die Sortierung
|
||||||
|
„zuletzt geändert" die tatsächliche Aktivität abbildet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Git-Anbindung
|
||||||
|
|
||||||
|
### 4.1 Unterstützte Systeme
|
||||||
|
|
||||||
|
| System | API | Authentifizierung | Besonderheit |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| **GitHub** | REST v3 | `Authorization: Bearer` | github.com und GitHub Enterprise (`/api/v3`) |
|
||||||
|
| **GitLab** | API v4 | `PRIVATE-TOKEN` | gitlab.com und Self-Hosted, verschachtelte Gruppen |
|
||||||
|
| **Gitea / Forgejo** | API v1 | `Authorization: token` | beliebige eigene Instanz |
|
||||||
|
|
||||||
|
Mehrere Verbindungen desselben Typs sind möglich — etwa privates GitHub und
|
||||||
|
Firmen-Gitea nebeneinander.
|
||||||
|
|
||||||
|
### 4.2 Verbindungen verwalten
|
||||||
|
|
||||||
|
- Anlegen mit Anzeigename, System, Basis-URL und Access Token.
|
||||||
|
- **Verbindungstest** auf Knopfdruck: prüft Erreichbarkeit und Token, zeigt den erkannten
|
||||||
|
Benutzer und bei Gitea zusätzlich die Serverversion. Ergebnis und Zeitpunkt werden
|
||||||
|
gespeichert und in der Karte angezeigt.
|
||||||
|
- **Token-Verwaltung**: verschlüsselt gespeichert, in der UI nur als Hinweis (`ghp_…9f3a`)
|
||||||
|
sichtbar. Beim Bearbeiten bedeutet ein leeres Feld „unverändert lassen".
|
||||||
|
- **Repository-Auswahl**: Nebula listet alle Repos, auf die der Token Zugriff hat, mit
|
||||||
|
Suchfeld. Ein Klick übernimmt URL, Owner, Name und — falls noch leer — Projektname und
|
||||||
|
Kurzbeschreibung.
|
||||||
|
- **Löschen** trennt nur die Verknüpfung; die Projekte selbst bleiben erhalten.
|
||||||
|
|
||||||
|
### 4.3 Was beim Sync geholt wird
|
||||||
|
|
||||||
|
| Bereich | Details |
|
||||||
|
| --- | --- |
|
||||||
|
| Repository | Voller Pfad, Beschreibung, Default-Branch, Sichtbarkeit, Größe, letzte Aktivität |
|
||||||
|
| Kennzahlen | Stars, Forks, offene Issues, offene Pull-/Merge-Requests |
|
||||||
|
| Branches | bis zu 50, mit SHA, Default-Markierung, Schutzstatus und (wo die API es liefert) letztem Commit |
|
||||||
|
| Tags | bis zu 25, mit SHA, Nachricht und Datum |
|
||||||
|
| Commits | die letzten 15, mit Kurz-SHA, Nachricht, Autor, Datum und Link |
|
||||||
|
| Releases | bis zu 10, inklusive Pre-Release- und Draft-Kennzeichnung |
|
||||||
|
| Sprachen | Verteilung als Balken mit Prozentwerten |
|
||||||
|
|
||||||
|
- **Snapshot-Prinzip**: Alle Daten werden in der Datenbank abgelegt. Das Dashboard bleibt
|
||||||
|
ohne Netzverbindung oder bei erreichtem Rate-Limit vollständig nutzbar.
|
||||||
|
- **URL-Erkennung** für `https://…`, `git@host:owner/repo.git` und GitLab-Weboberflächen-URLs
|
||||||
|
mit `/-/tree/…`; verschachtelte Gruppenpfade bleiben erhalten.
|
||||||
|
- **Ohne Token** funktionieren öffentliche Repositories, mit deutlich strengerem Rate-Limit.
|
||||||
|
- **Fehler landen am Projekt** statt in einer Fehlerseite: die Karte zeigt „Sync-Fehler",
|
||||||
|
die Projektseite die genaue Meldung. Typische HTTP-Codes werden in Klartext übersetzt
|
||||||
|
(401 Token, 403 Scopes/Rate-Limit, 404 Pfad, 408 Timeout).
|
||||||
|
- **Zeitlimit** pro Aufruf über `GIT_API_TIMEOUT_MS` einstellbar; die Teilabfragen laufen
|
||||||
|
parallel, eine fehlschlagende Liste bricht den restlichen Sync nicht ab.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Oberfläche
|
||||||
|
|
||||||
|
- **Dark Glassmorphism**: milchige Glasflächen, driftende Nebel im Hintergrund, feines
|
||||||
|
Raster, Neon-Akzente pro Projektfarbe.
|
||||||
|
- **Animationen**: gestaffelt einblendende Karten, Hover-Lift mit Farbverlaufsrand,
|
||||||
|
animierte Fortschrittsbalken.
|
||||||
|
- **Responsiv** von Handy bis Ultrawide (bis zu vier Kartenspalten).
|
||||||
|
- **Barrierearm**: durchgehende ARIA-Labels, Escape schließt Dialoge, sichtbarer
|
||||||
|
Fokusring, `prefers-reduced-motion` schaltet Animationen ab.
|
||||||
|
- **Deutschsprachig**, Datums- und Zahlenformate in `de-DE` mit fester Zeitzone
|
||||||
|
Europe/Berlin, damit Server- und Browser-Darstellung übereinstimmen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Daten und Technik
|
||||||
|
|
||||||
|
### 6.1 Datenmodell
|
||||||
|
|
||||||
|
| Tabelle | Inhalt |
|
||||||
|
| --- | --- |
|
||||||
|
| `Project` | Projektstammdaten, Status, Fortschritt, Repo-Verknüpfung |
|
||||||
|
| `Note` | Notizen (n:1 zu Projekt, Cascade-Delete) |
|
||||||
|
| `GitConnection` | Git-Systeme inkl. verschlüsseltem Token |
|
||||||
|
| `RepoSnapshot` | Zwischengespeicherter Repo-Stand (1:1 zu Projekt) |
|
||||||
|
|
||||||
|
Listen wie Branches oder Commits liegen als `JSONB`, damit providerspezifische Felder
|
||||||
|
nicht verloren gehen. Indizes auf Status, Verbindung und Änderungsdatum.
|
||||||
|
|
||||||
|
### 6.2 Sicherheit
|
||||||
|
|
||||||
|
- Access Tokens verschlüsselt mit **AES-256-GCM**, Schlüssel per **scrypt** aus
|
||||||
|
`APP_SECRET` abgeleitet, Chiffrat versioniert (`v1.<iv>.<tag>.<data>`).
|
||||||
|
- Tokens werden nie an den Browser gesendet — alle API-Antworten nutzen eine Feldauswahl
|
||||||
|
ohne `tokenCipher`.
|
||||||
|
- **Zod-Validierung** jeder Eingabe an der API-Grenze mit Feldfehlern für die UI.
|
||||||
|
- Prisma arbeitet ausschließlich mit parametrisierten Abfragen.
|
||||||
|
|
||||||
|
### 6.3 Betrieb
|
||||||
|
|
||||||
|
- **Zwei gleichwertige Betriebsarten**: Standalone (Node-Prozess, beliebige PostgreSQL)
|
||||||
|
oder komplett in Docker — dieselbe Codebasis, dieselbe `.env`.
|
||||||
|
- **Docker-Compose-Profile**: `db` läuft immer, `--profile full` startet zusätzlich die
|
||||||
|
App, `--profile tools` bringt Adminer als DB-Oberfläche mit.
|
||||||
|
- **Automatische Migration** beim Containerstart, inklusive Warteschleife auf die
|
||||||
|
Datenbank.
|
||||||
|
- **Healthchecks**: `pg_isready` für Postgres, `/api/health` für die App.
|
||||||
|
- **Setup-Skript** erzeugt die `.env` samt zufälligem `APP_SECRET`.
|
||||||
|
- **Seed-Daten** auf Wunsch, idempotent — mehrfaches Ausführen legt nichts doppelt an.
|
||||||
|
|
||||||
|
### 6.4 API
|
||||||
|
|
||||||
|
Zehn REST-Endpunkte für Projekte, Notizen, Verbindungen, Sync, Repo-Listen und Health.
|
||||||
|
Alles, was die Oberfläche kann, ist damit auch scriptbar. Übersicht in der
|
||||||
|
[README](README.md#api).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Ideen für später
|
||||||
|
|
||||||
|
Bewusst nicht umgesetzt, aber vorgemerkt:
|
||||||
|
|
||||||
|
- Kanban-Board mit Drag & Drop zwischen den Statusspalten
|
||||||
|
- Webhooks, damit Pushes den Snapshot ohne Knopfdruck aktualisieren
|
||||||
|
- Markdown-Rendering in Beschreibung und Notizen
|
||||||
|
- Volltextsuche über Notizen hinweg
|
||||||
|
- Export eines Projekts als Markdown
|
||||||
|
- Automatischer Sync im Hintergrund (Intervall pro Verbindung)
|
||||||
|
- Mehrbenutzerbetrieb mit Login
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
# ✦ Nebula
|
||||||
|
|
||||||
|
**Das Kontrollzentrum für deine Vibe-Coding Projekte.**
|
||||||
|
|
||||||
|
Ideen festhalten · Status pflegen · Notizen sammeln · Git-Repos live im Blick
|
||||||
|
|
||||||
|
<sub>Next.js 15 · TypeScript · Tailwind CSS 4 · Prisma · PostgreSQL · Docker</sub>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Was ist Nebula?
|
||||||
|
|
||||||
|
Vibe Coding produziert schnell viele halbfertige Projekte: ein Repo hier, eine Idee dort,
|
||||||
|
irgendwo eine Notiz in einer Textdatei. Nebula bündelt das an einem Ort.
|
||||||
|
|
||||||
|
Jedes Projekt bekommt einen **Status** (von der rohen Idee bis „Fertig"), beliebig viele
|
||||||
|
**Notizen** und optional ein **verknüpftes Repository**. Nebula holt sich von dort per API
|
||||||
|
Branches, Tags, Commits, Releases und offene Issues/PRs — egal ob **GitHub**, **GitLab**
|
||||||
|
oder eine selbst gehostete **Gitea**-Instanz.
|
||||||
|
|
||||||
|
Alle Daten liegen in **deiner lokalen PostgreSQL**. Es gibt keinen Cloud-Dienst dahinter,
|
||||||
|
Access Tokens werden verschlüsselt abgelegt.
|
||||||
|
|
||||||
|
Eine vollständige Auflistung aller Funktionen steht in **[FEATURES.md](FEATURES.md)**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Schnellstart
|
||||||
|
|
||||||
|
Zwei Betriebsarten, dieselbe Codebasis. Beide brauchen zuerst eine `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node scripts/setup.mjs # legt .env an und erzeugt ein zufälliges APP_SECRET
|
||||||
|
```
|
||||||
|
|
||||||
|
> Ohne Node zur Hand? Einfach `.env.example` nach `.env` kopieren und `APP_SECRET` von Hand
|
||||||
|
> auf einen langen Zufallswert setzen.
|
||||||
|
|
||||||
|
### Variante A — Standalone (empfohlen zum Entwickeln)
|
||||||
|
|
||||||
|
Die App läuft nativ auf dem Rechner, nur PostgreSQL kommt aus dem Container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d db # Postgres 17 auf localhost:5432
|
||||||
|
npm install
|
||||||
|
npm run db:migrate # Schema anlegen
|
||||||
|
npm run db:seed # optional: drei Beispielprojekte
|
||||||
|
npm run dev # → http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Für den Produktivbetrieb ohne Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
npm start # → http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variante B — Alles in Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile full up -d --build # → http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Der App-Container spielt beim Start automatisch die Migrationen ein und wartet dabei auf
|
||||||
|
die Datenbank. Logs mitlesen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile full logs -f app
|
||||||
|
```
|
||||||
|
|
||||||
|
Stoppen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --profile full down # Container weg, Daten bleiben
|
||||||
|
docker compose --profile full down -v # inkl. Datenbank-Volume
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variante C — Eigene, bereits laufende PostgreSQL
|
||||||
|
|
||||||
|
Docker wird gar nicht gebraucht. In der `.env` nur den Connection-String setzen:
|
||||||
|
|
||||||
|
```env
|
||||||
|
DATABASE_URL="postgresql://benutzer:passwort@dbhost:5432/nebula?schema=public"
|
||||||
|
```
|
||||||
|
|
||||||
|
Dann `npm install && npm run db:migrate && npm run dev`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
| Variante | Benötigt |
|
||||||
|
| --- | --- |
|
||||||
|
| Standalone | Node.js ≥ 20.11, npm, PostgreSQL ≥ 14 (lokal oder via Docker) |
|
||||||
|
| Docker | Docker Engine ≥ 24 mit Compose v2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfiguration
|
||||||
|
|
||||||
|
Alle Variablen sind in [`.env.example`](.env.example) dokumentiert.
|
||||||
|
|
||||||
|
| Variable | Bedeutung | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `DATABASE_URL` | PostgreSQL-Verbindung (Prisma) | `postgresql://nebula:nebula@localhost:5432/nebula` |
|
||||||
|
| `APP_SECRET` | Schlüssel für die Token-Verschlüsselung (AES-256-GCM) | — **unbedingt setzen** |
|
||||||
|
| `PORT` | Port der Anwendung | `3000` |
|
||||||
|
| `APP_PORT` | Host-Port-Mapping des App-Containers | `3000` |
|
||||||
|
| `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` | Zugangsdaten des DB-Containers | `nebula` |
|
||||||
|
| `POSTGRES_PORT` | Host-Port der Datenbank | `5432` |
|
||||||
|
| `ADMINER_PORT` | Host-Port von Adminer (`--profile tools`) | `8080` |
|
||||||
|
| `GIT_API_TIMEOUT_MS` | Timeout für Git-API-Aufrufe | `15000` |
|
||||||
|
|
||||||
|
> **`APP_SECRET` nachträglich ändern** macht bereits gespeicherte Git-Tokens unlesbar.
|
||||||
|
> Sie müssen dann in den Verbindungen neu hinterlegt werden — die restlichen Daten bleiben
|
||||||
|
> unberührt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Git-Verbindung einrichten
|
||||||
|
|
||||||
|
1. Im Git-System einen **Personal Access Token** mit Leserechten erzeugen:
|
||||||
|
|
||||||
|
| System | Scopes |
|
||||||
|
| --- | --- |
|
||||||
|
| GitHub | Fine-grained Token: *Contents: Read*, *Metadata: Read*, *Issues: Read*, *Pull requests: Read* |
|
||||||
|
| GitLab | `read_api` (alternativ `read_repository`) |
|
||||||
|
| Gitea / Forgejo | `repository:read`, `issue:read`, `user:read` |
|
||||||
|
|
||||||
|
2. In Nebula unter **Git-Verbindungen → Verbindung hinzufügen** eintragen:
|
||||||
|
System wählen, Basis-URL (z. B. `https://git.meine-firma.de`, ohne `/api`) und Token.
|
||||||
|
3. Mit **Testen** prüfen — Nebula meldet den erkannten Benutzer zurück.
|
||||||
|
4. Beim Anlegen oder Bearbeiten eines Projekts die Verbindung auswählen und über
|
||||||
|
**Repos laden** das Repository aussuchen (oder die URL direkt eintippen).
|
||||||
|
5. Auf der Projektseite **Jetzt synchronisieren** — Branches, Tags, Commits und Releases
|
||||||
|
werden geholt und als Snapshot gespeichert.
|
||||||
|
|
||||||
|
Der Snapshot bleibt in der Datenbank, das Dashboard funktioniert also auch offline.
|
||||||
|
Ohne Token gehen nur öffentliche Repositories, mit strengem Rate-Limit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Projektstruktur
|
||||||
|
|
||||||
|
```
|
||||||
|
nebula/
|
||||||
|
├── docker/entrypoint.sh Migrationen + Serverstart im Container
|
||||||
|
├── docker-compose.yml db (immer) · app (--profile full) · adminer (--profile tools)
|
||||||
|
├── Dockerfile Multi-Stage-Build auf Basis des Next-Standalone-Outputs
|
||||||
|
├── prisma/
|
||||||
|
│ ├── schema.prisma Datenmodell
|
||||||
|
│ ├── migrations/ versionierte SQL-Migrationen
|
||||||
|
│ └── seed.ts Beispieldaten
|
||||||
|
├── scripts/setup.mjs .env erzeugen inkl. APP_SECRET
|
||||||
|
└── src/
|
||||||
|
├── app/
|
||||||
|
│ ├── page.tsx Dashboard (Board, Filter, Kennzahlen)
|
||||||
|
│ ├── projects/[id]/ Projektdetail: Beschreibung, Notizen, Git
|
||||||
|
│ ├── connections/ Verwaltung der Git-Verbindungen
|
||||||
|
│ └── api/ REST-Endpunkte (Projekte, Notizen, Verbindungen, Sync)
|
||||||
|
├── components/ UI-Komponenten (Board, Karten, Panels, Dialoge)
|
||||||
|
├── lib/
|
||||||
|
│ ├── crypto.ts AES-256-GCM für Access Tokens
|
||||||
|
│ ├── db.ts Prisma-Client
|
||||||
|
│ ├── git/ Provider-Adapter: github.ts · gitlab.ts · gitea.ts
|
||||||
|
│ ├── sync.ts Repo-Snapshot holen und speichern
|
||||||
|
│ └── validation.ts Zod-Schemas für alle Eingaben
|
||||||
|
└── types/ gemeinsame Typen für Server und Client
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## npm-Skripte
|
||||||
|
|
||||||
|
| Skript | Zweck |
|
||||||
|
| --- | --- |
|
||||||
|
| `npm run dev` | Entwicklungsserver mit Hot Reload |
|
||||||
|
| `npm run build` / `npm start` | Produktionsbuild und -start (ohne Docker) |
|
||||||
|
| `npm run setup` | `.env` anlegen inkl. generiertem `APP_SECRET` |
|
||||||
|
| `npm run db:migrate` | Migrationen einspielen (`prisma migrate deploy`) |
|
||||||
|
| `npm run db:migrate:dev` | Neue Migration aus Schemaänderungen erzeugen |
|
||||||
|
| `npm run db:seed` | Beispielprojekte anlegen |
|
||||||
|
| `npm run db:studio` | Prisma Studio öffnen |
|
||||||
|
| `npm run db:reset` | Datenbank zurücksetzen (**löscht alles**) |
|
||||||
|
| `npm run typecheck` | TypeScript prüfen |
|
||||||
|
| `npm run docker:db` | Nur die Datenbank starten |
|
||||||
|
| `npm run docker:up` / `docker:down` | Kompletten Stack starten / stoppen |
|
||||||
|
| `npm run docker:tools` | Adminer auf `http://localhost:8080` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
Alle Endpunkte liefern und erwarten JSON.
|
||||||
|
|
||||||
|
| Methode | Pfad | Zweck |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `GET` | `/api/health` | Status inkl. Datenbankverbindung (Docker-Healthcheck) |
|
||||||
|
| `GET` `POST` | `/api/projects` | Projekte auflisten / anlegen |
|
||||||
|
| `GET` `PATCH` `DELETE` | `/api/projects/:id` | Projekt lesen / ändern / löschen |
|
||||||
|
| `POST` | `/api/projects/:id/sync` | Repo-Daten vom Git-System holen |
|
||||||
|
| `GET` `POST` | `/api/projects/:id/notes` | Notizen des Projekts |
|
||||||
|
| `PATCH` `DELETE` | `/api/notes/:id` | Notiz ändern / löschen |
|
||||||
|
| `GET` `POST` | `/api/connections` | Git-Verbindungen |
|
||||||
|
| `PATCH` `DELETE` | `/api/connections/:id` | Verbindung ändern / löschen |
|
||||||
|
| `POST` | `/api/connections/:id/check` | Verbindung und Token testen |
|
||||||
|
| `GET` | `/api/connections/:id/repos` | Zugängliche Repositories auflisten |
|
||||||
|
|
||||||
|
Beispiel — Idee per Kommandozeile anlegen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:3000/api/projects \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"name":"Neue Idee","status":"IDEA","tags":["experiment"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sicherheitshinweise
|
||||||
|
|
||||||
|
- Nebula hat **keine Benutzerverwaltung** und ist für den Betrieb im eigenen Netz gedacht.
|
||||||
|
Vor einer Veröffentlichung im Internet unbedingt einen Reverse Proxy mit Authentifizierung
|
||||||
|
davorschalten.
|
||||||
|
- Access Tokens werden mit **AES-256-GCM** verschlüsselt gespeichert, aus `APP_SECRET` per
|
||||||
|
scrypt abgeleitet. Sie werden ausschließlich serverseitig entschlüsselt und nie an den
|
||||||
|
Browser ausgeliefert — die API zeigt nur einen Hinweis wie `ghp_…9f3a`.
|
||||||
|
- Ist `APP_SECRET` nicht gesetzt, warnt die App beim Start und nutzt einen unsicheren
|
||||||
|
Entwicklungsschlüssel.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fehlersuche
|
||||||
|
|
||||||
|
| Symptom | Ursache / Lösung |
|
||||||
|
| --- | --- |
|
||||||
|
| `Can't reach database server` | Läuft `docker compose up -d db`? Stimmt `DATABASE_URL`? |
|
||||||
|
| `The table ... does not exist` | Migrationen fehlen: `npm run db:migrate` |
|
||||||
|
| Sync meldet `401` | Token abgelaufen oder falsche Scopes — unter Git-Verbindungen neu setzen |
|
||||||
|
| Sync meldet `404` | Owner/Repo prüfen; bei GitLab gehört die volle Gruppenkette in „Owner" |
|
||||||
|
| Sync meldet `403 Rate-Limit` | Ohne Token ist das Limit sehr niedrig — Token hinterlegen |
|
||||||
|
| Tokens plötzlich ungültig | `APP_SECRET` wurde geändert — Tokens neu eintragen |
|
||||||
|
| Port 3000 belegt | `APP_PORT` in der `.env` ändern (Docker) bzw. `npm run dev -- -p 3001` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Lizenz
|
||||||
|
|
||||||
|
MIT — siehe [LICENSE](LICENSE).
|
||||||
Reference in New Issue
Block a user