generated from Dicken/dickendock
181 lines
6.7 KiB
Markdown
181 lines
6.7 KiB
Markdown
# LaunchPad
|
||
|
||
Ein moderner, minimalistischer Homelab-Launcher – inspiriert von Raycast, Spotlight, Arc
|
||
und Linear. Tippe wenige Buchstaben, finde sofort den gewünschten Dienst, drücke Enter.
|
||
|
||
Kein überladenes Dashboard. Keine Kacheln. Im Mittelpunkt steht eine extrem schnelle Suche.
|
||
|
||
## Quickstart (Docker)
|
||
|
||
```bash
|
||
git clone <repo-url> LaunchPad
|
||
cd LaunchPad
|
||
cp .env.example .env # optional anpassen, siehe unten
|
||
docker compose up -d --build
|
||
```
|
||
|
||
- Frontend: http://localhost:8080
|
||
- Backend / Health-API: http://localhost:3001/api/health
|
||
|
||
## Quickstart (lokale Entwicklung)
|
||
|
||
Voraussetzungen: Node.js ≥ 20, pnpm ≥ 9.
|
||
|
||
```bash
|
||
pnpm install
|
||
pnpm dev:backend # startet Fastify auf :3001
|
||
pnpm dev:frontend # startet Vite auf :5173 (proxyt /api zum Backend)
|
||
```
|
||
|
||
## Projektstruktur
|
||
|
||
```
|
||
LaunchPad
|
||
│
|
||
├── apps
|
||
│ ├── frontend React + Vite + TypeScript + TailwindCSS
|
||
│ └── backend Fastify + TypeScript + Drizzle ORM + SQLite
|
||
│
|
||
├── packages
|
||
│ ├── shared gemeinsame Typen (Device, Service) + Such-Ranking-Logik
|
||
│ └── ui gemeinsame UI-Komponenten (SearchInput, StatusBadge)
|
||
│
|
||
├── docker zusätzliche Docker-Hilfsdateien
|
||
├── docs Projektdokumentation
|
||
├── pnpm-workspace.yaml
|
||
├── docker-compose.yml
|
||
└── tsconfig.base.json
|
||
```
|
||
|
||
## Stand dieses Commits
|
||
|
||
Dieser erste Commit liefert ein lauffähiges Grundgerüst:
|
||
|
||
- ✅ pnpm-Monorepo mit `apps/*` und `packages/*`
|
||
- ✅ Fastify-Backend mit `/api/health`-Endpunkt
|
||
- ✅ SQLite-Datenbank (better-sqlite3) inkl. Schema für `devices`, `services`, `categories`
|
||
(Drizzle ORM), automatisch angelegt beim Start
|
||
- ✅ React-Startseite mit Suchfeld, Dark-/Light-Mode und Live-Statusanzeige des Backends
|
||
- ✅ Tastaturkürzel `/` und `Strg+K` zum Fokussieren der Suche
|
||
- ✅ Docker-Compose-Setup: `docker compose up -d --build` startet Frontend + Backend
|
||
- ✅ Persistentes Docker-Volume für die SQLite-Datenbank
|
||
- ✅ REST-API für Geräte & Dienste (`/api/devices`, `/api/services`), Zod-validiert,
|
||
mit Repository-Layer über Drizzle (siehe `apps/backend/src/db/repositories`)
|
||
- ✅ Suche im Frontend gegen echte Backend-Daten (TanStack Query), inkl. Ranking-Logik
|
||
aus `packages/shared` und Tastatur-Navigation (Pfeiltasten, Enter, Escape)
|
||
- ✅ Kategorien-API (`/api/categories`), inkl. Umbenennen, Löschen (Dienste behalten
|
||
ihre Zuordnung nicht, werden aber nicht gelöscht) und Bulk-Reorder für Drag & Drop
|
||
- ✅ Favoriten-Toggle direkt in der Trefferliste (Stern anklicken)
|
||
- ✅ Scanner-Engine + API (`POST /api/scan/devices/:id`, `POST /api/scan/fritzbox`):
|
||
DNS-Kandidaten (hostname/.home/.local), Portscan (80, 443 + typische Ports),
|
||
Titel-/Favicon-Auslesen, Softwareerkennung, FritzBox-Geräteliste per TR-064
|
||
(HTTP-Digest-Auth). Läuft ausschließlich manuell per API-Aufruf – nie automatisch.
|
||
Benutzeränderungen an Diensten (Name, Kategorie, Favorit, Alias, Icon, Reihenfolge)
|
||
bleiben bei erneuten Scans garantiert erhalten.
|
||
- ✅ Adminbereich unter `/admin` (TanStack Router): Dashboard, Geräte (inkl.
|
||
„Jetzt scannen"-Button), Dienste (Inline-Bearbeitung), Kategorien (natives
|
||
Drag & Drop), Scanner (FritzBox-Trigger + Sammel-Scan), Logs (Scan-Historie),
|
||
Einstellungen (Live-Systeminfo + Theme), Plugins (ehrlicher Hinweis auf
|
||
zukünftigen Commit)
|
||
- ✅ PWA: installierbar (Manifest + Icons für Android/iOS/Desktop), Service
|
||
Worker mit App-Shell-Precaching, `/api/*` läuft offline über den letzten
|
||
Cache-Stand (NetworkFirst, 3s-Timeout)
|
||
- ✅ Plugin-System: echte, ladbare Plugins unter `apps/backend/plugins/*`
|
||
(Bind-Mount, kein Rebuild nötig). Plugins können die Softwareerkennung des
|
||
Scanners erweitern (inkl. eigenem Icon) und eigene Geräte-Importquellen
|
||
bereitstellen. Zwei funktionierende Beispiel-Plugins liegen bei.
|
||
|
||
Noch **nicht** enthalten:
|
||
|
||
- shadcn/ui, React Hook Form (aktuell einfache kontrollierte Formulare)
|
||
- Eigene Admin-Routen/Menüpunkte pro Plugin (aktuell gesammelt auf einer Seite)
|
||
|
||
### Umgebungsvariablen (.env)
|
||
|
||
Alle Umgebungsvariablen sind in `.env.example` dokumentiert. Für die lokale
|
||
Entwicklung und für Docker Compose:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# .env anpassen (v. a. FRITZBOX_* für den FritzBox-Scan)
|
||
```
|
||
|
||
`.env` ist in `.gitignore` und wird nie committet. **Auf dem Server
|
||
(`/opt/LaunchPad`) muss sie nach dem ersten `git pull` einmalig manuell
|
||
angelegt werden**, da git-ignorierte Dateien nicht mitgepullt werden:
|
||
|
||
```bash
|
||
cd /opt/LaunchPad
|
||
cp .env.example .env
|
||
nano .env # FRITZBOX_* eintragen
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Fehlt `.env` komplett, startet alles trotzdem mit den in `docker-compose.yml`
|
||
hinterlegten Defaults – der FritzBox-Scan liefert dann kontrolliert `HTTP 400`
|
||
statt abzustürzen. Für `pnpm dev:backend` (ohne Docker) wird `.env` automatisch
|
||
über `dotenv` geladen (`apps/backend/src/env.ts`, wird als allererstes importiert).
|
||
|
||
Siehe [`docs/ROADMAP.md`](./docs/ROADMAP.md) für die geplante Reihenfolge.
|
||
|
||
## API-Endpunkte (Stand Commit 2)
|
||
|
||
```
|
||
GET /api/health
|
||
GET /api/devices Liste aller Geräte inkl. ihrer Dienste
|
||
GET /api/devices/:id
|
||
POST /api/devices
|
||
PATCH /api/devices/:id
|
||
DELETE /api/devices/:id (löscht zugehörige Dienste per Cascade)
|
||
|
||
GET /api/services optional ?deviceId=&category=&favorite=true
|
||
GET /api/services/:id
|
||
POST /api/services erfordert existierende deviceId
|
||
PATCH /api/services/:id
|
||
DELETE /api/services/:id
|
||
|
||
GET /api/categories
|
||
POST /api/categories
|
||
PATCH /api/categories/reorder Body: [{ id, order }, ...]
|
||
PATCH /api/categories/:id Umbenennen
|
||
DELETE /api/categories/:id Dienste behalten ihre category nicht mehr (null),
|
||
werden aber nicht gelöscht
|
||
|
||
POST /api/scan/devices/:id Netzwerk-Scan für ein Gerät (DNS, Ports, Titel,
|
||
Favicon, Softwareerkennung); legt/aktualisiert Dienste
|
||
POST /api/scan/fritzbox Liest Geräteliste der FritzBox per TR-064
|
||
(erfordert FRITZBOX_HOST/USERNAME/PASSWORD)
|
||
|
||
GET /api/logs optional ?limit= (Default 100, Max 500)
|
||
|
||
GET /api/plugins geladene Plugins mit Capabilities
|
||
POST /api/plugins/:name/import löst importDevices() eines Plugins aus
|
||
```
|
||
|
||
## Frontend-Routen
|
||
|
||
```
|
||
/ Startseite: minimalistische Suche
|
||
/admin -> redirect zu /admin/dashboard
|
||
/admin/dashboard
|
||
/admin/devices
|
||
/admin/services
|
||
/admin/categories
|
||
/admin/scanner
|
||
/admin/plugins Hinweis: Plugin-System noch nicht gebaut
|
||
/admin/settings
|
||
/admin/logs
|
||
```
|
||
|
||
## Deployment auf dem Server (xlc-launchpad)
|
||
|
||
```bash
|
||
cd /opt/LaunchPad
|
||
git pull
|
||
docker compose up -d --build
|
||
```
|
||
|
||
## Branching
|
||
|
||
Entwicklung erfolgt ausschließlich auf `dev`. `main` bleibt der stabile Branch.
|