Testlauf dokumentiert, README vervollstaendigt
This commit is contained in:
217
docs/testlauf.md
Normal file
217
docs/testlauf.md
Normal file
@@ -0,0 +1,217 @@
|
||||
# Testlauf-Protokoll
|
||||
|
||||
Durchgefuehrt am 20.09.2026 gegen die echten Systeme, nicht simuliert.
|
||||
Alle Executions liegen in n8n und sind dort nachvollziehbar.
|
||||
|
||||
---
|
||||
|
||||
## Vorbereitung
|
||||
|
||||
`artikel-index.json` wurde so gesetzt, dass nur ein Artikel auf `offen` stand,
|
||||
um NeuronWriter-Kontingent zu sparen:
|
||||
|
||||
```
|
||||
brief_bereit handgeschriebene-werbebriefe
|
||||
pausiert handschriftliche-mailings-kundenbindung
|
||||
pausiert response-rate-direktmarketing
|
||||
offen dummy-testlauf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lauf 1: Workflow 1, Execution 167
|
||||
|
||||
Start per Webhook um 10:41:00, beendet 10:43:07, Status `success`.
|
||||
24 Nodes gelaufen, kein einziger Fehlerpfad.
|
||||
|
||||
Der Poll-Loop arbeitete wie ausgelegt:
|
||||
|
||||
| Node | Durchlaeufe |
|
||||
|---|---|
|
||||
| `Warten` | 6 |
|
||||
| `Analyse abfragen` | 6 |
|
||||
| `Versuch zaehlen` | 5 |
|
||||
| `Poll-Limit erreicht?` | 5 |
|
||||
|
||||
Die Analyse war nach dem sechsten Poll fertig, also nach rund 120 Sekunden.
|
||||
Von 30 erlaubten Versuchen wurden 6 gebraucht.
|
||||
|
||||
**Ergebnis:**
|
||||
|
||||
```
|
||||
Briefe vorbereitet: 1, Fehler: 0
|
||||
|
||||
Fertig:
|
||||
dummy-testlauf | Zielwortzahl 839 | 12 Pflichtbegriffe, 29 Fragen
|
||||
Datei: briefe/brief-dummy-testlauf.json
|
||||
Analyse: https://app.neuronwriter.com/analysis/view/ff324721305a0a60
|
||||
```
|
||||
|
||||
**Gegenprobe im Repo:**
|
||||
|
||||
- `briefe/brief-dummy-testlauf.json` angelegt, 19437 Bytes
|
||||
- Commit `150017a9` "Brief erzeugt: dummy-testlauf (handgeschriebene briefe roboter)"
|
||||
- Commit `4c4fc0f2` "Status auf brief_bereit gesetzt (1 Artikel)"
|
||||
- Zeile in `artikel-index.json` steht auf `brief_bereit`, `query_id` nachgetragen
|
||||
|
||||
Der Brief enthaelt alle geforderten Felder sowie den Zusatzblock:
|
||||
|
||||
```
|
||||
query_id ff324721305a0a60 | keyword handgeschriebene briefe roboter | wortzahl_ziel 839
|
||||
begriffe_pflicht 12 | begriffe_erweitert 65 | fragen 29
|
||||
top-3 Fragen (nach Gewicht):
|
||||
10 Wo kann ich handschriftliche Briefe schreiben lassen?
|
||||
9 Wie kann ich Handschriften in digitalen Text umwandeln?
|
||||
9 Wie kann ich schnell handschriftlich schreiben?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lauf 2a: Workflow 2, Nachbesserungspfad, Execution 168
|
||||
|
||||
Zielwert 72, Testartikel hatte Score 44. 24 Nodes, alle `success`.
|
||||
|
||||
```
|
||||
Importiert: 0 | Nachbessern: 1 | Fehler: 0
|
||||
|
||||
Score zu niedrig, Nachbesserung liegt im Repo:
|
||||
handgeschriebene-werbebriefe: Score 44 von 72
|
||||
9 Pflichtbegriffe fehlen, 71 Zusatzbegriffe
|
||||
Wortzahl 96 von 1178 (-1082)
|
||||
Datei: nachbessern/nachbessern-handgeschriebene-werbebriefe.json
|
||||
|
||||
Kein Beitrag wurde veroeffentlicht. Alle Importe stehen auf Entwurf.
|
||||
```
|
||||
|
||||
Der WordPress-Zweig wurde korrekt nicht betreten.
|
||||
|
||||
---
|
||||
|
||||
## Lauf 2b: Workflow 2, Importpfad, Execution 169
|
||||
|
||||
Zielwert per Webhook auf 40 abgesenkt (`{"score_ziel":40}`), damit derselbe
|
||||
Artikel den Importpfad nimmt. 32 Nodes, alle `success`.
|
||||
|
||||
```
|
||||
Importiert: 1 | Nachbessern: 0 | Fehler: 0
|
||||
|
||||
Als Entwurf in WordPress:
|
||||
handgeschriebene-werbebriefe (Score 44, neu angelegt)
|
||||
Vorschau: https://skrift.de/?p=4210&preview=true
|
||||
Bearbeiten: https://skrift.de/wp-admin/post.php?post=4210&action=edit
|
||||
PREISE: 2 ausgeschriebene(r) Preis(e) im Text: 2,56 EUR, 0,95 €.
|
||||
Bitte durch [skrift_preis key="..."] ersetzen.
|
||||
Hinweis: Cache-Endpunkt antwortete mit HTTP 403. Kein Abbruchgrund.
|
||||
```
|
||||
|
||||
**Gegenprobe in WordPress** (`GET /wp-json/wp/v2/posts/4210?context=edit`):
|
||||
|
||||
```
|
||||
id 4210 | status draft | slug handgeschriebene-werbebriefe
|
||||
kategorien [17]
|
||||
kurzantwort gesetzt
|
||||
cta_ziel https://skrift.de/muster-anfordern
|
||||
stand_datum 2026-09-20
|
||||
_seopress_titles_title Handgeschriebene Werbebriefe: wann sie wirken
|
||||
_seopress_titles_desc gesetzt
|
||||
_seopress_analysis_target_kw handgeschriebene werbebriefe
|
||||
faq 2 Eintraege
|
||||
```
|
||||
|
||||
Die Kategorie `Direktmarketing` existierte nicht und wurde als ID 17 angelegt.
|
||||
|
||||
---
|
||||
|
||||
## Lauf 2c: Idempotenz, Execution 170
|
||||
|
||||
Derselbe Artikel ein zweites Mal, gleiche Parameter.
|
||||
|
||||
```
|
||||
post_id 4210 | aktion: aktualisiert | alter_status: draft | status: draft
|
||||
Kategorie erneut angelegt? nein (bestehende wiederverwendet)
|
||||
```
|
||||
|
||||
`GET /wp-json/wp/v2/posts?slug=handgeschriebene-werbebriefe&status=any`
|
||||
liefert genau **einen** Treffer. Es entstand kein Duplikat.
|
||||
|
||||
`status-importe.json` enthaelt eine Zeile, die beim zweiten Lauf ueberschrieben
|
||||
statt angehaengt wurde:
|
||||
|
||||
```json
|
||||
[{"slug":"handgeschriebene-werbebriefe","score":44,
|
||||
"datum":"2026-09-20T10:47:54.336Z","post_id":4210,
|
||||
"vorschau_url":"https://skrift.de/?p=4210&preview=true",
|
||||
"aktion":"aktualisiert","kategorie":"Direktmarketing"}]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Zwei Fehler, die der Testlauf gefunden hat
|
||||
|
||||
### 1. Webhook mit responseMode "lastNode"
|
||||
|
||||
Der erste Versuch endete in einem 504 von openresty, waehrend der Workflow im
|
||||
Hintergrund weiterlief. Ursache: Der Webhook hielt die HTTP-Verbindung bis zum
|
||||
Workflow-Ende offen, der Reverse Proxy brach nach 60 Sekunden ab.
|
||||
Beide Workflows nutzen jetzt `responseMode: "onReceived"`.
|
||||
|
||||
### 2. body statt data bei fullResponse
|
||||
|
||||
n8n 1.120 liefert den Antwortkoerper bei `fullResponse: true` im Feld `data`,
|
||||
nicht `body`. Alle Existenzpruefungen griffen auf `.body` zu und haetten immer
|
||||
"nicht vorhanden" ergeben. Folge waere gewesen: Workflow 2 legt bei jedem Lauf
|
||||
einen neuen Beitrag an, statt den bestehenden zu aktualisieren.
|
||||
An sieben Stellen korrigiert und versionsfest gemacht:
|
||||
|
||||
```js
|
||||
const K = (r) => (r && r.body !== undefined) ? r.body : ((r || {}).data);
|
||||
```
|
||||
|
||||
Lauf 2c belegt, dass die Idempotenz jetzt haelt.
|
||||
|
||||
---
|
||||
|
||||
## Netzwerkbefund: Gitea war aus n8n nicht erreichbar
|
||||
|
||||
Der erste Lauf scheiterte mit `timeout of 60000ms exceeded` beim Lesen der
|
||||
Artikeltabelle. Die Diagnose aus n8n heraus ergab:
|
||||
|
||||
| Ziel | Ergebnis |
|
||||
|---|---|
|
||||
| `https://gitea.lucas-orth.de/api/v1/version` | `ECONNABORTED` |
|
||||
| `http://gitea.lucas-orth.de/api/v1/version` | HTTP 301, Server openresty |
|
||||
| `https://app.neuronwriter.com/...` | HTTP 401 (erreichbar) |
|
||||
| `https://skrift.de/wp-json/` | HTTP 200 |
|
||||
| `http://gitea:3000/api/v1/version` | **HTTP 200** |
|
||||
|
||||
`gitea.lucas-orth.de` loest auf `100.98.99.19` auf, eine NetBird-Overlay-Adresse.
|
||||
Der n8n-Host erreichte den dortigen openresty auf Port 80, aber nicht auf 443.
|
||||
|
||||
Geloest ueber das Docker-Netz: beide Workflows sprechen Gitea jetzt als
|
||||
`http://gitea:3000` an. Der Weg laeuft nicht ueber den Reverse Proxy und
|
||||
nicht ueber das Overlay, ist damit schneller und faellt nicht aus, wenn am
|
||||
Proxy etwas geaendert wird.
|
||||
|
||||
Zum Nachtesten liegt der Hilfsworkflow `netzcheck` in n8n:
|
||||
|
||||
```bash
|
||||
curl -X POST https://n8n.lucas-orth.de/webhook/probe \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"url":"http://gitea:3000/api/v1/version"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Offene Punkte nach dem Testlauf
|
||||
|
||||
**Cache leeren gibt HTTP 403.** Der Benutzer `ai-agent` hat als Redakteur nicht
|
||||
die Berechtigung fuer `POST /wp-json/seopress/v1/commands/clear-cache`.
|
||||
Der Workflow behandelt das als Hinweis, nicht als Fehler. Bei Entwuerfen ist ein
|
||||
Cache-Purge ohnehin wirkungslos. Relevant wird es erst, wenn ein bereits
|
||||
veroeffentlichter Beitrag aktualisiert wird. Wer das braucht, gibt der Rolle
|
||||
Redakteur die noetige Capability oder leert nach dem Veroeffentlichen von Hand.
|
||||
|
||||
**Testreste.** In WordPress steht Beitrag 4210 als Entwurf, dazu die Kategorie
|
||||
`Direktmarketing` (ID 17). In NeuronWriter liegen zwei Analysen
|
||||
(`565abcca58f65e52`, `ff324721305a0a60`) mit je einer importierten Revision.
|
||||
Beides kann bleiben oder geloescht werden.
|
||||
Reference in New Issue
Block a user