Hallo Igor,
willkommen an Bord. Du übernimmst die Integration unserer News-Recherche-Pipeline (news.publishingheroes.de) in OneStack/VAILOR. Dieses Dokument ist deine Single Source of Truth: Es erklärt das komplette System, die Datenstrukturen, den bereits live laufenden OneStack-API-Contract und alle Zugänge.
Bester Einstieg: Lies dich von oben nach unten durch. Sektion 4 (bestehende Integration) und Sektion 6 (Migrations-Pfad) sind für dich am wichtigsten. Die versionierte Markdown-Quelle und alle tiefen Docs liegen im Repo — ideal für Claude Code.
Zugang: Kai schaltet dir GitHub (Collaborator) und Supabase frei und schickt dir die API-Keys separat über einen sicheren Kanal. Bei Fragen einfach bei Kai melden.
OneStack Vollintegration
Single Source of Truth für die Architektur, Datenstrukturen, die bestehende API-Integration und die Zugänge des Systems news.publishingheroes.de — mit allen Fakten, um die Pipeline vollständig in OneStack (VAILOR) zu portieren oder als Headless-Backend anzubinden.
Executive Summary
▾Das News-Recherche-Tool ist eine vollautonome (Level 5) Content-Pipeline für die Marken promptloop.de, idee-fuer-mich.de, maedchen.de sowie den Mandanten haustiermagazin.com. Es generiert täglich quellenbasierte, halluzinationsfreie und GEO/SEO-optimierte Artikel.
Status Quo
Aktuell existiert eine Stufe-1-Integration. Redakteure prüfen die generierten Artikel in einem Next.js-Dashboard und pushen sie per Klick via API (/api/onestack/push) an OneStack.
Zielbild (Vollintegration)
Das Frontend news.publishingheroes.de wird perspektivisch durch OneStack abgelöst. OneStack übernimmt das Redaktions-UI. Das bestehende Backend (Python-Worker, Supabase-DB, LLM-Router) wird entweder als Headless-Service beibehalten und tief an OneStack angebunden, oder die Logik wird vollständig nach OneStack migriert.
System-Architektur & Pipeline
▾Das System läuft auf einem dedizierten Cloud Computer (Ubuntu 24.04) und besteht aus vier Schichten: Eingang (Discovery/Ideation), Recherche (Research), Produktion (Generator) und Distribution (Publisher).
2.1 Die zwei Themen-Pipelines
Das System hat zwei getrennte Wege für Themen, die in unterschiedlichen Tabellen leben:
| Pipeline | Tabelle | Quelle | Zweck |
|---|---|---|---|
| Discovery | topics | RSS, NewsData.io | Aktuelle, externe Nachrichten-Themen |
| Ideation | story_ideas | Brand-DNA, Trends, Pillar-Balance | Eigene, markenkonforme Themen (KI-generiert) |
story_ideas können in topics konvertiert werden (story_ideas.topic_id), um den Recherche- und Generierungsprozess zu durchlaufen.2.2 Worker-Inventar (Python / systemd)
| Worker | Kadenz | Modell | Aufgabe |
|---|---|---|---|
discovery_rss / _newsdata | 2h / 1h | — | Ingest externer Quellen in topics |
enrichment_perplexity | 1h | Sonar Pro | Relevanz-Scoring & Pitch |
ideation_worker | Täglich 08:00 | GPT-4.1-mini | Generiert story_ideas |
chief_editor | 4h (steuerbar) | Claude 4.6 | QA-Gate: publish/rework/kill |
research_builder + deepdive | 15 min / 1h | Claude 4.6 / Sonar Pro | Erstellt research_dossier |
generator_v1 | 30 min | Claude 4.6 | Schreibt articles (Markdown) |
publisher_v1 | On-demand | — | Push an CMS (Legacy/Webhook) |
worker_schedule_config steuerbar; die systemd-Timer sind nur grobe Wecker.Datenmodell (Supabase)
▾Die PostgreSQL-17-Datenbank in Supabase (EU/Frankfurt) umfasst 40 Tabellen. Row Level Security (RLS) stellt sicher, dass Nutzer nur auf Marken zugreifen können, für die sie in user_brand_access autorisiert sind.
Kern-Tabellen
| Tabelle | Beschreibung |
|---|---|
brands | Stammdaten der Marken (Slug, Domain) |
brand_dna | Die „Seele“ der Marke: Tonalität, Blacklists, Content Pillars, Style-Rules |
topics | Recherche-Objekt: Scores, research_dossier (JSONB), Status-Lifecycle |
articles | Text-Entwurf: body_md, teaser, meta_title, geo_tldr, CMS-Metadaten |
model_configs | Steuert LLM-Workload-Zuordnung inkl. Fallback-Ketten |
Status-Lifecycle der Topics: proposed → researching → draft → review → approved → published.
docs/tech/database.md und memory/system_architecture.md im Repo.Die bestehende OneStack-Integration (Stufe 1)
▾Eine dedizierte Push-Route im Next.js-Frontend (apps/web/app/api/onestack/push/route.ts) sendet Artikel an OneStack. Dies ist der API-Contract, den OneStack heute erwartet:
4.1 Endpoints & Auth
- Base URL:
https://onestack.quinta.tools/api/v1 - Ingest:
POST /ingest/articles(Upsert viaexternalId) - Validate:
POST /ingest/articles/validate(Vorab-Check) - Auth: Header
X-API-Key; brand-spezifisch, verschlüsselt im Supabase Vault (z. B.onestack_api_key_haustiermagazin)
4.2 Daten-Format (TipTap JSON)
OneStack erwartet den Body nicht als HTML oder Markdown, sondern als strukturiertes TipTap-JSON. Eine eigene Logik (mdToTiptap()) wandelt Markdown in TipTap-Blöcke (H1–H4, Paragraphen, Listen, Blockquotes). Spezial-Blöcke wie das FAQ werden als dedizierte Block-Typen (type: "faq") in das content-Array eingebettet.
4.3 Feld-Mapping
| News-Tool Feld | OneStack Feld | Format |
|---|---|---|
article.id | externalId | UUID (String) |
article.title | title | String |
article.teaser | teaser | String (ohne Längenlimit) |
article.slug | slug | String |
article.body_edited_md | content | TipTap-JSON Document |
article.geo_tldr | tldr | TipTap-BulletList-JSON |
article.meta_title | metaTitle | String |
article.meta_description | metaDescription | String (max 160 Z.) |
article.cover_image_url | media | Array [{ url, type, isHero }] |
uncategorized. Echte Kategorien werden über das Capabilities-Endpoint pro Site definiert.Zugänge, Server & Secrets
▾.secrets/ auf der Maschine. Dieses Dokument sagt, wo alles liegt und wie Igor drankommt — den Key-Transfer macht Kai über einen sicheren Kanal.5.1 Infrastruktur & Repositories
| Ressource | Ort / URL | Zugriff |
|---|---|---|
| Cloud Computer „News“ | IP 35.195.248.50 (Ubuntu 24.04) | SSH via GCP / Manus. Nutzer ubuntu (sudo) |
| Code Repository | github.com/KaiKromat/news-publishingheroes | Privat. Branch Protection auf main (PR-only). Igor braucht Collaborator-Zugriff |
| Hub Repository | github.com/KaiKromat/publishingheroes-hub | Cross-Projekt-Kommunikation, lokal unter ~/news/hub-ref |
| Supabase Dashboard | Projekt qnfzusiohuzgjghjeawk (EU/Frankfurt) | Kai erteilt Igor Zugriff via E-Mail-Invite |
5.2 Secrets & Environment Variables
1. .secrets/-Verzeichnis (auf dem Cloud Computer): Pfad /home/ubuntu/news/.secrets/. Enthält .env-Dateien (z. B. supabase.env), die von systemd-Workern und dem Next.js-Build geladen werden — inkl. DB-Passwort und Service-Role-Key. Alle chmod 600, per .gitignore geschützt.
2. Supabase Vault (DB-intern): Hier liegen alle Drittanbieter-API-Keys (Anthropic, OpenAI, Perplexity, SerpAPI, DataForSEO) sowie die OneStack-Keys. Zugriff im Code über die RPC get_vault_secret('key_name'). Nur gelistete Keys (Allowlist in Migration 0049) sind auslesbar.
-- Beispiel: Secret aus dem Vault lesen (nur Service-Rolle / Admin)
SELECT get_vault_secret('onestack_api_key_haustiermagazin');
Migrations-Pfad zur Vollintegration
▾Empfohlener strategischer Pfad (Szenario C: Headless-Backend):
- API-First: Python-Worker und Supabase-DB bleiben als robuster „Motor“ bestehen — optimiert für Prompt-Caching, Fallbacks und RAG.
- OneStack als UI: Das Next.js-Frontend wird abgeschaltet. Redakteure arbeiten ausschließlich in OneStack.
- Bidirektionaler Sync:
- Push: Sobald
generator_v1einen Artikel fertigstellt (Statusdraft), wird er automatisch (statt manuell) an OneStack gepusht. - Pull/Webhooks: Redaktions-Änderungen in OneStack triggern Webhooks, die den Status in Supabase aktualisieren (z. B.
published), damit das Backend den Lifecycle abschließt.
- Push: Sobald
- Code-Umzug: Die Logik aus
onestack/push/route.tswird in einen neuen Python-Worker (onestack_sync_worker.py) portiert, der auf DB-Änderungen reagiert.
Betriebs-Runbook
▾Wichtige Befehle, falls Igor direkt auf der Maschine (35.195.248.50) operiert:
# Worker-Logs live mitlesen
journalctl -u news-generator-v1.timer -f
# Web-App bauen & neu starten
cd ~/news/apps/web && NODE_ENV=production pnpm build
sudo systemctl restart news-web.service
admin off. Bei Änderungen in /etc/caddy/Caddyfile zwingend sudo systemctl restart caddy nutzen — reload funktioniert NICHT.DB-Migrationen: liegen in infra/supabase/migrations/, ausgeführt via psql gegen den Pooler-Host aws-1-eu-central-1.pooler.supabase.com (der direkte db.*.supabase.co-Host ist IPv6-only und nicht erreichbar).
Backups: Täglicher logischer DB-Dump + Memory-Snapshot nach Cloudflare R2 (03:15 UTC). Supabase PITR zusätzlich aktiv.
Weiterführende Dokumentation (im Repo)
▾Alle tiefen Details liegen versioniert im Repository unter /docs/ und /memory/ — optimal für Claude Code lesbar:
| Datei | Inhalt |
|---|---|
memory/system_architecture.md | Vollständiges System-Design |
docs/tech/database.md | Alle Tabellen, Spalten, RLS-Policies |
docs/tech/deployment.md | Hosting, systemd-Struktur, Backups |
docs/prd/PRD.md | Product Requirements (Stand v1.29.2) |
memory/decisions/decision_log.md | 190+ Architektur-Entscheidungen (ADRs) — warum Dinge so gebaut sind |
memory/INDEX.md | Einstiegspunkt & Workflow-Vertrag |
memory/INDEX.md → system_architecture.md → decision_log.md.Glossar
▾| Begriff | Bedeutung |
|---|---|
| Brand-DNA | DB-Tabelle, die Tonalität, Zielgruppe, Content-Säulen und Verbots-Listen einer Marke definiert. Steuert, wie das LLM schreibt. |
| Research-Dossier | Strukturiertes JSONB-Objekt mit verifizierten Fakten, Zitaten und Quellen — die Basis für die Artikel-Generierung. |
| GEO | Generative Engine Optimization — Optimierung für Antwort-Maschinen/LLMs (z. B. TL;DR- und FAQ-Blöcke), nicht nur klassisches SEO. |
| TipTap-JSON | Strukturiertes Block-Format des TipTap-Editors, das OneStack als Body-Content erwartet (statt HTML/Markdown). |
| Anti-Slop | Regelwerk + Post-Linter, der KI-typische Floskeln und generische Überschriften aus den Texten fernhält. |
| RLS | Row Level Security — Zugriffsschutz auf Zeilen-Ebene direkt in PostgreSQL. |
| Vault | Verschlüsselter Secret-Speicher in Supabase (pgcrypto) für API-Keys. |
| Level-5-Autonomie | Das System läuft ohne menschlichen Eingriff von der Themenfindung bis zum fertigen Artikel-Entwurf. |