retoor 874c37350b 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.
2026-10-05 15:55:35 +02:00

Molodetz

Blog roll of the Molodetz community. Quiet, serif, slightly provocative. Posts are markdown in SQLite, written by retoor through an admin area. Flyers and memes are galleries. Join is a real sign-up form ("I'm in"). The whole site is in English; the old Dutch paths (/rol, /standaard, /mensen, /binnen, /voorwaarden) redirect with 301.

Built to the frozen DPP template (/workspace/dpp/dptemplate.md). See SELECTION.md for the module choice and COMPLIANCE.md for the review.

Running

make install          # venv in .venv, pip install -e ".[dev]", Chromium, git hooks
cp .env.example .env  # only when there is no .env yet; chmod 600 .env
make dev              # http://127.0.0.1:8088, reload
make prod             # workers, pinned static version

make install needs a python3 with the venv module (Debian/Ubuntu ship it as python3-venv).

Without make:

.venv/bin/python -m uvicorn molodetz.main:app --host 127.0.0.1 --port 8088

The first start creates the administrator from MOLODETZ_ADMIN_USERNAME / MOLODETZ_ADMIN_EMAIL / MOLODETZ_ADMIN_PASSWORD in .env, seeds the placeholder posts once and syncs the gallery. A one-time migration (system.migrate.english) translates content seeded by older Dutch versions. Log in at /auth/login, admin at /admin.

Testing

make test         # unit + api + e2e (Playwright, headless)
make test-headed  # visible with slow motion
make check-ui     # six static gates + em-dash + json_error order
make preflight    # import, pyflakes, JS syntax, sqlglot lint, check-ui
make coverage
make locust-headless

Tests boot their own server on port 8099; set MOLODETZ_TEST_PORT to a free port when 8099 is taken. Browser tests wait up to 60 seconds per step and retry a stalled page load once via goto_ready in tests/conftest.py.

Docker

docker compose up -d --build                        # staging dev server on http://127.0.0.1:19847, reload on change
docker compose -f docker-compose.test.yml up -d     # public test server on http://127.0.0.1:19849
PROD_SECRET_KEY=... PROD_ADMIN_PASSWORD=... docker compose -f docker-compose.prod.yml up -d --build  # production on :19848
docker compose logs -f                              # follow logs
docker compose down                                 # stop

Each compose file is its own project (molodetz-dev, molodetz-test, molodetz-prod) with its own ./data/<env> file mount, so the three never interfere. Production secrets come only from PROD_SECRET_KEY / PROD_ADMIN_PASSWORD and refuse to boot without them; staging.app.molodetz.nl, molodetz-test.app.molodetz.nl, and molodetz.nl proxy to :19847, :19849, and :19848 (see molohttp_deploy.md).

The container runs the dev server (uvicorn --reload) with ./molodetz mounted, so every saved change is live within seconds. Data lives in the file mount ./data/staging (plain files, no named volumes anywhere). The admin account comes from MOLODETZ_ADMIN_USERNAME / MOLODETZ_ADMIN_EMAIL / MOLODETZ_ADMIN_PASSWORD (default password staging-admin-pass-1, override per shell); an empty password skips admin bootstrap. The compose port is fixed at 127.0.0.1:19847 and is what staging.app.molodetz.nl proxies to, so keep it stable.

make staging-refresh  # copy the holy prod database over staging, then verify

Refresh snapshots ./data/production (online backup API, production keeps running), integrity-checks the copy, stops staging, swaps the staging file mount content, restarts, and verifies health. After a refresh the staging admin password is the production one, so pass it to make screenshots-staging STAGING_ADMIN_PASSWORD=....

Screenshots

make screenshots                                                         # test gallery into ../static/pizdetz/test
make screenshots-staging                                                 # staging gallery into ../static/pizdetz/staging
make screenshots-production SCREENSHOTS_ADMIN_PASSWORD=...               # production gallery into ../static/pizdetz/production

Each run captures 32 full-page desktop shots (public, docs, admin) plus a 25-cell responsive matrix (home, roll, flyers, join, docs at 1440x900, 768x1024, 390x844, 360x740, 320x568) with a horizontal-overflow check per cell, then rebuilds the hub page at ../static/pizdetz/index.html from whichever environments exist on disk.

Rules, exactly: test always wipes ./data/test, boots its own server there, and seeds one join request; staging and production shoot a live base URL and never seed. Staging logs in with STAGING_ADMIN_PASSWORD (default staging-admin-pass-1, must match the compose admin password); production has no default and fails loudly without SCREENSHOTS_ADMIN_PASSWORD. Any overflow is reported and exits nonzero. Override the output root with SCREENSHOTS_DIR=....

CLI

molodetz --help: roles, API keys, posts list/import (.md and .pdf via pypdf), join requests, backups, prunes, sql-lint, emoji regenerate.

Data

All application data lives under ./data/<env>, enforced in code: molodetz/config.py refuses to start with a MOLODETZ_DATA_DIR outside ./data or a sqlite file outside the data dir.

  • development - local make dev runs (see .env)
  • staging - docker dev server on :19847 (file mount)
  • production - holy production database (file mount, docker prod on :19848)
  • test - screenshot runs, wiped at the start of every run
  • .tmp-pytest-<pid>, .tmp-locust - single test runs, removed afterwards

Each env dir holds molodetz.db (plus WAL files while running) and one subdirectory per kind: uploads (blobs, attachments), backups, keys, locks, seo_reports. The whole tree is git-ignored. Nothing else on the system holds application data; molodetz/static/js/generated/EmojiMap.js is a vendored build artifact the app only rewrites if missing.

Operations

Production serving runs through molohttp on this box. molohttp_deploy.md is the operator guide: access, file owners, the backup specification, site changes, and static publishing.

S
Description
Molodetz (Absurd Development) community blog roll, FastAPI on the DPP template
Readme
9.6 MiB
Languages
Python 74.7%
HTML 10.5%
JavaScript 7.7%
CSS 5.5%
Makefile 1%
Other 0.5%