From cee54df54fa721c0bbdc83d0afe2c2ec926c3879 Mon Sep 17 00:00:00 2001 From: Jannis Date: Wed, 6 May 2026 09:39:17 +0000 Subject: [PATCH 1/4] =?UTF-8?q?README:=20Projekt=20pausiert=20=E2=80=93=20?= =?UTF-8?q?eigene=20L=C3=B6sung=20in=20Entwicklung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 0ba4b28..af89da2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,14 @@ # πŸ—‚οΈ 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-notes](https://gitea.starfour.de/Jannis/go-webframework-notes) + + 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. --- -- 2.49.1 From e7e568a0aa916441280f3917d43f22724e033790 Mon Sep 17 00:00:00 2001 From: Jannis Date: Wed, 6 May 2026 09:41:32 +0000 Subject: [PATCH 2/4] put right repo in put right repo in the link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af89da2..dca674b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > 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-notes](https://gitea.starfour.de/Jannis/go-webframework-notes) +> πŸ‘‰ **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. -- 2.49.1 From cb2700066aa2f614c5b25ec6a085e56a5009bdec Mon Sep 17 00:00:00 2001 From: Jannis Date: Wed, 13 May 2026 08:11:47 +0000 Subject: [PATCH 3/4] Update README.md --- README.md | 318 ++++++++++++++++++++++++++---------------------------- 1 file changed, 150 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index dca674b..c2a3323 100644 --- a/README.md +++ b/README.md @@ -1,218 +1,200 @@ -# πŸ—‚οΈ Gitea Projekt-Dashboard +# πŸ—‚οΈ Gitea Project Dashboard > [!WARNING] -> **⏸️ Projekt pausiert** +> **⏸️ Project paused** > -> 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. +> This project is currently paused. I am continuing to develop my own solution to replace Beego. Once my own web framework is far enough along, this project will be rebuilt with it. > -> πŸ‘‰ **Eigene LΓΆsung in Entwicklung:** [go-webframework](https://gitea.starfour.de/Jannis/go-webframework) +> πŸ‘‰ **Own solution in development:** [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. +A self-hosted dashboard for centrally managing all personal projects – technical and non-technical alike. Projects can be linked to a Gitea repository, but don't have to be. --- -## 🏷️ Funktionsprinzip: Tag-basierte Projektanzeige +## 🏷️ How It Works: Tag-Based Project Display -Jedes Repository, das auf dieser Gitea-Instanz mit dem Topic-Tag `dashboard` versehen ist, wird automatisch im Dashboard angezeigt. +Every repository on this Gitea instance that has the topic tag `dashboard` is automatically shown in the dashboard. -### So funktioniert es: +### How it works: +1. In a Gitea repository, go to **Settings β†’ Topics** and add the tag `dashboard` +2. The backend service polls the Gitea API regularly (or via webhook) for all repos with this tag +3. The found repos are stored and cached in the PostgreSQL database +4. The frontend displays all tagged repos as project cards with live data -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. +> **Example:** Repo `my-project` gets the topic `dashboard` β†’ immediately appears in the dashboard with issues, last commit, status, and description. --- -## 🧱 Architektur - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” Gitea REST API v1 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Gitea Server β”‚ ◄────────────────────────► β”‚ Backend Service β”‚ -β”‚ (Repos + Topics)β”‚ β”‚ (Go, net/http) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ PostgreSQL DB β”‚ - β”‚ (Repos, Issues, β”‚ - β”‚ Milestones, Cache) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Frontend β”‚ - β”‚ (SvelteKit) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +## 🧱 Architecture ``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” Gitea REST API v1 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Gitea Server β”‚ ◄────────────────────► β”‚ Backend Service β”‚ +β”‚ (Repos + Topics)β”‚ β”‚ (Go, net/http) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ PostgreSQL DB β”‚ + β”‚ (Repos, Issues, β”‚ + β”‚ Milestones, Cache) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Frontend β”‚ + β”‚ (SvelteKit) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ``` ---- + ## πŸ–₯️ Frontend: SvelteKit -## πŸ–₯️ Frontend: **SvelteKit** + **Why 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 + - Lightweight and fast – ideal for an internal dashboard + - Server-Side Rendering (SSR) out of the box – no flickering on load + - Simple reactivity without overhead + - Perfect for data-driven dashboards with real-time updates via SSE or 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 + **Frontend features:** ---- + - Project cards with repo name, description, last commit, open issues + - Filter function by topics, language, activity + - Detail view: edit issues & milestones directly in the dashboard (bi-directional) + - Live updates via webhook events (Server-Sent Events) + - Dark mode, responsive design -## βš™οΈ Backend: **Go (net/http + pgx)** + ## βš™οΈ 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. + Go is an excellent backend language – the standard library is so complete that no web framework is needed. `net/http` provides everything required: routing, handlers, middleware. The result is a dependency-light, readable codebase. -**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 + **Why no framework?** -**Externe Dependencies (minimal):** -- `pgx` – PostgreSQL-Treiber (direktes SQL, kein ORM) -- `godotenv` – `.env`-Datei laden -- `golang.org/x/oauth2` – OAuth2-Flow fΓΌr Gitea-Login + - `net/http` from the standard library is fully sufficient for ~6 endpoints + - No framework overhead, no breaking changes from external dependencies + - The Go-typical approach: explicit, simple, readable + - Compiles to a single static binary – minimal Docker footprint -**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) + **External dependencies (minimal):** -**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) + - `pgx` – PostgreSQL driver (direct SQL, no ORM) + - `godotenv` – load `.env` file + - `golang.org/x/oauth2` – OAuth2 flow for Gitea login -log.Fatal(http.ListenAndServe(":8080", mux)) -``` + **Backend tasks:** ---- + - `GET /api/projects` – return all tagged repos from the DB + - `POST /api/webhook` – Gitea webhook listener for push, issue, tag events + - `GET /api/projects/{id}/issues` – fetch issues for a repo live from Gitea + - Background goroutine: query Gitea API every 5 minutes for repos with tag `dashboard` + - Cache repo data in PostgreSQL (incl. topics, last activity, issue count) -## πŸ” Auth: **Gitea OAuth2** + **Example – HTTP server without a framework:** -Gitea kann selbst als OAuth2-Provider fungieren – Nutzer loggen sich mit ihrem Gitea-Account im Dashboard ein, genau wie "Login with GitHub". + ```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) -### Setup in Gitea: + log.Fatal(http.ListenAndServe(":8080", mux)) + ``` -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 can act as its own OAuth2 provider – users log into the dashboard with their Gitea account, just like "Login with GitHub". -``` -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 -``` + **Setup in Gitea:** + 1. In Gitea under **Settings β†’ Applications β†’ OAuth2 Applications**, register a new app + 2. Enter Client ID and Client Secret in the `.env` file + 3. Set the Redirect URI to `https://dashboard.example.com/auth/callback` -**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 + **Flow:** + - User clicks "Login with Gitea" + - β†’ Redirect to Gitea instance (Authorization Endpoint) + - β†’ User confirms access + - β†’ Gitea redirects back with Authorization Code + - β†’ Backend exchanges code for Access Token + - β†’ User is logged in, Gitea identity is known ---- + **Advantages:** -## πŸ—„οΈ Datenbank: **PostgreSQL** + - No custom auth system needed – Gitea handles passwords and sessions + - User identity directly available β†’ repos and issues can be filtered per user + - Write permissions (create/close issues) only for the respective repo owner + - Implemented with `golang.org/x/oauth2` – official Go package, no third-party lib needed -**Schema-Übersicht:** + ## πŸ—„οΈ Database: PostgreSQL -```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() -); + **Schema overview:** --- 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 -); + ```sql + -- Cached repo information + 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[], -- e.g. ["dashboard", "freelancer"] + language VARCHAR(100), + open_issues INTEGER DEFAULT 0, + last_push TIMESTAMPTZ, + is_private BOOLEAN DEFAULT false, + synced_at TIMESTAMPTZ DEFAULT NOW() + ); --- Webhook-Event-Log -CREATE TABLE webhook_events ( - id SERIAL PRIMARY KEY, - event_type VARCHAR(50), - payload JSONB, - received_at TIMESTAMPTZ DEFAULT NOW() -); -``` + -- Managed issues / tasks + 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 + ## πŸš€ Roadmap + - v0.1 – Repo listing via tag `dashboard`, polling every 5 min + - v0.2 – Webhook listener for real-time updates + - v0.3 – Display issues & milestones in the dashboard + - v0.4 – Create/close issues directly from the dashboard (bi-directional) + - v0.5 – Gitea OAuth2 login + - v0.6 – Integration with freelancer dashboard (repos = projects) + - v1.0 – Multi-user, public project pages -- [ ] **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 ---- + | Layer | Technology | + |----------|-------------------------------------| + | Frontend | SvelteKit + TailwindCSS | + | Backend | Go + net/http (standard lib) | + | Database | PostgreSQL + pgx | + | Auth | Gitea OAuth2 + golang.org/x/oauth2 | + | API | Gitea REST API v1 | + | Deploy | Docker Compose | -## πŸ”§ Tech Stack + ## πŸ“¦ Getting Started -| 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 | + ```bash + # Clone the repo + git clone https://gitea.starfour.de/Jannis/gitea-projekt-dashboard ---- + # Set environment variables + cp .env.example .env + # Fill in GITEA_URL, GITEA_TOKEN, GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, DATABASE_URL, DASHBOARD_TAG -## πŸ“¦ Getting Started + # Start with Docker + docker compose up -d + ``` -```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)* \ No newline at end of file + This project is part of the personal project ideas collection. Related overview repo: [projekt-ideen](https://gitea.starfour.de/Jannis/projekt-ideen) \ No newline at end of file -- 2.49.1 From 8b5cee8a6f55afd67f7ff8a5128e7cb9c74394e7 Mon Sep 17 00:00:00 2001 From: Jannis Date: Wed, 13 May 2026 08:36:54 +0000 Subject: [PATCH 4/4] Update README.md --- README.md | 273 +++++++++++++++++++++++++++--------------------------- 1 file changed, 137 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index c2a3323..571cc4c 100644 --- a/README.md +++ b/README.md @@ -26,175 +26,176 @@ Every repository on this Gitea instance that has the topic tag `dashboard` is au --- ## 🧱 Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” 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)β”‚ β”‚ (Go, net/http) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ PostgreSQL DB β”‚ - β”‚ (Repos, Issues, β”‚ - β”‚ Milestones, Cache) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Frontend β”‚ - β”‚ (SvelteKit) β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - ``` - ## πŸ–₯️ Frontend: SvelteKit +## πŸ–₯️ Frontend: SvelteKit - **Why SvelteKit?** +**Why SvelteKit?** - - Lightweight and fast – ideal for an internal dashboard - - Server-Side Rendering (SSR) out of the box – no flickering on load - - Simple reactivity without overhead - - Perfect for data-driven dashboards with real-time updates via SSE or WebSocket +- Lightweight and fast – ideal for an internal dashboard +- Server-Side Rendering (SSR) out of the box – no flickering on load +- Simple reactivity without overhead +- Perfect for data-driven dashboards with real-time updates via SSE or WebSocket - **Frontend features:** +**Frontend features:** - - Project cards with repo name, description, last commit, open issues - - Filter function by topics, language, activity - - Detail view: edit issues & milestones directly in the dashboard (bi-directional) - - Live updates via webhook events (Server-Sent Events) - - Dark mode, responsive design +- Project cards with repo name, description, last commit, open issues +- Filter function by topics, language, activity +- Detail view: edit issues & milestones directly in the dashboard (bi-directional) +- Live updates via webhook events (Server-Sent Events) +- Dark mode, responsive design - ## βš™οΈ Backend: Go (net/http + pgx) +## βš™οΈ Backend: Go (net/http + pgx) - Go is an excellent backend language – the standard library is so complete that no web framework is needed. `net/http` provides everything required: routing, handlers, middleware. The result is a dependency-light, readable codebase. +Go is an excellent backend language – the standard library is so complete that no web framework is needed. `net/http` provides everything required: routing, handlers, middleware. The result is a dependency-light, readable codebase. - **Why no framework?** +**Why no framework?** - - `net/http` from the standard library is fully sufficient for ~6 endpoints - - No framework overhead, no breaking changes from external dependencies - - The Go-typical approach: explicit, simple, readable - - Compiles to a single static binary – minimal Docker footprint +- `net/http` from the standard library is fully sufficient for ~6 endpoints +- No framework overhead, no breaking changes from external dependencies +- The Go-typical approach: explicit, simple, readable +- Compiles to a single static binary – minimal Docker footprint - **External dependencies (minimal):** +**External dependencies (minimal):** - - `pgx` – PostgreSQL driver (direct SQL, no ORM) - - `godotenv` – load `.env` file - - `golang.org/x/oauth2` – OAuth2 flow for Gitea login +- `pgx` – PostgreSQL driver (direct SQL, no ORM) +- `godotenv` – load `.env` file +- `golang.org/x/oauth2` – OAuth2 flow for Gitea login - **Backend tasks:** +**Backend tasks:** - - `GET /api/projects` – return all tagged repos from the DB - - `POST /api/webhook` – Gitea webhook listener for push, issue, tag events - - `GET /api/projects/{id}/issues` – fetch issues for a repo live from Gitea - - Background goroutine: query Gitea API every 5 minutes for repos with tag `dashboard` - - Cache repo data in PostgreSQL (incl. topics, last activity, issue count) +- `GET /api/projects` – return all tagged repos from the DB +- `POST /api/webhook` – Gitea webhook listener for push, issue, tag events +- `GET /api/projects/{id}/issues` – fetch issues for a repo live from Gitea +- Background goroutine: query Gitea API every 5 minutes for repos with tag `dashboard` +- Cache repo data in PostgreSQL (incl. topics, last activity, issue count) - **Example – HTTP server without a framework:** +**Example – HTTP server without a 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) +```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)) - ``` +log.Fatal(http.ListenAndServe(":8080", mux)) +``` - ## πŸ” Auth: Gitea OAuth2 +## πŸ” Auth: Gitea OAuth2 - Gitea can act as its own OAuth2 provider – users log into the dashboard with their Gitea account, just like "Login with GitHub". +Gitea can act as its own OAuth2 provider – users log into the dashboard with their Gitea account, just like "Login with GitHub". - **Setup in Gitea:** - 1. In Gitea under **Settings β†’ Applications β†’ OAuth2 Applications**, register a new app - 2. Enter Client ID and Client Secret in the `.env` file - 3. Set the Redirect URI to `https://dashboard.example.com/auth/callback` +**Setup in Gitea:** +1. In Gitea under **Settings β†’ Applications β†’ OAuth2 Applications**, register a new app +2. Enter Client ID and Client Secret in the `.env` file +3. Set the Redirect URI to `https://dashboard.example.com/auth/callback` - **Flow:** - - User clicks "Login with Gitea" - - β†’ Redirect to Gitea instance (Authorization Endpoint) - - β†’ User confirms access - - β†’ Gitea redirects back with Authorization Code - - β†’ Backend exchanges code for Access Token - - β†’ User is logged in, Gitea identity is known +**Flow:** +- User clicks "Login with Gitea" +- β†’ Redirect to Gitea instance (Authorization Endpoint) +- β†’ User confirms access +- β†’ Gitea redirects back with Authorization Code +- β†’ Backend exchanges code for Access Token +- β†’ User is logged in, Gitea identity is known - **Advantages:** +**Advantages:** - - No custom auth system needed – Gitea handles passwords and sessions - - User identity directly available β†’ repos and issues can be filtered per user - - Write permissions (create/close issues) only for the respective repo owner - - Implemented with `golang.org/x/oauth2` – official Go package, no third-party lib needed +- No custom auth system needed – Gitea handles passwords and sessions +- User identity directly available β†’ repos and issues can be filtered per user +- Write permissions (create/close issues) only for the respective repo owner +- Implemented with `golang.org/x/oauth2` – official Go package, no third-party lib needed - ## πŸ—„οΈ Database: PostgreSQL +## πŸ—„οΈ Database: PostgreSQL - **Schema overview:** +**Schema overview:** - ```sql - -- Cached repo information - 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[], -- e.g. ["dashboard", "freelancer"] - language VARCHAR(100), - open_issues INTEGER DEFAULT 0, - last_push TIMESTAMPTZ, - is_private BOOLEAN DEFAULT false, - synced_at TIMESTAMPTZ DEFAULT NOW() - ); +```sql +-- Cached repo information +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[], -- e.g. ["dashboard", "freelancer"] + language VARCHAR(100), + open_issues INTEGER DEFAULT 0, + last_push TIMESTAMPTZ, + is_private BOOLEAN DEFAULT false, + synced_at TIMESTAMPTZ DEFAULT NOW() +); - -- Managed issues / tasks - 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 - ); +-- Managed issues / tasks +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() - ); - ``` +-- 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 every 5 min - - v0.2 – Webhook listener for real-time updates - - v0.3 – Display issues & milestones in the dashboard - - v0.4 – Create/close issues directly from the dashboard (bi-directional) - - v0.5 – Gitea OAuth2 login - - v0.6 – Integration with freelancer dashboard (repos = projects) - - v1.0 – Multi-user, public project pages +## πŸš€ Roadmap +- v0.1 – Repo listing via tag `dashboard`, polling every 5 min +- v0.2 – Webhook listener for real-time updates +- v0.3 – Display issues & milestones in the dashboard +- v0.4 – Create/close issues directly from the dashboard (bi-directional) +- v0.5 – Gitea OAuth2 login +- v0.6 – Integration with freelancer dashboard (repos = projects) +- v1.0 – Multi-user, public project pages - ## πŸ”§ Tech Stack +## πŸ”§ Tech Stack - | Layer | Technology | - |----------|-------------------------------------| - | Frontend | SvelteKit + TailwindCSS | - | Backend | Go + net/http (standard lib) | - | Database | PostgreSQL + pgx | - | Auth | Gitea OAuth2 + golang.org/x/oauth2 | - | API | Gitea REST API v1 | - | Deploy | Docker Compose | +| Layer | Technology | +|----------|-------------------------------------| +| Frontend | SvelteKit + TailwindCSS | +| Backend | Go + net/http (standard lib) | +| Database | PostgreSQL + pgx | +| Auth | Gitea OAuth2 + golang.org/x/oauth2 | +| API | Gitea REST API v1 | +| Deploy | Docker Compose | - ## πŸ“¦ Getting Started +## πŸ“¦ Getting Started - ```bash - # Clone the repo - git clone https://gitea.starfour.de/Jannis/gitea-projekt-dashboard +```bash +# Clone the repo +git clone https://gitea.starfour.de/Jannis/gitea-projekt-dashboard - # Set environment variables - cp .env.example .env - # Fill in GITEA_URL, GITEA_TOKEN, GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, DATABASE_URL, DASHBOARD_TAG +# Set environment variables +cp .env.example .env +# Fill in GITEA_URL, GITEA_TOKEN, GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, DATABASE_URL, DASHBOARD_TAG - # Start with Docker - docker compose up -d - ``` +# Start with Docker +docker compose up -d +``` - This project is part of the personal project ideas collection. Related overview repo: [projekt-ideen](https://gitea.starfour.de/Jannis/projekt-ideen) \ No newline at end of file +This project is part of the personal project ideas collection. Related overview repo: [projekt-ideen](https://gitea.starfour.de/Jannis/projekt-ideen) \ No newline at end of file -- 2.49.1