docs: README komplett überarbeitet – allgemeiner Projektmanager statt Gitea-Web-UI
This commit is contained in:
322
README.md
322
README.md
@@ -1,209 +1,219 @@
|
||||
# 🗂️ Gitea Projekt-Dashboard
|
||||
# 🗂️ Projekt-Dashboard
|
||||
|
||||
Ein selbst gehostetes Dashboard, das automatisch alle Gitea-Repositories anzeigt, die mit einem bestimmten **Topic-Tag** versehen sind.
|
||||
Ein selbst gehostetes Dashboard zur zentralen Verwaltung aller persönlichen Projekte – technische wie nicht-technische.
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ Funktionsprinzip: Tag-basierte Projektanzeige
|
||||
## 💡 Was ist ein Projekt?
|
||||
|
||||
Jedes Repository, das auf dieser Gitea-Instanz mit dem Topic-Tag `dashboard` versehen ist, wird automatisch im Dashboard angezeigt.
|
||||
Ein Projekt ist **alles, woran aktiv gearbeitet wird oder wurde** – unabhängig davon, ob es einen Code-Repository hat oder nicht.
|
||||
|
||||
### So funktioniert es:
|
||||
Beispiele:
|
||||
|
||||
1. Du setzt in einem Gitea-Repository unter **Settings → Topics** das Tag `dashboard`
|
||||
2. Der Backend-Service pollt regelmäßig (oder per Webhook) die Gitea API nach allen Repos mit diesem Tag
|
||||
3. Die gefundenen Repos werden in der PostgreSQL-Datenbank gespeichert und gecacht
|
||||
4. Das Frontend zeigt alle getaggten Repos als Projektkarten mit Live-Daten an
|
||||
- 🖥️ **Softwareprojekt** – eine selbst gehostete App, ein CLI-Tool, ein Backend-Service
|
||||
- 🔧 **Hardware-Projekt** – Aufbau eines zweiten PCs, Einrichten eines Homelab-Servers
|
||||
- 🏗️ **Infrastruktur** – Umstrukturierung des Heimnetzwerks, Migration zu Docker Compose
|
||||
- 📋 **Organisatorisches** – Dokumentation aufräumen, Backupstrategie planen
|
||||
- 🌱 **Persönliches** – Lernprojekte, Kurse, Ziele ohne technischen Bezug
|
||||
|
||||
> **Beispiel:** Repo `mein-projekt` bekommt das Topic `dashboard` → erscheint sofort im Dashboard mit Issues, letztem Commit, Status und Beschreibung.
|
||||
Ein Projekt **kann** mit einer Gitea-Repository verknüpft sein, **muss es aber nicht**.
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ Repo-Verknüpfung (optional)
|
||||
|
||||
Wenn ein Projekt eine zugehörige Gitea-Repository hat, kann diese durch das Topic-Tag `projekt` markiert werden. Das Dashboard erkennt diese Repos automatisch und zeigt zugehörige Metadaten an (letzter Commit, offene Issues, Sprache etc.).
|
||||
|
||||
Repos **ohne** das Tag `projekt` erscheinen nicht im Dashboard – sie sind keine verwalteten Projekte.
|
||||
|
||||
Projekte **ohne** Repository existieren nur in der Datenbank des Dashboards und werden manuell angelegt.
|
||||
|
||||
---
|
||||
|
||||
## 🧱 Architektur
|
||||
|
||||
```
|
||||
┌─────────────────┐ Gitea REST API v1 ┌──────────────────────┐
|
||||
│ Gitea Server │ ◄────────────────────────► │ Backend Service │
|
||||
│ (Repos + Topics)│ │ (Go, net/http) │
|
||||
└─────────────────┘ └──────────┬───────────┘
|
||||
│
|
||||
┌──────────▼───────────┐
|
||||
│ PostgreSQL DB │
|
||||
│ (Repos, Issues, │
|
||||
│ Milestones, Cache) │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
┌──────────▼───────────┐
|
||||
│ Frontend │
|
||||
│ (SvelteKit) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
┌─────────────────────┐ Gitea REST API v1 ┌──────────────────────┐
|
||||
│ Gitea Server │ ◄─────────────────────────────► │ Backend Service │
|
||||
│ (Repos + Topics) │ (nur wenn Repo verknüpft) │ (Go, net/http) │
|
||||
└─────────────────────┘ └──────────┬───────────┘
|
||||
│
|
||||
┌──────────▼───────────┐
|
||||
│ PostgreSQL DB │
|
||||
│ (Projekte, Tasks, │
|
||||
│ Milestones, Notizen) │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
┌──────────▼───────────┐
|
||||
│ Frontend │
|
||||
│ (SvelteKit) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
## 🖥️ Frontend: **SvelteKit**
|
||||
## 🖥️ Frontend: SvelteKit
|
||||
|
||||
**Warum SvelteKit?**
|
||||
- Leichtgewichtig und schnell – ideal für ein internes Dashboard
|
||||
- Server-Side Rendering (SSR) out of the box – kein Flackern beim Laden
|
||||
- Einfache Reaktivität ohne Overhead
|
||||
- Perfekt für datengetriebene Dashboards mit Echtzeit-Updates via SSE oder WebSocket
|
||||
Warum SvelteKit?
|
||||
|
||||
**Features im Frontend:**
|
||||
- Projektkarten mit Repo-Name, Beschreibung, letztem Commit, offenen Issues
|
||||
- Filterfunktion nach Topics, Sprache, Aktivität
|
||||
- Detailansicht: Issues & Milestones direkt im Dashboard bearbeiten (bi-direktional)
|
||||
- Live-Updates via Webhook-Events (Server-Sent Events)
|
||||
- Dark Mode, responsive Design
|
||||
- Leichtgewichtig und schnell – ideal für ein internes Dashboard
|
||||
- Server-Side Rendering (SSR) out of the box – kein Flackern beim Laden
|
||||
- Einfache Reaktivität ohne Overhead
|
||||
- Perfekt für datengetriebene Übersichten mit Echtzeit-Updates
|
||||
|
||||
---
|
||||
Features im Frontend:
|
||||
|
||||
## ⚙️ Backend: **Go (net/http + pgx)**
|
||||
- Projektkarten mit Name, Beschreibung, Status und offenen Tasks
|
||||
- Unterscheidung zwischen repo-gebundenen und freien Projekten
|
||||
- Filterfunktion nach Kategorie, Status, Aktivität
|
||||
- Detailansicht: Tasks, Milestones, Notizen pro Projekt
|
||||
- Live-Updates via Server-Sent Events (bei repo-gebundenen Projekten)
|
||||
- Dark Mode, responsive Design
|
||||
|
||||
Go eignet sich hervorragend als Backend-Sprache – die Standardbibliothek ist so vollständig, dass kein Web-Framework nötig ist. `net/http` liefert alles was gebraucht wird: Routing, Handler, Middleware. Das Ergebnis ist eine dependency-arme, gut lesbare Codebasis.
|
||||
---
|
||||
|
||||
**Warum kein Framework?**
|
||||
- `net/http` aus der Standardbibliothek reicht für ~6 Endpoints vollständig aus
|
||||
- Kein Framework-Overhead, keine Breaking Changes durch externe Dependencies
|
||||
- Go-typischer Ansatz: explizit, simpel, lesbar
|
||||
- Kompiliert zu einer einzigen statischen Binary – minimaler Docker-Footprint
|
||||
## ⚙️ Backend: Go (net/http + pgx)
|
||||
|
||||
**Externe Dependencies (minimal):**
|
||||
- `pgx` – PostgreSQL-Treiber (direktes SQL, kein ORM)
|
||||
- `godotenv` – `.env`-Datei laden
|
||||
- `golang.org/x/oauth2` – OAuth2-Flow für Gitea-Login
|
||||
Go eignet sich hervorragend als Backend-Sprache – die Standardbibliothek ist so vollständig, dass kein Web-Framework nötig ist. `net/http` liefert alles was gebraucht wird: Routing, Handler, Middleware.
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- `GET /api/projects` – alle getaggten Repos aus der DB zurückgeben
|
||||
- `POST /api/webhook` – Gitea Webhook-Listener für Push, Issue, Tag-Events
|
||||
- `GET /api/projects/{id}/issues` – Issues eines Repos live aus Gitea holen
|
||||
- Hintergrund-Goroutine: alle 5 Minuten Gitea API nach Repos mit Tag `dashboard` abfragen
|
||||
- Repo-Daten in PostgreSQL cachen (inkl. Topics, letzter Aktivität, Issue-Count)
|
||||
**Warum kein Framework?**
|
||||
|
||||
**Beispiel – HTTP-Server ohne Framework:**
|
||||
```go
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("GET /api/projects", h.listProjects)
|
||||
mux.HandleFunc("POST /api/webhook", h.handleWebhook)
|
||||
mux.HandleFunc("GET /api/projects/{id}/issues", h.listIssues)
|
||||
- `net/http` aus der Standardbibliothek reicht für die benötigten Endpoints vollständig aus
|
||||
- Kein Framework-Overhead, keine Breaking Changes durch externe Dependencies
|
||||
- Go-typischer Ansatz: explizit, simpel, lesbar
|
||||
- Kompiliert zu einer einzigen statischen Binary – minimaler Docker-Footprint
|
||||
|
||||
log.Fatal(http.ListenAndServe(":8080", mux))
|
||||
```
|
||||
**Externe Dependencies (minimal):**
|
||||
|
||||
---
|
||||
- `pgx` – PostgreSQL-Treiber (direktes SQL, kein ORM)
|
||||
- `godotenv` – `.env`-Datei laden
|
||||
- `golang.org/x/oauth2` – OAuth2-Flow für Gitea-Login (optional)
|
||||
|
||||
## 🔐 Auth: **Gitea OAuth2**
|
||||
**Backend-Aufgaben:**
|
||||
|
||||
Gitea kann selbst als OAuth2-Provider fungieren – Nutzer loggen sich mit ihrem Gitea-Account im Dashboard ein, genau wie "Login with GitHub".
|
||||
- `GET /api/projects` – alle Projekte aus der DB zurückgeben
|
||||
- `POST /api/projects` – neues Projekt anlegen (mit oder ohne Repo-Verknüpfung)
|
||||
- `GET /api/projects/{id}/tasks` – Tasks eines Projekts abrufen
|
||||
- `POST /api/webhook` – Gitea Webhook-Listener für repo-gebundene Projekte
|
||||
- Hintergrund-Goroutine: Gitea API nach Repos mit Tag `projekt` abfragen und DB synchronisieren
|
||||
|
||||
### Setup in Gitea:
|
||||
---
|
||||
|
||||
1. In Gitea unter **Settings → Applications → OAuth2 Applications** eine neue App registrieren
|
||||
2. `Client ID` und `Client Secret` in die `.env` eintragen
|
||||
3. Redirect URI auf `https://dashboard.example.com/auth/callback` setzen
|
||||
## 🔐 Auth: Gitea OAuth2
|
||||
|
||||
### Flow:
|
||||
Gitea fungiert als OAuth2-Provider – Nutzer loggen sich mit ihrem Gitea-Account im Dashboard ein.
|
||||
|
||||
```
|
||||
Nutzer klickt "Login mit Gitea"
|
||||
→ Weiterleitung zur Gitea-Instanz (Authorization Endpoint)
|
||||
→ Nutzer bestätigt Zugriff
|
||||
→ Gitea leitet mit Authorization Code zurück
|
||||
→ Backend tauscht Code gegen Access Token
|
||||
→ Nutzer ist eingeloggt, Gitea-Identität bekannt
|
||||
```
|
||||
**Flow:**
|
||||
|
||||
**Vorteile:**
|
||||
- Kein eigenes Auth-System nötig – Gitea übernimmt Passwörter und Sessions
|
||||
- Nutzeridentität direkt bekannt → Repos und Issues können nutzerbasiert gefiltert werden
|
||||
- Schreibrechte (Issues erstellen/schließen) nur für den jeweiligen Repo-Owner
|
||||
- Implementiert mit `golang.org/x/oauth2` – offizielles Go-Paket, keine Drittanbieter-Lib nötig
|
||||
Nutzer klickt "Login mit Gitea" → Weiterleitung zur Gitea-Instanz → Nutzer bestätigt Zugriff → Gitea leitet mit Authorization Code zurück → Backend tauscht Code gegen Access Token → Nutzer ist eingeloggt
|
||||
|
||||
---
|
||||
**Vorteile:**
|
||||
|
||||
## 🗄️ Datenbank: **PostgreSQL**
|
||||
- Kein eigenes Auth-System nötig
|
||||
- Nutzeridentität direkt bekannt
|
||||
- Implementiert mit `golang.org/x/oauth2`
|
||||
|
||||
**Schema-Übersicht:**
|
||||
---
|
||||
|
||||
```sql
|
||||
-- Gecachte Repo-Informationen
|
||||
CREATE TABLE projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
gitea_id INTEGER UNIQUE NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
full_name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
html_url TEXT,
|
||||
topics TEXT[], -- z.B. ["dashboard", "freelancer"]
|
||||
language VARCHAR(100),
|
||||
open_issues INTEGER DEFAULT 0,
|
||||
last_push TIMESTAMPTZ,
|
||||
is_private BOOLEAN DEFAULT false,
|
||||
synced_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
## 🗄️ Datenbank: PostgreSQL
|
||||
|
||||
-- Gemanagte Issues / Aufgaben
|
||||
CREATE TABLE issues (
|
||||
id SERIAL PRIMARY KEY,
|
||||
gitea_id INTEGER NOT NULL,
|
||||
project_id INTEGER REFERENCES projects(id),
|
||||
title TEXT NOT NULL,
|
||||
state VARCHAR(20), -- open / closed
|
||||
assignee VARCHAR(100),
|
||||
milestone TEXT,
|
||||
updated_at TIMESTAMPTZ
|
||||
);
|
||||
**Schema-Übersicht:**
|
||||
|
||||
-- Webhook-Event-Log
|
||||
CREATE TABLE webhook_events (
|
||||
id SERIAL PRIMARY KEY,
|
||||
event_type VARCHAR(50),
|
||||
payload JSONB,
|
||||
received_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
```sql
|
||||
-- Alle Projekte (mit oder ohne Repo-Verknüpfung)
|
||||
CREATE TABLE projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
status VARCHAR(50) DEFAULT 'active', -- active / paused / done
|
||||
category VARCHAR(100), -- z.B. "software", "hardware", "infra", "personal"
|
||||
gitea_repo TEXT, -- optional: voller Repo-Name (z.B. "Jannis/mein-projekt")
|
||||
gitea_id INTEGER, -- optional: Gitea-interne Repo-ID
|
||||
html_url TEXT, -- optional: Link zur Repo
|
||||
language VARCHAR(100), -- optional: Hauptsprache der Repo
|
||||
open_tasks INTEGER DEFAULT 0,
|
||||
last_activity TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
synced_at TIMESTAMPTZ -- NULL wenn kein Gitea-Sync
|
||||
);
|
||||
|
||||
---
|
||||
-- Tasks / Aufgaben pro Projekt
|
||||
CREATE TABLE tasks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
project_id INTEGER REFERENCES projects(id),
|
||||
gitea_issue_id INTEGER, -- optional: verknüpftes Gitea-Issue
|
||||
title TEXT NOT NULL,
|
||||
body TEXT,
|
||||
state VARCHAR(20) DEFAULT 'open', -- open / closed
|
||||
priority VARCHAR(20), -- low / medium / high
|
||||
milestone TEXT,
|
||||
assignee VARCHAR(100),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
## 🚀 Roadmap
|
||||
-- Milestones pro Projekt
|
||||
CREATE TABLE milestones (
|
||||
id SERIAL PRIMARY KEY,
|
||||
project_id INTEGER REFERENCES projects(id),
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
due_date TIMESTAMPTZ,
|
||||
closed BOOLEAN DEFAULT false
|
||||
);
|
||||
|
||||
- [ ] **v0.1** – Repo-Listing via Tag `dashboard`, Polling alle 5 min
|
||||
- [ ] **v0.2** – Webhook-Listener für Echtzeit-Updates
|
||||
- [ ] **v0.3** – Issues & Milestones im Dashboard anzeigen
|
||||
- [ ] **v0.4** – Issues direkt aus dem Dashboard erstellen/schließen (bi-direktional)
|
||||
- [ ] **v0.5** – Gitea OAuth2 Login
|
||||
- [ ] **v0.6** – Verknüpfung mit Freelancer-Dashboard (Repos = Projekte)
|
||||
- [ ] **v1.0** – Multi-User, öffentliche Projektsseiten
|
||||
-- Webhook-Event-Log (nur für repo-gebundene Projekte)
|
||||
CREATE TABLE webhook_events (
|
||||
id SERIAL PRIMARY KEY,
|
||||
event_type VARCHAR(50),
|
||||
project_id INTEGER REFERENCES projects(id),
|
||||
payload JSONB,
|
||||
received_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
## 🔧 Tech Stack
|
||||
## 🚀 Roadmap
|
||||
|
||||
| Schicht | Technologie |
|
||||
|--------------|--------------------------------|
|
||||
| Frontend | SvelteKit + TailwindCSS |
|
||||
| Backend | Go + net/http (Standardlib) |
|
||||
| Datenbank | PostgreSQL + pgx |
|
||||
| Auth | Gitea OAuth2 + golang.org/x/oauth2 |
|
||||
| API | Gitea REST API v1 |
|
||||
| Deployment | Docker Compose |
|
||||
- **v0.1** – Projekt-Listing: manuelle Projekte anlegen, Repos mit Tag `projekt` automatisch einlesen
|
||||
- **v0.2** – Webhook-Listener für Echtzeit-Sync bei repo-gebundenen Projekten
|
||||
- **v0.3** – Tasks & Milestones im Dashboard anzeigen und verwalten
|
||||
- **v0.4** – Tasks direkt aus dem Dashboard erstellen/schließen (bi-direktional mit Gitea)
|
||||
- **v0.5** – Gitea OAuth2 Login
|
||||
- **v0.6** – Kategorien, Filter, Status-Verwaltung für alle Projekttypen
|
||||
- **v1.0** – Multi-User, öffentliche Projektseiten
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
## 📦 Getting Started
|
||||
## 🔧 Tech Stack
|
||||
|
||||
```bash
|
||||
# Repo klonen
|
||||
git clone https://gitea.starfour.de/Jannis/gitea-projekt-dashboard
|
||||
| Schicht | Technologie |
|
||||
|-------------|-------------------------------------|
|
||||
| Frontend | SvelteKit + TailwindCSS |
|
||||
| Backend | Go + net/http (Standardlib) |
|
||||
| Datenbank | PostgreSQL + pgx |
|
||||
| Auth | Gitea OAuth2 + golang.org/x/oauth2 |
|
||||
| API | Gitea REST API v1 (optional) |
|
||||
| Deployment | Docker Compose |
|
||||
|
||||
# Umgebungsvariablen setzen
|
||||
cp .env.example .env
|
||||
# GITEA_URL, GITEA_TOKEN, GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, DATABASE_URL, DASHBOARD_TAG eintragen
|
||||
---
|
||||
|
||||
# Mit Docker starten
|
||||
docker compose up -d
|
||||
```
|
||||
## 📦 Getting Started
|
||||
|
||||
---
|
||||
```bash
|
||||
# Repo klonen
|
||||
git clone https://gitea.starfour.de/Jannis/gitea-projekt-dashboard
|
||||
|
||||
# Umgebungsvariablen setzen
|
||||
cp .env.example .env
|
||||
# GITEA_URL, GITEA_TOKEN, DATABASE_URL, PROJEKT_TAG eintragen
|
||||
|
||||
# Mit Docker starten
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Dieses Projekt ist Teil der persönlichen Projekt-Ideen-Sammlung.
|
||||
Zugehöriges Übersichts-Repo: [projekt-ideen](https://gitea.starfour.de/Jannis/projekt-ideen)
|
||||
|
||||
*Dieses Projekt ist Teil der persönlichen Projekt-Ideen-Sammlung. Zugehöriges Übersichts-Repo: [projekt-ideen](https://gitea.starfour.de/Jannis/projekt-ideen)*
|
||||
Reference in New Issue
Block a user