Pablan, as it stands

Self-hosted knowledge management for SMEs: a split-screen Markdown editor
whose sections an LLM refines while you write, and RAG question answering
over the documents that result. FastAPI + Postgres/pgvector on the back,
SvelteKit on the front, everything OpenAI-compatible and self-hostable.

Squashed into a single commit; the development history stays local.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CA43ZJda8Rbp2hKXNy8f6b
This commit is contained in:
ProfessorNova
2026-09-04 09:21:37 +02:00
co-authored by Claude Opus 5
parent 68d3a43191
commit 784b76baf7
346 changed files with 43430 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
from app.rag.chunking import TARGET_CHUNK_CHARS, chunk_markdown
def test_heading_paths_follow_hierarchy() -> None:
md = (
"Intro before any heading.\n\n"
"## Wartung\n\nWöchentlich schmieren.\n\n"
"### Schmierstoffe\n\nNur GX-220 verwenden.\n\n"
"## Sicherheit\n\nLichtvorhang nie überbrücken.\n"
)
chunks = chunk_markdown(md, "Maschinenhandbuch")
paths = [chunk.heading_path for chunk in chunks]
assert paths == [
"Maschinenhandbuch",
"Maschinenhandbuch Wartung",
"Maschinenhandbuch Wartung Schmierstoffe",
"Maschinenhandbuch Sicherheit",
]
assert "GX-220" in chunks[2].content
def test_leading_h1_equal_to_title_is_not_duplicated() -> None:
md = "# Handbuch\n\nText direkt unter dem Titel.\n\n## Details\n\nMehr.\n"
chunks = chunk_markdown(md, "Handbuch")
assert chunks[0].heading_path == "Handbuch"
assert chunks[1].heading_path == "Handbuch Details"
def test_oversized_section_is_split_at_paragraphs() -> None:
paragraph = "Absatz mit ausreichend vielen Wörtern für den Test. " * 20
md = "## Lang\n\n" + "\n\n".join([paragraph] * 5)
chunks = chunk_markdown(md, "Doc")
assert len(chunks) > 1
assert all(len(chunk.content) <= TARGET_CHUNK_CHARS + 100 for chunk in chunks)
assert all(chunk.heading_path == "Doc Lang" for chunk in chunks)
def test_code_fences_are_never_split() -> None:
fence = "```\n" + "\n\n".join(["zeile eins", "zeile zwei", "zeile drei"]) + "\n```"
filler = "Wort " * 500
md = f"## Code\n\n{filler}\n\n{fence}\n\n{filler}"
chunks = chunk_markdown(md, "Doc")
fenced = [chunk for chunk in chunks if "```" in chunk.content]
for chunk in fenced:
assert chunk.content.count("```") % 2 == 0, "chunk split inside a fence"
def test_heading_inside_fence_is_not_a_section() -> None:
md = "## Skript\n\n```\n# kein heading, nur ein Kommentar\necho hi\n```\n"
chunks = chunk_markdown(md, "Doc")
assert len(chunks) == 1
assert chunks[0].heading_path == "Doc Skript"
def test_empty_document_yields_no_chunks() -> None:
assert chunk_markdown("", "Leer") == []
assert chunk_markdown("\n\n \n", "Leer") == []