feat: secure and document book reviews system
Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Failing after 10m3s

Added rate limiting to APIs, cleaned up docs, implemented fallback logic for reviews without text, and added comprehensive n8n guide.
This commit is contained in:
2026-02-15 22:32:49 +01:00
parent 0766b46cc8
commit 6998a0e7a1
22 changed files with 3141 additions and 4135 deletions

View File

@@ -0,0 +1,99 @@
# Automatisierung: Gelesene Bücher (Hardcover → Directus)
Diese Anleitung erklärt, wie du n8n einrichtest, damit Bücher, die du auf Hardcover als "Read" markierst, automatisch in deinem Directus CMS landen.
## Ziel
- **Quelle:** Hardcover (Status: Read)
- **Ziel:** Directus (Collection: `book_reviews`)
- **Verhalten:**
- Buch wird automatisch angelegt.
- Status wird auf `draft` gesetzt (damit du optional eine Bewertung/Review schreiben kannst).
- Wenn du keine Review schreiben willst, kannst du den Status im n8n Workflow direkt auf `published` setzen.
## Voraussetzungen
1. **n8n Instanz** (self-hosted oder Cloud).
2. **Directus URL & Token** (Admin oder Token mit Schreibrechten auf `book_reviews`).
3. **Hardcover Account** (GraphQL API Zugriff).
## Schritt-für-Schritt Einrichtung
### 1. Directus Collection `book_reviews` vorbereiten
Stelle sicher, dass deine Collection in Directus folgende Felder hat (nullable = optional):
- `status` (String: `draft`, `published`, `archived`)
- `book_title` (String, required)
- `book_author` (String, required)
- `book_image` (String, URL)
- `rating` (Integer, nullable, 1-5)
- `hardcover_id` (String, unique, um Duplikate zu vermeiden)
- `finished_at` (Date, wann du es gelesen hast)
- `review` (Text/Markdown, nullable - DEINE Meinung)
### 2. n8n Workflow erstellen
Erstelle einen neuen Workflow in n8n.
#### Node 1: Trigger (Zeitgesteuert)
- **Typ:** `Schedule Trigger`
- **Intervall:** Alle 60 Minuten (oder wie oft du willst).
#### Node 2: Hardcover API Abfrage
- **Typ:** `GraphQL` (oder `HTTP Request` POST an `https://api.hardcover.app/graphql`)
- **Query:**
```graphql
query {
me {
books_read(limit: 5, order_by: {finished_at: desc}) {
finished_at
book {
id
title
contributions {
author {
name
}
}
images {
url
}
}
}
}
```
- **Auth:** Bearer Token (Dein Hardcover API Key).
#### Node 3: Auf neue Bücher prüfen
- **Typ:** `Function` / `Code`
- **Logik:** Vergleiche die `id` von Hardcover mit den `hardcover_id`s, die schon in Directus sind (du musst vorher eine Directus Abfrage machen, um existierende IDs zu holen).
- **Ziel:** Filtere Bücher heraus, die schon importiert wurden.
#### Node 4: Buch in Directus anlegen
- **Typ:** `Directus` (oder `HTTP Request` POST an dein Directus)
- **Resource:** `Items` -> `book_reviews` -> `Create`
- **Mapping:**
- `book_title`: `{{ $json.book.title }}`
- `book_author`: `{{ $json.book.contributions[0].author.name }}`
- `book_image`: `{{ $json.book.images[0].url }}`
- `hardcover_id`: `{{ $json.book.id }}`
- `finished_at`: `{{ $json.finished_at }}`
- `status`: `draft` (oder `published` wenn du es sofort live haben willst)
- `rating`: `null` (das füllst du dann manuell in Directus aus!)
- `review`: `null` (das schreibst du dann manuell in Directus!)
### 3. Workflow aktivieren
- Teste den Workflow einmal manuell.
- Aktiviere ihn ("Active" Switch oben rechts).
## Workflow: Bewertung schreiben (Optional)
1. Das Buch erscheint automatisch in Directus als `draft`.
2. Du bekommst (optional) eine Benachrichtigung (via n8n -> Email/Discord/Telegram).
3. Du loggst dich in Directus ein.
4. Du öffnest das Buch.
5. **Möchtest du bewerten?**
- Ja: Gib `rating` (1-5) und `review` Text ein. Setze Status auf `published`.
- Nein, nur auflisten: Lass `rating` leer. Setze Status auf `published`.
## Frontend Logik (Code Anpassung)
Der Code im Frontend (`ReadBooks.tsx`) ist bereits so gebaut, dass er:
- Bücher anzeigt, die `status: published` haben.
- Wenn `rating` vorhanden ist, werden Sterne angezeigt.
- Wenn `review` vorhanden ist, wird der Text angezeigt.
- Wenn beides fehlt, wird das Buch einfach nur als "Gelesen" aufgelistet (Cover + Titel + Autor).