This commit is contained in:
team3
2026-06-22 22:21:23 +02:00
parent b3b5dbf37d
commit 28d0b494cd
7 changed files with 875 additions and 232 deletions

View File

@@ -9,6 +9,7 @@ Schritt-Dateien bleiben liegen → Abbruch erhält Fortschritt, ▶ setzt am off
"""
import asyncio
import json
import logging
import math
from datetime import datetime, timezone
@@ -21,7 +22,7 @@ from config import (
LESBARKEIT_AKTIV, TEMPLATES_DIR,
)
import lesbarkeit
from database import list_guides, update_guide
from database import list_guides, update_guide, list_bausteine, list_subbausteine, set_guide_content
from fsutil import atomic_write_json, atomic_write_text
from jsonio import read_json_file as _json_datei
from paths import bausteine_path, guide_content_path, project_dir, subbausteine_path
@@ -52,12 +53,19 @@ GUIDE_CHUNK = 10
LESE_RUNDEN = 1
def _load_subbausteine(topic: str) -> dict[str, list[dict]]:
"""Sidecar laden: {Baustein-Titel: [{titel, stufe}, …]}. Fehlt sie → {} (Fallback)."""
async def _load_subbausteine(topic: str) -> dict[str, list[dict]]:
"""Subbausteine je Baustein — DB-first ({titel, stufe, relevanz}), Fallback Sidecar-Datei.
Fehlt beides → {} (Guide nimmt alles)."""
out: dict[str, list[dict]] = {}
for r in await list_subbausteine(topic):
if r["status"] == "konsens" and r["sub_titel"] and r["stufe"] in ("einfach", "mittel", "schwer"):
out.setdefault(r["baustein"], []).append(
{"titel": r["sub_titel"], "stufe": r["stufe"], "relevanz": r["relevanz"]})
if out:
return out
data = _json_datei(subbausteine_path(topic))
if not isinstance(data, dict):
return {}
out: dict[str, list[dict]] = {}
for titel, subs in data.items():
if not isinstance(subs, list):
continue
@@ -478,9 +486,9 @@ async def _generate_sections(
"Wähle, was diesem Zweck dient — lass weg, was dafür nicht nötig ist."
)
# Subbausteine je Baustein (Sidecar) — früh geladen: steuert Auswahl + Sub-Filter je Format.
# Subbausteine je Baustein (DB-first) — früh geladen: steuert Auswahl + Sub-Filter je Format.
# Fehlt sie → {} (Fallback: Guide nimmt alles).
subs_raw = _load_subbausteine(topic)
subs_raw = await _load_subbausteine(topic)
def _hat_relevanz(num, art):
return any(isinstance(s, dict) and s.get("relevanz") == art for s in subs_raw.get(_titel(entries[num]), []))
@@ -932,7 +940,13 @@ async def generate_guide(guide_id: str, topic: str, format_name: str, instructio
for p_alt in guide_slot_dateien(content_path):
p_alt.unlink(missing_ok=True)
alle = _lade_bausteine(bausteine_path(topic).read_text(encoding="utf-8"))
bs = await list_bausteine(topic, status="konsens")
if bs:
alle = {i: (f"{b['titel']}{b['beschreibung']}" if b["beschreibung"] else b["titel"])
for i, b in enumerate(bs, 1)}
else: # Fallback: bausteine.md (Alt-Themen)
bp = bausteine_path(topic)
alle = _lade_bausteine(bp.read_text(encoding="utf-8")) if bp.exists() else {}
if not alle:
await _fail(guide_id, "Keine Bausteine gefunden")
return
@@ -946,7 +960,8 @@ async def generate_guide(guide_id: str, topic: str, format_name: str, instructio
return
content = {"topic": topic, "format": format_name, "chapters": chapters}
atomic_write_json(content_path, content, indent=1)
atomic_write_json(content_path, content, indent=1) # Brücke (Resume/Fallback)
await set_guide_content(topic, format_name, json.dumps(content, ensure_ascii=False))
now = datetime.now(timezone.utc).isoformat()
await update_guide(guide_id, status="done", progress=None, step=None, updated_at=now)