This commit is contained in:
team3
2026-07-03 12:50:32 +02:00
parent 9754cbcfae
commit 91b0d00aa1
27 changed files with 203 additions and 580 deletions

View File

@@ -18,15 +18,6 @@ CREATE TABLE IF NOT EXISTS guides (
)
"""
CREATE_PROGRESS = """
CREATE TABLE IF NOT EXISTS guide_progress (
guide_id TEXT NOT NULL,
chapter TEXT NOT NULL,
created_at TEXT NOT NULL,
PRIMARY KEY (guide_id, chapter)
)
"""
CREATE_TOPICS = """
CREATE TABLE IF NOT EXISTS topics (
name TEXT PRIMARY KEY,
@@ -34,18 +25,6 @@ CREATE TABLE IF NOT EXISTS topics (
)
"""
CREATE_BLOCK_TEXTE = """
CREATE TABLE IF NOT EXISTS block_texte (
topic TEXT NOT NULL,
block TEXT NOT NULL,
kind TEXT NOT NULL,
md TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
PRIMARY KEY (topic, block, kind)
)
"""
CREATE_BLOCK_PROGRESS = """
CREATE TABLE IF NOT EXISTS block_progress (
topic TEXT NOT NULL,
@@ -308,9 +287,7 @@ async def init_db():
await db.execute("PRAGMA synchronous=NORMAL")
await db.execute("PRAGMA busy_timeout=5000")
await db.execute(CREATE_GUIDES)
await db.execute(CREATE_PROGRESS)
await db.execute(CREATE_TOPICS)
await db.execute(CREATE_BLOCK_TEXTE)
await db.execute(CREATE_BLOCK_PROGRESS)
await db.execute(CREATE_BLOCKS)
await db.execute(CREATE_SUBBLOCKS)
@@ -370,16 +347,13 @@ async def init_db():
await db.execute("ALTER TABLE blocks ADD COLUMN reader TEXT NOT NULL DEFAULT '[]'")
except aiosqlite.OperationalError:
pass
# Migration: old vertiefungen table → block_texte (existing = long form, kind 'deepdive')
cursor = await db.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'vertiefungen'")
if await cursor.fetchone():
await db.execute(
"INSERT OR IGNORE INTO block_texte (topic, block, kind, md, created_at, updated_at) "
"SELECT topic, block, 'deepdive', md, created_at, updated_at FROM vertiefungen"
)
await db.execute("DROP TABLE vertiefungen")
# Migration: the elements feature was removed entirely — drop its orphaned table.
# Migration: removed features leave orphaned tables behind — drop them.
# elements (feature removed), vertiefungen/block_texte (never read), guide_progress
# (chapter progress had no frontend and its only reader ignored the value).
await db.execute("DROP TABLE IF EXISTS elements")
await db.execute("DROP TABLE IF EXISTS vertiefungen")
await db.execute("DROP TABLE IF EXISTS block_texte")
await db.execute("DROP TABLE IF EXISTS guide_progress")
await db.execute(
"UPDATE guides SET status = 'error', progress = NULL, error_msg = 'Server restart' "
"WHERE status IN ('queued', 'generating')"
@@ -473,49 +447,6 @@ async def delete_topic(name: str) -> None:
await db.commit()
# --- Chapter progress ---
async def list_progress_all() -> dict[str, set[str]]:
"""Complete chapter progress in one query: guide_id → chapter title."""
db = await get_db()
cursor = await db.execute("SELECT guide_id, chapter FROM guide_progress")
rows = await cursor.fetchall()
out: dict[str, set[str]] = {}
for guide_id, chapter in rows:
out.setdefault(guide_id, set()).add(chapter)
return out
async def list_progress(guide_id: str) -> list[str]:
db = await get_db()
cursor = await db.execute(
"SELECT chapter FROM guide_progress WHERE guide_id = ?", (guide_id,)
)
rows = await cursor.fetchall()
return [row[0] for row in rows]
async def set_progress(guide_id: str, chapter: str, done: bool) -> None:
from datetime import datetime, timezone
db = await get_db()
if done:
await db.execute(
"INSERT OR IGNORE INTO guide_progress (guide_id, chapter, created_at) VALUES (?, ?, ?)",
(guide_id, chapter, datetime.now(timezone.utc).isoformat()),
)
else:
await db.execute(
"DELETE FROM guide_progress WHERE guide_id = ? AND chapter = ?", (guide_id, chapter)
)
await db.commit()
async def delete_progress(guide_id: str) -> None:
db = await get_db()
await db.execute("DELETE FROM guide_progress WHERE guide_id = ?", (guide_id,))
await db.commit()
# --- Block learning: deep-dives + exam progress ---
def _now() -> str:
@@ -667,7 +598,6 @@ async def list_block_scores_all() -> list[tuple[str, str, int]]:
async def delete_block_data(topic: str) -> None:
db = await get_db()
await db.execute("DELETE FROM block_texte WHERE topic = ?", (topic,))
await db.execute("DELETE FROM block_progress WHERE topic = ?", (topic,))
await db.commit()
@@ -984,14 +914,6 @@ async def kanban_members_of(topic: str, group_id: str) -> list[str]:
return [r[0] for r in await cursor.fetchall()]
async def kanban_member_group(topic: str, member_id: str) -> str | None:
db = await get_db()
cursor = await db.execute(
"SELECT group_id FROM kanban_members WHERE topic = ? AND member_id = ?", (topic, member_id))
row = await cursor.fetchone()
return row[0] if row else None
# ── Guide board (one card per block, linear stages) ──────────────────────────────
async def upsert_guide_card(topic: str, format: str, block_norm: str, block: str,
stage: str = "lernziele") -> None:
@@ -1277,13 +1199,6 @@ async def mark_sources_read_done(topic: str, sources: list[str]) -> None:
await db.commit()
async def list_coverage(topic: str) -> dict[str, int]:
db = await get_db()
cursor = await db.execute("SELECT source, read_done FROM research_coverage WHERE topic = ?", (topic,))
rows = await cursor.fetchall()
return {q: g for q, g in rows}
async def mark_content(topic: str, content: list[str], noise: list[str]) -> None:
"""Store the triage result per crawl page: content=1 (content) or 0 (noise)."""
db = await get_db()
@@ -1335,16 +1250,6 @@ async def get_step_status(topic: str, step: str) -> str:
async def delete_pipeline_state(topic: str, steps: list[str] | None = None) -> None:
db = await get_db()
if steps is None:
await db.execute("DELETE FROM pipeline_state WHERE topic = ?", (topic,))
elif steps:
marks = ",".join("?" for _ in steps)
await db.execute(f"DELETE FROM pipeline_state WHERE topic = ? AND step IN ({marks})", (topic, *steps))
await db.commit()