update
This commit is contained in:
@@ -69,9 +69,9 @@ BAUSTEINE_STEPS = (
|
||||
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
|
||||
"Gliederung",
|
||||
"Fragen finden", "Fragen wählen", "Fragen klären", "Fragen prüfen",
|
||||
"Karteikarten", "Beispiele", "Diagramme",
|
||||
"Karteikarten", "Beispiele",
|
||||
)
|
||||
ARTEFAKT_TYPEN = ("karteikarte", "beispiel", "diagramm")
|
||||
ARTEFAKT_TYPEN = ("karteikarte", "beispiel")
|
||||
|
||||
|
||||
def lade_quelle(topic: str) -> dict:
|
||||
@@ -206,7 +206,7 @@ def _bausteine_steps(topic: str) -> tuple:
|
||||
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
|
||||
"Gliederung",
|
||||
"Fragen finden", "Fragen wählen", "Fragen klären", "Fragen prüfen",
|
||||
"Karteikarten", "Beispiele", "Diagramme",
|
||||
"Karteikarten", "Beispiele",
|
||||
)
|
||||
mitte = base + (("Ergänzung",) if q["type"] == "projekt" else ()) + rest
|
||||
return (("Quelle aufbereiten",) if q["type"] == "link" else ()) + mitte
|
||||
@@ -235,7 +235,7 @@ PHASEN = (
|
||||
("Relevanz", ("Relevanz finden", "Relevanz wählen", "Relevanz klären")),
|
||||
("Gliederung", ("Gliederung",)),
|
||||
("Fragen", ("Fragen finden", "Fragen wählen", "Fragen klären", "Fragen prüfen")),
|
||||
("Artefakte", ("Karteikarten", "Beispiele", "Diagramme")),
|
||||
("Artefakte", ("Karteikarten", "Beispiele")),
|
||||
)
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ def _resume_step(topic: str) -> int:
|
||||
# Gliederung fertig; Frage-Muster offen?
|
||||
if not _frage_muster_komplett(topic):
|
||||
return _step_idx(topic, "Fragen finden")
|
||||
# Fragen fertig; Lern-Artefakte (Karteikarten/Beispiele/Diagramme) offen?
|
||||
# Fragen fertig; Lern-Artefakte (Karteikarten/Beispiele) offen?
|
||||
if not _artefakte_komplett(files):
|
||||
return _step_idx(topic, "Karteikarten")
|
||||
return len(_bausteine_steps(topic))
|
||||
@@ -402,7 +402,7 @@ def _reset_ab_phase(topic: str, label: str) -> None:
|
||||
p.unlink(missing_ok=True)
|
||||
|
||||
# Phasen-Index: Quelle=0 · Inventar=1 · Subbausteine=2 · Fakten=3 · Stufen=4 · Relevanz=5 · Gliederung=6 · Fragen=7 · Artefakte=8
|
||||
if idx <= 8: # Artefakte (Karteikarten/Beispiele/Diagramme)
|
||||
if idx <= 8: # Artefakte (Karteikarten/Beispiele)
|
||||
files["artefakte"].unlink(missing_ok=True)
|
||||
glob_del("artefakt-*")
|
||||
if idx <= 7: # Fragen
|
||||
@@ -1742,7 +1742,7 @@ async def _gliederung_block(ctx: GenContext, set_p, files: dict, entries: dict,
|
||||
return plan
|
||||
|
||||
|
||||
# --- Lern-Artefakte (Karteikarten/Beispiele/Diagramme aus den Fakten) ---
|
||||
# --- Lern-Artefakte (Karteikarten/Beispiele aus den Fakten) ---
|
||||
|
||||
def _karten_schema(data):
|
||||
"""{"karten":[{baustein,subbaustein,frage,antwort}]} → Liste (auch leer) · None bei kaputt."""
|
||||
@@ -1772,20 +1772,9 @@ def _beispiel_schema(data):
|
||||
return out
|
||||
|
||||
|
||||
def _diagramm_schema(data):
|
||||
"""{"diagramme":[{baustein,mermaid}]} → Liste (auch leer) · None bei kaputt."""
|
||||
if not isinstance(data, dict) or not isinstance(data.get("diagramme"), list):
|
||||
return None
|
||||
out = []
|
||||
for e in data["diagramme"]:
|
||||
if isinstance(e, dict) and (m := str(e.get("mermaid", "")).strip()):
|
||||
out.append({"baustein": str(e.get("baustein", "")).strip(), "mermaid": m})
|
||||
return out
|
||||
|
||||
|
||||
_ARTEFAKT_SCHEMA = {"karteikarte": _karten_schema, "beispiel": _beispiel_schema, "diagramm": _diagramm_schema}
|
||||
_ARTEFAKT_PROMPT = {"karteikarte": "Artefakt-Karteikarte", "beispiel": "Artefakt-Beispiel", "diagramm": "Artefakt-Diagramm"}
|
||||
_ARTEFAKT_SCHRITT = {"karteikarte": "Karteikarten", "beispiel": "Beispiele", "diagramm": "Diagramme"}
|
||||
_ARTEFAKT_SCHEMA = {"karteikarte": _karten_schema, "beispiel": _beispiel_schema}
|
||||
_ARTEFAKT_PROMPT = {"karteikarte": "Artefakt-Karteikarte", "beispiel": "Artefakt-Beispiel"}
|
||||
_ARTEFAKT_SCHRITT = {"karteikarte": "Karteikarten", "beispiel": "Beispiele"}
|
||||
|
||||
|
||||
def _artefakte_komplett(files: dict) -> bool:
|
||||
@@ -1853,10 +1842,10 @@ async def _artefakte_block(ctx: GenContext, set_p, files: dict, sidecar: dict, i
|
||||
|
||||
|
||||
async def _mirror_artefakte_db(topic: str, sidecar: dict, artefakte: dict) -> None:
|
||||
"""Artefakte in die DB spiegeln. Karteikarte/Beispiel je Sub (sub_norm), Diagramm je Baustein (sub_norm='')."""
|
||||
"""Artefakte in die DB spiegeln. Karteikarte/Beispiel je Sub (sub_norm)."""
|
||||
await db.delete_sub_artefakte(topic)
|
||||
btitel_list = list(sidecar.keys())
|
||||
for typ in ("karteikarte", "beispiel"):
|
||||
for typ in ARTEFAKT_TYPEN:
|
||||
for e in artefakte.get(typ, []):
|
||||
bt = _match_sub(e.get("baustein", ""), btitel_list)
|
||||
bnorm, sn = _norm_titel(bt), _norm_titel(e.get("subbaustein", ""))
|
||||
@@ -1864,12 +1853,6 @@ async def _mirror_artefakte_db(topic: str, sidecar: dict, artefakte: dict) -> No
|
||||
continue
|
||||
daten = json.dumps({k: v for k, v in e.items() if k not in ("baustein", "subbaustein")}, ensure_ascii=False)
|
||||
await db.put_sub_artefakt(topic, bnorm, sn, typ, daten, bt, e.get("subbaustein", ""))
|
||||
for e in artefakte.get("diagramm", []):
|
||||
bt = _match_sub(e.get("baustein", ""), btitel_list)
|
||||
if not (bnorm := _norm_titel(bt)):
|
||||
continue
|
||||
daten = json.dumps({"mermaid": e.get("mermaid", "")}, ensure_ascii=False)
|
||||
await db.put_sub_artefakt(topic, bnorm, "", "diagramm", daten, bt, "")
|
||||
|
||||
|
||||
async def _mirror_sidecar_db(topic: str, sidecar: dict) -> None:
|
||||
@@ -1912,7 +1895,7 @@ async def _mirror_frage_muster_db(topic: str, muster: dict) -> None:
|
||||
async def _reset_db_ab_phase(topic: str, label: str) -> None:
|
||||
"""DB-Inhalt der Phasen ≥ `label` verwerfen (kanonische Reihenfolge Quelle…Artefakte)."""
|
||||
idx = _phase_idx(label)
|
||||
if idx <= 8: # Artefakte (Karteikarten/Beispiele/Diagramme)
|
||||
if idx <= 8: # Artefakte (Karteikarten/Beispiele)
|
||||
await db.delete_sub_artefakte(topic)
|
||||
if idx <= 7: # Fragen
|
||||
await db.delete_frage_muster(topic)
|
||||
@@ -2119,7 +2102,7 @@ async def generate_bausteine(topic: str, instructions: str = "", provider: str =
|
||||
return # Abbruch
|
||||
atomic_write_json(files["frage_muster"], muster, indent=1)
|
||||
|
||||
# Block F: Lern-Artefakte (Karteikarten/Beispiele/Diagramme) aus den Fakten — Bonus,
|
||||
# Block F: Lern-Artefakte (Karteikarten/Beispiele) aus den Fakten — Bonus,
|
||||
# vom Frontend präsentiert. Bricht den Lauf nicht ab (Artefakte sind optional).
|
||||
sidecar = _json_datei(files["sidecar"])
|
||||
if _sidecar_schema(sidecar) is not None and not _artefakte_komplett(files):
|
||||
|
||||
@@ -182,7 +182,7 @@ CREATE TABLE IF NOT EXISTS guide_gliederung (
|
||||
"""
|
||||
|
||||
# Generischer Lern-Artefakt-Layer: je (Baustein, Subbaustein, Typ) ein Artefakt (JSON in `daten`).
|
||||
# typ: karteikarte | beispiel | diagramm. sub_norm='' = Baustein-Ebene (z. B. Diagramm).
|
||||
# typ: karteikarte | beispiel. sub_norm='' = Baustein-Ebene (für künftige Baustein-weite Artefakte).
|
||||
# In der Bausteine-Phase aus den Fakten erzeugt, vom Frontend präsentiert (Trennung Artefakt/Anzeige).
|
||||
CREATE_SUB_ARTEFAKTE = """
|
||||
CREATE TABLE IF NOT EXISTS sub_artefakte (
|
||||
@@ -1001,7 +1001,7 @@ async def delete_gliederung(topic: str) -> None:
|
||||
|
||||
async def put_sub_artefakt(topic: str, baustein_norm: str, sub_norm: str, typ: str,
|
||||
daten: str, baustein: str = "", sub_titel: str = "") -> None:
|
||||
"""Ein Lern-Artefakt (karteikarte/beispiel/diagramm) als JSON in `daten` speichern."""
|
||||
"""Ein Lern-Artefakt (karteikarte/beispiel) als JSON in `daten` speichern."""
|
||||
db = await get_db()
|
||||
await db.execute(
|
||||
"""INSERT INTO sub_artefakte (topic, baustein_norm, sub_norm, typ, baustein, sub_titel, daten, updated_at)
|
||||
|
||||
@@ -232,21 +232,18 @@ async def get_frage_muster(topic: str, baustein: str):
|
||||
|
||||
@router.get("/bausteine/artefakte")
|
||||
async def get_artefakte(topic: str, typ: str | None = None):
|
||||
"""Lern-Artefakte (Karteikarten/Beispiele/Diagramme) je Thema, gruppiert nach Baustein-Norm.
|
||||
Diagramm liegt auf Baustein-Ebene (sub_norm=''), Karteikarte/Beispiel je Subbaustein."""
|
||||
"""Lern-Artefakte (Karteikarten/Beispiele) je Thema, gruppiert nach Baustein-Norm — je Subbaustein."""
|
||||
rows = await get_sub_artefakte(topic, typ)
|
||||
out: dict[str, dict] = {}
|
||||
for r in rows:
|
||||
b = out.setdefault(r["baustein_norm"], {"baustein": r["baustein"], "karteikarte": [], "beispiel": [], "diagramm": None})
|
||||
b = out.setdefault(r["baustein_norm"], {"baustein": r["baustein"], "karteikarte": [], "beispiel": []})
|
||||
if r["baustein"] and not b["baustein"]:
|
||||
b["baustein"] = r["baustein"]
|
||||
try:
|
||||
daten = json.loads(r["daten"])
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
if r["typ"] == "diagramm":
|
||||
b["diagramm"] = daten
|
||||
elif r["typ"] in ("karteikarte", "beispiel"):
|
||||
if r["typ"] in ("karteikarte", "beispiel"):
|
||||
b[r["typ"]].append({"subbaustein": r["sub_titel"], **daten})
|
||||
return {"artefakte": out}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user