From e06be9d50adadb764bde985d4f07a81703806aeb Mon Sep 17 00:00:00 2001 From: team3 Date: Mon, 12 Oct 2026 16:02:57 +0200 Subject: [PATCH] =?UTF-8?q?Stopp=20nach=20der=20Gliederung=20als=20H=C3=A4?= =?UTF-8?q?kchen=20neben=20=E2=80=9EBuch=20erzeugen=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Das Häkchen steht im Lauf neben dem Startknopf und bei „Neue Version“ neben „Buch erzeugen“, nicht mehr im Anlegen-Formular. Es wird mit dem Start gespeichert und ist sichtbar, solange die Gliederung aussteht. Co-Authored-By: Claude Fable 5.1 --- API.md | 3 +-- backend/main.py | 14 ++++++++++---- backend/state.py | 4 ++-- frontend/src/App.vue | 7 ++----- frontend/src/api.js | 4 ++-- frontend/src/components/Lauf.vue | 13 ++++++++----- frontend/src/style.css | 2 +- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/API.md b/API.md index c04eee6..a832cb9 100644 --- a/API.md +++ b/API.md @@ -17,12 +17,11 @@ Ohne `v2` gilt die neueste Version. - `POST /api/themen` `{name, hinweise, spezialisierung}` → Thema wie oben (legt `v1` an) – `name`: Hauptthema; `spezialisierung`: grenzt es ein, nur was dafür gebraucht wird; die Bezeichnung (`name` in der Antwort, Ordner) wird „Thema – Spezialisierung“ – `hinweise`: wie das Thema zu verstehen ist; gelten je Version und sind bei einer neuen Version änderbar - – `stopp_gliederung` (bool, optional): der Lauf hält nach der Gliederung an (`pausiert`); „Fortsetzen“ schreibt die Kapitel - `GET /api/themen/{slug}` → Thema wie oben - `DELETE /api/themen/{slug}` – ganzes Thema - `POST /api/themen/{slug}/versionen` `{hinweise?, stopp_gliederung?}` → `{"v": N}` – nächste Version ohne Start; ohne Angabe übernimmt sie die Hinweise der neuesten Version - `DELETE /api/themen/{slug}/v{N}` – nur diese Version -- `POST /api/themen/{slug}/v{N}/start` – startet oder setzt fort (resümiert an der offenen Stufe) +- `POST /api/themen/{slug}/v{N}/start` `{stopp_gliederung?}` – startet oder setzt fort (resümiert an der offenen Stufe); `stopp_gliederung: true` hält nach der Gliederung als `pausiert` an, „Fortsetzen“ schreibt die Kapitel - `POST /api/themen/{slug}/v{N}/pause` – bricht laufende Agenten ab; Neustart mit `start` - `POST /api/themen/{slug}/v{N}/reset` – löscht alles in der Version außer dem Zustand „neu“ - `GET|PUT /api/themen/{slug}/v{N}/position` – Leseposition `{abschnitt, lesemodus}` diff --git a/backend/main.py b/backend/main.py index 41496c3..78b5f9b 100644 --- a/backend/main.py +++ b/backend/main.py @@ -30,7 +30,6 @@ class ThemaNeu(BaseModel): name: str hinweise: str = "" spezialisierung: str = "" - stopp_gliederung: bool = False class VersionNeu(BaseModel): @@ -38,6 +37,10 @@ class VersionNeu(BaseModel): stopp_gliederung: bool = False +class Start(BaseModel): + stopp_gliederung: bool | None = None # None: wie gespeichert + + class Position(BaseModel): abschnitt: str | None = None lesemodus: str | int | None = None # neu: key des Bildschirms, alt: Index @@ -91,7 +94,7 @@ async def thema_anlegen(body: ThemaNeu): if not state.name_ok(name) or not state.name_ok(state.bezeichnung(name, body.spezialisierung.strip())): raise HTTPException(400, "Ungültiger Name") try: - return _thema_info(state.anlegen(name, body.hinweise, body.spezialisierung, body.stopp_gliederung)) + return _thema_info(state.anlegen(name, body.hinweise, body.spezialisierung)) except ValueError as e: raise HTTPException(409, str(e)) @@ -137,10 +140,13 @@ async def version_loeschen(slug: str, n: int): @app.post("/api/themen/{slug}/v{n}/start") -async def start(slug: str, n: int): +async def start(slug: str, n: int, body: Start | None = None): key = _key(slug, n) - if state.zustand(key)["status"] == "fertig": + st = state.zustand(key) + if st["status"] == "fertig": raise HTTPException(400, "Lauf ist fertig – erst zurücksetzen") + if body and body.stopp_gliederung is not None: + st["stopp_gliederung"] = body.stopp_gliederung pipeline.starten(key) return {"ok": True} diff --git a/backend/state.py b/backend/state.py index 691b7ef..d903904 100644 --- a/backend/state.py +++ b/backend/state.py @@ -139,7 +139,7 @@ def themen() -> list[dict]: return aus -def anlegen(name: str, hinweise: str, spezialisierung: str = "", stopp_gliederung: bool = False) -> dict: +def anlegen(name: str, hinweise: str, spezialisierung: str = "") -> dict: """name ist das Hauptthema („Game Design“), die Spezialisierung grenzt es ein; beides zusammen bildet die Bezeichnung.""" spezialisierung = spezialisierung.strip() bez = bezeichnung(name, spezialisierung) @@ -150,7 +150,7 @@ def anlegen(name: str, hinweise: str, spezialisierung: str = "", stopp_gliederun t = {"name": bez, "thema": name, "spezialisierung": spezialisierung, "slug": slug_frei(bez), "titel": bez, "hinweise": hinweise.strip(), "angelegt": jetzt()} _schreiben(d / "thema.json", t) - version_anlegen(bez, stopp_gliederung=stopp_gliederung) + version_anlegen(bez) return t diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 8018cab..6503e34 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -36,7 +36,6 @@ const fehler = ref('') const neuName = ref('') const neuHinweise = ref('') const neuSpezialisierung = ref('') -const neuStopp = ref(false) const navAuf = ref(false) let timer = null @@ -106,11 +105,10 @@ async function anlegen() { const name = neuName.value.trim() if (!name) return try { - const t = await api.anlegen(name, neuHinweise.value.trim(), neuSpezialisierung.value.trim(), neuStopp.value) + const t = await api.anlegen(name, neuHinweise.value.trim(), neuSpezialisierung.value.trim()) neuName.value = '' neuHinweise.value = '' neuSpezialisierung.value = '' - neuStopp.value = false await topicsLaden() themaWaehlen(t.slug) } catch (e) { fehler.value = String(e.message || e) } @@ -175,7 +173,6 @@ function tokens(n) { return n >= 1e6 ? (n / 1e6).toFixed(1) + 'M' : n >= 1e3 ? M - @@ -202,7 +199,7 @@ function tokens(n) { return n >= 1e6 ? (n / 1e6).toFixed(1) + 'M' : n >= 1e3 ? M
{{ fehler }} — klicken zum Schließen
diff --git a/frontend/src/api.js b/frontend/src/api.js index fb35825..429ce97 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -18,12 +18,12 @@ const e = encodeURIComponent const v = (slug, n) => `/themen/${e(slug)}/v${n}` export const api = { themen: () => req('/themen'), - anlegen: (name, hinweise = '', spezialisierung = '', stopp_gliederung = false) => req('/themen', { method: 'POST', body: { name, hinweise, spezialisierung, stopp_gliederung } }), + anlegen: (name, hinweise = '', spezialisierung = '') => req('/themen', { method: 'POST', body: { name, hinweise, spezialisierung } }), loeschen: (slug) => req(`/themen/${e(slug)}`, { method: 'DELETE' }), versionAnlegen: (slug, eingaben) => req(`/themen/${e(slug)}/versionen`, { method: 'POST', body: eingaben }), versionLoeschen: (slug, n) => req(v(slug, n), { method: 'DELETE' }), state: (slug, n) => req(v(slug, n)), - start: (slug, n) => req(v(slug, n) + '/start', { method: 'POST' }), + start: (slug, n, body) => req(v(slug, n) + '/start', { method: 'POST', body }), pause: (slug, n) => req(v(slug, n) + '/pause', { method: 'POST' }), reset: (slug, n) => req(v(slug, n) + '/reset', { method: 'POST' }), buch: (slug, n) => req(v(slug, n) + '/buch'), diff --git a/frontend/src/components/Lauf.vue b/frontend/src/components/Lauf.vue index 8d2716d..01ff85e 100644 --- a/frontend/src/components/Lauf.vue +++ b/frontend/src/components/Lauf.vue @@ -1,5 +1,5 @@