fix: QC-Ratings aus 7 älteren Artikeln entfernt (CHECK 10)
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user