Lessons L-15 to L-19: route docs, form errors, tokens, tests, venv stamp
This commit is contained in:
@@ -426,3 +426,103 @@ Standing instruction from retoor, recorded as a clear rule:
|
||||
- Research grounds the choice (example: invite tokens use hash-only
|
||||
storage, single use and expiry per current security practice), it
|
||||
never replaces verification against the repo's own code and tests.
|
||||
|
||||
### L-2026-10-05-15: Every new route needs a docs_api registry entry
|
||||
|
||||
| Field | Value |
|
||||
|--------------|-------|
|
||||
| date | 2026-10-05 |
|
||||
| agent | muse-spark |
|
||||
| status | proposed |
|
||||
| dpp_template | no |
|
||||
| dpp_reason | proposed; Grok folds into template docs section |
|
||||
|
||||
The suite enforces documentation coverage:
|
||||
`test_every_product_route_is_documented` fails when any product route
|
||||
is missing from the `docs_api` registry, and
|
||||
`test_documented_auth_matches_reality` calls every registered probe
|
||||
path as anon, member and admin and asserts the declared auth holds.
|
||||
|
||||
Adding a route therefore means adding its registry entry in the same
|
||||
change: method, path, auth level, fields, sample, plus a safe probe
|
||||
path and body. Admin probes conventionally target an `unknown` id
|
||||
(404 for admins proves the route exists past the guard); public
|
||||
probes must answer anon with anything but 401 or 403.
|
||||
|
||||
### L-2026-10-05-16: New public POST forms need a validation_handler branch
|
||||
|
||||
| Field | Value |
|
||||
|--------------|-------|
|
||||
| date | 2026-10-05 |
|
||||
| agent | muse-spark |
|
||||
| status | proposed |
|
||||
| dpp_template | no |
|
||||
| dpp_reason | proposed; Grok folds into template forms section |
|
||||
|
||||
`RequestValidationError` on an HTML form post only re-renders the
|
||||
form for paths the `validation_handler` in `main.py` knows
|
||||
(`/auth/login`, `/join`, `/invite/...`). Any other path bounces the
|
||||
user to the referer with no error shown.
|
||||
|
||||
Every new public POST form needs its own branch that echoes the
|
||||
submitted values (never passwords) back into its template with the
|
||||
friendly messages, or the form silently eats validation errors.
|
||||
|
||||
### L-2026-10-05-17: Token features store hash only, single use, silent invalid
|
||||
|
||||
| Field | Value |
|
||||
|--------------|-------|
|
||||
| date | 2026-10-05 |
|
||||
| agent | muse-spark |
|
||||
| status | proposed |
|
||||
| dpp_template | no |
|
||||
| dpp_reason | proposed; Grok folds into template auth section |
|
||||
|
||||
The member-invite pattern is the template for future token features
|
||||
(password reset, email change, one-time links):
|
||||
|
||||
- Token from `secrets` with at least 128 bits; store SHA-256 only so
|
||||
a database read never yields a usable token.
|
||||
- Single use (`used_at`) plus expiry (`expires_at`, setting-backed).
|
||||
- One live token per subject; issuing revokes the previous.
|
||||
- Unknown, used, revoked and expired tokens answer identically, so
|
||||
links cannot be probed for state.
|
||||
- Bind the token to its subject where one exists (invite email).
|
||||
|
||||
### L-2026-10-05-18: Shared-DB API tests must not assert closed sets
|
||||
|
||||
| Field | Value |
|
||||
|--------------|-------|
|
||||
| date | 2026-10-05 |
|
||||
| agent | muse-spark |
|
||||
| status | proposed |
|
||||
| dpp_template | no |
|
||||
| dpp_reason | proposed; Grok folds into template test section |
|
||||
|
||||
API tests share one server database per session. A test that asserts
|
||||
an exact set of rows (observed: `/people` usernames equal to the two
|
||||
seeds) breaks the moment any other test legitimately adds rows
|
||||
through the product's own flows.
|
||||
|
||||
Assert intent instead: seeds present, ordering held, every row
|
||||
well-formed (username pattern, required fields). Closed-set
|
||||
assertions are only valid for tables no test ever extends.
|
||||
|
||||
### L-2026-10-05-19: Version bumps must not rebuild the venv
|
||||
|
||||
| Field | Value |
|
||||
|--------------|-------|
|
||||
| date | 2026-10-05 |
|
||||
| agent | muse-spark |
|
||||
| status | proposed |
|
||||
| dpp_template | no |
|
||||
| dpp_reason | proposed; Grok folds into template make section |
|
||||
|
||||
The Makefile venv stamp depends on `pyproject.toml`, so a
|
||||
version-only bump makes the next `make` target rebuild the whole
|
||||
virtualenv (observed: rebuild failed on a box whose system python
|
||||
has no `venv` module, blocking unrelated targets).
|
||||
|
||||
Workaround: `touch .venv/.stamp` when only the version changed.
|
||||
Durable fix for the template: key the stamp on dependency inputs,
|
||||
not on the version field.
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "molodetz"
|
||||
version = "1.0.18"
|
||||
version = "1.0.19"
|
||||
description = "Molodetz, a calm community blog roll."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
Reference in New Issue
Block a user