From 874c37350bd4a8f7b231f858d4e2cadcec917eee Mon Sep 17 00:00:00 2001 From: retoor Date: Mon, 5 Oct 2026 15:55:35 +0200 Subject: [PATCH] Remove contributing and component docs from the public docs site Drop the Contributing and internals section, Architecture, Frontend, and dp-* component pages from the docs registry, prose files, nav, and legacy redirect target. Guard with tests that fail if they return. --- molodetz/docs_prose.py | 14 +-- molodetz/routers/legacy.py | 2 +- molodetz/templates/docs/prose/architecture.md | 18 ---- .../templates/docs/prose/component-avatar.md | 5 -- .../templates/docs/prose/component-chat.md | 5 -- .../templates/docs/prose/component-code.md | 5 -- .../templates/docs/prose/component-content.md | 5 -- .../docs/prose/component-context-menu.md | 5 -- .../templates/docs/prose/component-dialog.md | 5 -- .../docs/prose/component-lightbox.md | 5 -- .../templates/docs/prose/component-title.md | 5 -- .../templates/docs/prose/component-toast.md | 5 -- .../templates/docs/prose/component-upload.md | 5 -- molodetz/templates/docs/prose/frontend.md | 7 -- molodetz/templates/docs/prose/welcome.md | 2 +- pyproject.toml | 2 +- tests/api/docs/removed_internals.py | 87 +++++++++++++++++++ tests/api/legacy.py | 2 +- tests/e2e/index.py | 2 +- 19 files changed, 93 insertions(+), 93 deletions(-) delete mode 100644 molodetz/templates/docs/prose/architecture.md delete mode 100644 molodetz/templates/docs/prose/component-avatar.md delete mode 100644 molodetz/templates/docs/prose/component-chat.md delete mode 100644 molodetz/templates/docs/prose/component-code.md delete mode 100644 molodetz/templates/docs/prose/component-content.md delete mode 100644 molodetz/templates/docs/prose/component-context-menu.md delete mode 100644 molodetz/templates/docs/prose/component-dialog.md delete mode 100644 molodetz/templates/docs/prose/component-lightbox.md delete mode 100644 molodetz/templates/docs/prose/component-title.md delete mode 100644 molodetz/templates/docs/prose/component-toast.md delete mode 100644 molodetz/templates/docs/prose/component-upload.md delete mode 100644 molodetz/templates/docs/prose/frontend.md create mode 100644 tests/api/docs/removed_internals.py diff --git a/molodetz/docs_prose.py b/molodetz/docs_prose.py index 24c56bf..5776136 100644 --- a/molodetz/docs_prose.py +++ b/molodetz/docs_prose.py @@ -10,9 +10,7 @@ from molodetz.rendering import normalize_dashes PROSE_DIR = config.TEMPLATES_DIR / "docs" / "prose" -SECTIONS = ("Start here", "Building with the API", "Contributing and internals", "Admin") - -COMPONENTS = ("avatar", "code", "content", "title", "toast", "dialog", "context-menu", "upload", "lightbox", "chat") +SECTIONS = ("Start here", "Building with the API", "Admin") DOCS_PAGES = [ {"slug": "welcome", "title": "Welcome", "section": "Start here", "file": "welcome.md"}, @@ -20,18 +18,8 @@ DOCS_PAGES = [ {"slug": "join", "title": "Joining", "section": "Start here", "file": "join.md"}, {"slug": "legal", "title": "Terms and privacy", "section": "Start here", "file": "legal.md"}, {"slug": "api", "title": "API and authentication", "section": "Building with the API", "file": "api.md"}, - {"slug": "architecture", "title": "Architecture", "section": "Contributing and internals", "file": "architecture.md"}, - {"slug": "frontend", "title": "Frontend and components", "section": "Contributing and internals", "file": "frontend.md"}, {"slug": "admin", "title": "Admin and services", "section": "Admin", "file": "admin.md", "admin": True}, {"slug": "backups", "title": "Backups and maintenance", "section": "Admin", "file": "backups.md", "admin": True}, -] + [ - { - "slug": f"component-{name}", - "title": f"dp-{name}", - "section": "Contributing and internals", - "file": f"component-{name}.md", - } - for name in COMPONENTS ] diff --git a/molodetz/routers/legacy.py b/molodetz/routers/legacy.py index 6519abf..4befa68 100644 --- a/molodetz/routers/legacy.py +++ b/molodetz/routers/legacy.py @@ -14,7 +14,7 @@ LEGACY_PATHS = { "/docs/schrijven": "/docs/writing", "/docs/binnen": "/docs/join", "/docs/juridisch": "/docs/legal", - "/docs/architectuur": "/docs/architecture", + "/docs/architectuur": "/docs/welcome", "/docs/beheer": "/docs/admin", "/docs/api/inhoud": "/docs/api/content", "/docs/api/binnen": "/docs/api/join", diff --git a/molodetz/templates/docs/prose/architecture.md b/molodetz/templates/docs/prose/architecture.md deleted file mode 100644 index 922d31e..0000000 --- a/molodetz/templates/docs/prose/architecture.md +++ /dev/null @@ -1,18 +0,0 @@ -# Architecture - -FastAPI with Jinja2, rendered on the server. SQLite through `dataset`, synchronous and deliberately without a threadpool. Sessions with PBKDF2-SHA256 passwords. - -## Layers - -- `molodetz/database/`: one file per subject, always import from the package root. -- `molodetz/routers/`: mirrors the URL path. -- `molodetz/services/`: background services under one supervisor with a file lock. -- `molodetz/templates/`: one Jinja environment in `templating.py`. - -## Deleting - -Everything is soft deleted with `deleted_at` and `deleted_by`. Only cleanup jobs delete for real. - -## Static files - -Assets go through `static_url()`, which versions them under `/static/v/`. Those are immutably cacheable for a year. diff --git a/molodetz/templates/docs/prose/component-avatar.md b/molodetz/templates/docs/prose/component-avatar.md deleted file mode 100644 index 9f0845b..0000000 --- a/molodetz/templates/docs/prose/component-avatar.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-avatar - -Shows a deterministic SVG avatar plus a presence dot. Attributes `seed`, `size`, `uid`. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-chat.md b/molodetz/templates/docs/prose/component-chat.md deleted file mode 100644 index 792044c..0000000 --- a/molodetz/templates/docs/prose/component-chat.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-chat - -Simple log with an input line. Emits a `dp-chat-send` event. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-code.md b/molodetz/templates/docs/prose/component-code.md deleted file mode 100644 index 34f8d67..0000000 --- a/molodetz/templates/docs/prose/component-code.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-code - -Highlights a code block with highlight.js and adds a Copy button. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-content.md b/molodetz/templates/docs/prose/component-content.md deleted file mode 100644 index 5bbfd9f..0000000 --- a/molodetz/templates/docs/prose/component-content.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-content - -Renders live markdown on the client through marked, then DOMPurify. Only for live content, such as the editor preview. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-context-menu.md b/molodetz/templates/docs/prose/component-context-menu.md deleted file mode 100644 index ba47387..0000000 --- a/molodetz/templates/docs/prose/component-context-menu.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-context-menu - -Small context menu with buttons, positioned at the cursor. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-dialog.md b/molodetz/templates/docs/prose/component-dialog.md deleted file mode 100644 index b07cb1e..0000000 --- a/molodetz/templates/docs/prose/component-dialog.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-dialog - -Confirmation dialog. Forms with `data-confirm` go through it. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-lightbox.md b/molodetz/templates/docs/prose/component-lightbox.md deleted file mode 100644 index 002ab84..0000000 --- a/molodetz/templates/docs/prose/component-lightbox.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-lightbox - -Full screen view for images with `data-lightbox`. Escape or a click closes it. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-title.md b/molodetz/templates/docs/prose/component-title.md deleted file mode 100644 index f12184e..0000000 --- a/molodetz/templates/docs/prose/component-title.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-title - -Inline variant of dp-content for titles. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-toast.md b/molodetz/templates/docs/prose/component-toast.md deleted file mode 100644 index 2593a1c..0000000 --- a/molodetz/templates/docs/prose/component-toast.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-toast - -Host for short notices. Use `Toast.flash(el, message)` or `app.toast(message)`. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/component-upload.md b/molodetz/templates/docs/prose/component-upload.md deleted file mode 100644 index d27b2ac..0000000 --- a/molodetz/templates/docs/prose/component-upload.md +++ /dev/null @@ -1,5 +0,0 @@ -# dp-upload - -Drop zone for files. Emits a `dp-files` event with the chosen files. - -Light DOM, no shadow DOM. Registers itself with `customElements.define`. diff --git a/molodetz/templates/docs/prose/frontend.md b/molodetz/templates/docs/prose/frontend.md deleted file mode 100644 index ad65293..0000000 --- a/molodetz/templates/docs/prose/frontend.md +++ /dev/null @@ -1,7 +0,0 @@ -# Frontend and components - -ES6 modules, one class per file, no framework and no bundler. `Application.js` creates all singletons and sets `window.app`. - -Components are custom elements with the `dp-` prefix, without shadow DOM. See the component pages in the sidebar. - -Client rendering with marked and DOMPurify is only for live content: the preview in the editor. Published posts are rendered on the server. diff --git a/molodetz/templates/docs/prose/welcome.md b/molodetz/templates/docs/prose/welcome.md index 8f035c4..e99d7f5 100644 --- a/molodetz/templates/docs/prose/welcome.md +++ b/molodetz/templates/docs/prose/welcome.md @@ -12,4 +12,4 @@ Molodetz is a quiet blog roll. Notes about the work, finishing it, and judgement ## Where to start -Read [Writing on the roll](/docs/writing) for the content, [API and authentication](/docs/api) for integrations, and [Architecture](/docs/architecture) if you want to know how it is built. +Read [Writing on the roll](/docs/writing) for the content, and [API and authentication](/docs/api) for integrations. diff --git a/pyproject.toml b/pyproject.toml index 432a880..ba1bf1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "molodetz" -version = "1.0.15" +version = "1.0.16" description = "Molodetz, a calm community blog roll." readme = "README.md" requires-python = ">=3.12" diff --git a/tests/api/docs/removed_internals.py b/tests/api/docs/removed_internals.py new file mode 100644 index 0000000..3393c94 --- /dev/null +++ b/tests/api/docs/removed_internals.py @@ -0,0 +1,87 @@ +# retoor +import re + +from molodetz.docs_prose import DOCS_PAGES, PROSE_DIR, SECTIONS + +BANNED_SECTION = "Contributing and internals" +BANNED_TITLES = { + "Architecture", + "Frontend and components", + "dp-avatar", + "dp-code", + "dp-content", + "dp-title", + "dp-toast", + "dp-dialog", + "dp-context-menu", + "dp-upload", + "dp-lightbox", + "dp-chat", +} +BANNED_SLUGS = { + "architecture", + "frontend", + "component-avatar", + "component-code", + "component-content", + "component-title", + "component-toast", + "component-dialog", + "component-context-menu", + "component-upload", + "component-lightbox", + "component-chat", +} +BANNED_FILES = { + "architecture.md", + "frontend.md", + *[ + f"component-{name}.md" + for name in ( + "avatar", + "code", + "content", + "title", + "toast", + "dialog", + "context-menu", + "upload", + "lightbox", + "chat", + ) + ], +} + + +def _docs_surfaces(html): + sidebar = re.search(r'', html, re.S) + content = re.search(r'
(.*?)
', html, re.S) + return (sidebar.group(1) if sidebar else ""), (content.group(1) if content else "") + + +def test_docs_registry_excludes_removed_internals(): + assert BANNED_SECTION not in SECTIONS + titles = {page["title"] for page in DOCS_PAGES} + slugs = {page["slug"] for page in DOCS_PAGES} + sections = {page["section"] for page in DOCS_PAGES} + assert not titles & BANNED_TITLES + assert not slugs & BANNED_SLUGS + assert BANNED_SECTION not in sections + for name in BANNED_FILES: + assert not (PROSE_DIR / name).exists(), name + + +def test_served_docs_hide_removed_internals(anon, admin): + banned_hrefs = {f"/docs/{slug}" for slug in BANNED_SLUGS} + for client in (anon, admin): + for path in ("/docs", "/docs/welcome", "/docs/api"): + html = client.get(path).text + sidebar, content = _docs_surfaces(html) + surface = f"{sidebar}\n{content}" + assert BANNED_SECTION not in surface, path + for title in BANNED_TITLES: + assert title not in surface, (path, title) + for href in banned_hrefs: + assert href not in surface, (path, href) + for slug in sorted(BANNED_SLUGS): + assert anon.get(f"/docs/{slug}").status_code == 404, slug diff --git a/tests/api/legacy.py b/tests/api/legacy.py index ac34486..258714c 100644 --- a/tests/api/legacy.py +++ b/tests/api/legacy.py @@ -14,7 +14,7 @@ REDIRECTS = [ ("/docs/schrijven", "/docs/writing"), ("/docs/binnen", "/docs/join"), ("/docs/juridisch", "/docs/legal"), - ("/docs/architectuur", "/docs/architecture"), + ("/docs/architectuur", "/docs/welcome"), ("/docs/api/inhoud", "/docs/api/content"), ("/docs/api/binnen", "/docs/api/join"), ] diff --git a/tests/e2e/index.py b/tests/e2e/index.py index 3792be0..8ee3694 100644 --- a/tests/e2e/index.py +++ b/tests/e2e/index.py @@ -1,7 +1,7 @@ # retoor from tests.conftest import assert_no_horizontal_overflow, goto_ready -PUBLIC_PAGES = ["/", "/roll", "/standard", "/flyers", "/memes", "/people", "/people/retoor", "/join", "/docs", "/docs/welcome", "/docs/api/content", "/docs/component-code", "/terms", "/privacy"] +PUBLIC_PAGES = ["/", "/roll", "/standard", "/flyers", "/memes", "/people", "/people/retoor", "/join", "/docs", "/docs/welcome", "/docs/api/content", "/terms", "/privacy"] def test_home_renders_without_errors(page, app_server):