Files
BSN-Chatsystem/plan_qc_agent.md

165 lines
6.6 KiB
Markdown

# Plan: Automatischer QC-Agent für Article-Server
> **Ziel:** Jeder Artikel auf dem Article-Server wird automatisch geprüft. Ein Icon zeigt den QC-Status. Erst nach bestandener Prüfung wird der Artikel für Daniel zum Publizieren freigegeben.
**Stand:** 22. Juni 2026 | **Autor:** Basti (CvD)
---
## 1. Workflow-Visualisierung
```
Artikel wird auf Article-Server hochgeladen
┌─────────────────────────────┐
│ 🔴 QC AUSSTEHEND │ ← Icon im Article-Server
│ "Warte auf Qualitätscheck" │
└─────────────┬───────────────┘
┌─────────▼─────────┐
│ QC-Agent startet │ ← automatisch, asynchron
│ (Cronjob/Subagent) │
└─────────┬─────────┘
┌─────────▼─────────┐
│ Phase 1: Technik │ ~5 Sekunden
│ Phase 2: Inhalt │ ~30 Sekunden
│ Phase 3: Joomla │ ~5 Sekunden
└─────────┬─────────┘
┌───────┴───────┐
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ 🟢 FREI │ │ 🔴 FEHLER│
│ "Geprüft"│ │ "X Fehler"│
└──────────┘ └──────────┘
```
---
## 2. QC-Phasen im Detail
### Phase 1: Technische Prüfung (Sekunden)
| # | Check | Methode | Fehlerbehandlung |
|---|---|---|---|
| T1 | Genau 1 Read-More | `grep -c system-readmore` | ❌ BLOCKER |
| T2 | Kein `<br>` nach Read-More | `grep -A1 system-readmore \| grep '<br>'` | ❌ BLOCKER |
| T3 | `<p class="meta">` nicht `<div>` | Regex | ❌ BLOCKER |
| T4 | Keine Emojis im Body | Unicode-Range grep | ⚠️ WARNUNG |
| T5 | Endet mit `</html>` | `tail -1` | ❌ BLOCKER |
| T6 | Alle Links `target="_blank"` | `grep -c '<a '` vs `grep -c 'target="_blank"'` | ❌ BLOCKER |
| T7 | Quellen als span-strong, nicht h2 | Regex | ❌ BLOCKER |
| T8 | Meta-Description gefüllt | `grep 'meta name="description" content="[a-zA-Z]'` | ❌ BLOCKER |
| T9 | Meta-Keywords gefüllt | `grep 'meta name="keywords" content="[a-zA-Z]'` | ⚠️ WARNUNG |
| T10 | QC-Zeile in `<p class="qc">` | Regex | ⚠️ WARNUNG |
| T11 | HTML wohlgeformt | `xmllint --html` | ❌ BLOCKER |
| T12 | Keine nackten Umlaut-Verluste | `fix_umlauts.py --check` | ❌ BLOCKER |
### Phase 2: Inhaltliche Prüfung (KI-gestützt, ~30 Sekunden)
| # | Check | Methode | Fehlerbehandlung |
|---|---|---|---|
| I1 | **Link-Gültigkeit** | HEAD-Request auf alle externen Links, max 5 parallel | ⚠️ 404 → WARNUNG, Link entfernen? |
| I2 | **Zahlen-Plausibilität** | KI: "Sind genannte Zahlen im Kontext plausibel? Z.B. kein Kickstarter über $50M" | ⚠️ WARNUNG bei Verdacht |
| I3 | **Genderneutralität** | KI: "Enthält der Text maskuline Generika (Spieler, Leser, Entwickler)?" | ⚠️ WARNUNG |
| I4 | **Quellen-Breite** | KI: "Stammen ALLE Quellen aus nur EINER Domain (z.B. nur Reddit)?" | ⚠️ WARNUNG |
| I5 | **Abkürzungen ausgeschrieben** | KI: "Werden Abkürzungen (BGG, SFG, TCG) bei Erstverwendung ausgeschrieben?" | ⚠️ WARNUNG |
| I6 | **Spieletitel in strong** | KI: "Sind alle Spieletitel in `<strong>` gewrappt?" | ⚠️ WARNUNG |
| I7 | **Keine Zugangsprobleme erwähnt** | KI: "Enthält der Text Sätze wie 'Seite nicht zugänglich'?" | ❌ BLOCKER |
| I8 | **Publikationsdatum der Quellen** | KI: "Sind Quellen aktuell (<14 Tage)? Falls älter: als Retro gekennzeichnet?" | ⚠️ WARNUNG |
### Phase 3: Joomla-Readiness
| # | Check | Methode | Fehlerbehandlung |
|---|---|---|---|
| J1 | Bild in article_images.json gemappt | JSON-Key-Check | ⚠️ WARNUNG |
| J2 | Bild-Datei existiert auf Disk | `os.path.exists()` | ❌ BLOCKER |
| J3 | Bild-Format korrekt (joomlaImage) | Regex auf image_intro in Payload | ❌ BLOCKER |
| J4 | Kategorie gesetzt | Meta-Tag oder Default | ⚠️ WARNUNG |
| J5 | Artikel-Server antwortet mit 200 | `curl localhost:8890/artikel_...` | ❌ BLOCKER |
---
## 3. BLOCKER vs WARNUNG
| Level | Bedeutung | Artikel nutzbar? |
|---|---|---|
| **❌ BLOCKER** | Artikel kann SO nicht publiziert werden | ❌ Nein — muss korrigiert werden |
| **⚠️ WARNUNG** | Potenzielles Problem, Publizieren trotzdem möglich | ⚠️ Ja, aber mit Hinweis an Daniel |
**Minimum für 🟢 FREI: 0 BLOCKER**
---
## 4. Icon-System im Article-Server
| Icon | Zustand | Aktion |
|---|---|---|
| 🔴 | QC ausstehend | Warten |
| 🟡 | QC läuft | Warten |
| 🟢 | QC bestanden (0 Blocker) | Publizieren freigegeben |
| 🟠 | QC mit Warnungen (0 Blocker, >0 Warnungen) | Publizieren möglich, Warnungen einsehbar |
| 🔴❌ | QC fehlgeschlagen (>0 Blocker) | Fehlerliste einsehbar, Korrektur nötig |
---
## 5. Technische Umsetzung
### 5.1 QC-Agent als Skill
```yaml
name: article-qc
description: Automatischer Qualitätscheck für Artikel auf dem Article-Server
trigger: Artikel-Upload auf Port 8890
```
### 5.2 article_server.py Erweiterung
```python
# Neue Felder im Artikel-Objekt
{
"filename": "artikel_xxx.html",
"qc_status": "pending|running|passed|warning|failed",
"qc_score": {"blockers": 0, "warnings": 2, "total_checks": 20},
"qc_details": [
{"check": "T1", "status": "pass", "message": "Read-More: 1"},
{"check": "I1", "status": "warn", "message": "3 Links antworten mit 404"}
],
"qc_timestamp": "2026-06-22T10:45:00"
}
```
### 5.3 Ablauf
1. **Trigger:** Sobald eine neue HTML-Datei auf dem Artikel-Server erscheint (Upload oder write_file)
2. **article_server.py** setzt Status auf `pending`, zeigt 🔴
3. **article_server.py** startet `bash verify_article.sh` (Phase 1)
4. Bei 0 Blockern: startet Subagent für Phase 2+3
5. Subagent returned QC-Report als JSON
6. article_server.py speichert Ergebnis in `article_qc.json`
7. Frontend zeigt aktualisiertes Icon
---
## 6. Umsetzungsschritte
| Schritt | Was | Aufwand |
|---|---|---|
| 1 | `article_qc.py` schreiben (Phase 1 Checks + JSON-Output) | 30 Min |
| 2 | `article_server.py` erweitern (QC-Status-Feld + Icon-Logik) | 45 Min |
| 3 | Subagent-Prompt für Phase 2+3 schreiben | 15 Min |
| 4 | `article_server.html` Frontend updaten (Icons) | 30 Min |
| 5 | Testen mit 3 Artikeln (Deal, Crowdfunding, BGA) | 30 Min |
| 6 | Skill `article-qc` anlegen | 10 Min |
---
## 7. Erfolgskriterium
> **99% fehlerfreie Artikel** = 0 BLOCKER + Daniel muss NICHTS manuell nachkorrigieren.
Gemessen über 10 aufeinanderfolgende Artikel.