From fee5e76842b92d2b42c086b683ad913400a8717e Mon Sep 17 00:00:00 2001 From: Oliver G Date: Wed, 18 Feb 2026 11:03:53 +0100 Subject: [PATCH] feat(ui): add publish readiness indicators and WP env key aliases --- backend/app/admin_ui.py | 19 +++++++++++++++++++ backend/app/config.py | 7 ++++--- backend/templates/admin_article_detail.html | 15 +++++++++++++-- backend/templates/admin_dashboard.html | 4 ++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/backend/app/admin_ui.py b/backend/app/admin_ui.py index 8d8e879..fba1b91 100644 --- a/backend/app/admin_ui.py +++ b/backend/app/admin_ui.py @@ -156,6 +156,19 @@ def _build_image_entries(article: dict, extraction: dict, meta: dict) -> list[di return entries +def _publish_readiness(article: dict, meta: dict) -> tuple[bool, list[str]]: + reasons: list[str] = [] + if article.get("status") not in {"approved", "published"}: + reasons.append("Status ist nicht 'approved'") + if int(article.get("legal_checked", 0)) != 1: + reasons.append("Rechtsfreigabe fehlt") + image_review = meta.get("image_review") if isinstance(meta.get("image_review"), dict) else {} + selected_image = image_review.get("selected_url") if isinstance(image_review.get("selected_url"), str) else None + if not selected_image: + reasons.append("Hauptbild nicht ausgewählt") + return len(reasons) == 0, reasons + + def _legal_checklist(article: dict, feed: dict | None) -> list[dict[str, str]]: meta = article.get("meta", {}) extraction = meta.get("extraction") if isinstance(meta.get("extraction"), dict) else {} @@ -287,6 +300,9 @@ def admin_dashboard(request: Request): extraction = meta.get("extraction") if isinstance(meta.get("extraction"), dict) else {} images = _read_article_images(article, extraction) article["meta"] = meta + ready, reasons = _publish_readiness(article, meta) + article["publish_ready"] = ready + article["publish_blockers"] = reasons article["extracted_images"] = images article["image_entries"] = _build_image_entries(article, extraction, meta) image_review = meta.get("image_review") if isinstance(meta.get("image_review"), dict) else {} @@ -339,6 +355,9 @@ def admin_article_detail(request: Request, article_id: int): if not article.get("press_contact") and isinstance(extraction.get("press_contact"), str): article["press_contact"] = extraction.get("press_contact") article["extraction"] = extraction + publish_ready, publish_blockers = _publish_readiness(article, meta) + article["publish_ready"] = publish_ready + article["publish_blockers"] = publish_blockers article["image_selection"] = extraction.get("image_selection") if isinstance(extraction.get("image_selection"), dict) else {} article["image_entries"] = _build_image_entries(article, extraction, meta) image_review = meta.get("image_review") if isinstance(meta.get("image_review"), dict) else {} diff --git a/backend/app/config.py b/backend/app/config.py index e194bcc..fc52ec3 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -2,6 +2,7 @@ from functools import lru_cache from pathlib import Path from dotenv import load_dotenv +from pydantic import AliasChoices, Field from pydantic_settings import BaseSettings, SettingsConfigDict @@ -25,9 +26,9 @@ class Settings(BaseSettings): app_db_path: str = "backend/data/rss_news.db" - wordpress_base_url: str | None = None - wordpress_username: str | None = None - wordpress_app_password: str | None = None + wordpress_base_url: str | None = Field(default=None, validation_alias=AliasChoices("WORDPRESS_BASE_URL", "WP_BASE_URL")) + wordpress_username: str | None = Field(default=None, validation_alias=AliasChoices("WORDPRESS_USERNAME", "WP_USERNAME")) + wordpress_app_password: str | None = Field(default=None, validation_alias=AliasChoices("WORDPRESS_APP_PASSWORD", "WP_PASSWORD")) wordpress_default_status: str = "draft" diff --git a/backend/templates/admin_article_detail.html b/backend/templates/admin_article_detail.html index a5943ef..6f06d36 100644 --- a/backend/templates/admin_article_detail.html +++ b/backend/templates/admin_article_detail.html @@ -203,10 +203,21 @@

WordPress Publish Queue

-

Voraussetzungen: Status `approved`, Rechtsfreigabe aktiv, Hauptbild gesetzt.

+ {% if article.publish_ready %} +

Publish bereit

+ {% else %} +

Publish blockiert

+ {% if article.publish_blockers %} + + {% endif %} + {% endif %}
- +
diff --git a/backend/templates/admin_dashboard.html b/backend/templates/admin_dashboard.html index d47628f..fe811a5 100644 --- a/backend/templates/admin_dashboard.html +++ b/backend/templates/admin_dashboard.html @@ -163,6 +163,10 @@ {{ a.status }}
Legal: {{ "OK" if a.legal_checked else "offen" }}
+
Publish: {{ "bereit" if a.publish_ready else "blockiert" }}
+ {% if not a.publish_ready and a.publish_blockers %} +
{{ a.publish_blockers|join(", ") }}
+ {% endif %} {% if a.selected_image_url %}
Hauptbild gesetzt
Hauptbild