# 🗂️ Gitea Projekt-Dashboard

> [!WARNING]
> **⏸️ Projekt pausiert**
>
> Dieses Projekt ist aktuell pausiert. Ich entwickle eine eigene Lösung weiter, die Beego ersetzen soll.
> Sobald mein eigenes Web-Framework weit genug ist, wird dieses Projekt damit neu aufgesetzt.
>
> 👉 **Eigene Lösung in Entwicklung:** [go-webframework](https://gitea.starfour.de/Jannis/go-webframework)


Ein selbst gehostetes Dashboard zur zentralen Verwaltung aller persönlichen Projekte – technische wie nicht-technische. Projekte können mit einer Gitea-Repository verknüpft sein, müssen es aber nicht.

---

## 🏷️ Funktionsprinzip: Tag-basierte Projektanzeige

Jedes Repository, das auf dieser Gitea-Instanz mit dem Topic-Tag `dashboard` versehen ist, wird automatisch im Dashboard angezeigt.

### So funktioniert es:

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

> **Beispiel:** Repo `mein-projekt` bekommt das Topic `dashboard` → erscheint sofort im Dashboard mit Issues, letztem Commit, Status und Beschreibung.

---

## 🧱 Architektur

```
┌─────────────────┐     Gitea REST API v1      ┌──────────────────────┐
│   Gitea Server  │ ◄────────────────────────► │   Backend Service    │
│ (Repos + Topics)│                            │   (Go, net/http)     │
└─────────────────┘                            └──────────┬───────────┘
                                                          │
                                               ┌──────────▼───────────┐
                                               │   PostgreSQL DB      │
                                               │ (Repos, Issues,      │
                                               │  Milestones, Cache)  │
                                               └──────────┬───────────┘
                                                          │
                                               ┌──────────▼───────────┐
                                               │   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

**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

---

## ⚙️ Backend: **Go (net/http + pgx)**

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

**Externe Dependencies (minimal):**
- `pgx` – PostgreSQL-Treiber (direktes SQL, kein ORM)
- `godotenv` – `.env`-Datei laden
- `golang.org/x/oauth2` – OAuth2-Flow für Gitea-Login

**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)

**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)

log.Fatal(http.ListenAndServe(":8080", mux))
```

---

## 🔐 Auth: **Gitea OAuth2**

Gitea kann selbst als OAuth2-Provider fungieren – Nutzer loggen sich mit ihrem Gitea-Account im Dashboard ein, genau wie "Login with GitHub".

### 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

### Flow:

```
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
```

**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

---

## 🗄️ Datenbank: **PostgreSQL**

**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()
);

-- 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
);

-- Webhook-Event-Log
CREATE TABLE webhook_events (
  id           SERIAL PRIMARY KEY,
  event_type   VARCHAR(50),
  payload      JSONB,
  received_at  TIMESTAMPTZ DEFAULT NOW()
);
```

---

## 🚀 Roadmap

- [ ] **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

---

## 🔧 Tech Stack

| 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                 |

---

## 📦 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, GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, DATABASE_URL, DASHBOARD_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)*