From 0c42cde4ff60c667126eb62d91e085cd80ca97fc Mon Sep 17 00:00:00 2001 From: Konrad du Plessis Date: Fri, 24 Apr 2026 00:38:52 +0200 Subject: [PATCH] fix(perf): CLAUDE.md runbook + drop dead var in cache-bust test Code-review followups on 16d4399: - CLAUDE.md's "When CSS changes don't appear" diagnostic steps were written for the old per-request token. Under mtime-based caching, a stable ?v= number is the healthy expected state, not a broken one. Rewrote steps 1 + 3 so someone debugging a real production CSS issue gets the right advice. - Dropped unused `original = cp._compute_cache_bust_token` line in test_token_falls_back_if_file_missing - it misled readers into thinking the function itself was patched. Added a one- line comment clarifying the monkey-patch is path-only. Tests: still 68/68. Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 5 +++-- core/tests.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9303c1e..b07ea06 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -265,9 +265,10 @@ that only a hard refresh in incognito temporarily fixed. Never use `request.time in templates — it doesn't exist. ### When CSS changes don't appear on production -1. Confirm Django is rendering the new URL: `curl -s https://foxlog.flatlogic.app/ | grep -oE 'custom\.css\?v=[^"]+'` — the `v=` number should change per request (or at least per restart) +1. Confirm Django is rendering a stable URL: `curl -s https://foxlog.flatlogic.app/ | grep -oE 'custom\.css\?v=[^"]+'` — run it twice; the `v=` number must be IDENTICAL across requests. Under the mtime-based token (see previous subsection), the number only changes after `static/css/custom.css` is edited. If it DOES change every request, the fallback branch of `_compute_cache_bust_token()` is active (the CSS file couldn't be stat'd) — check the file exists and is readable. 2. Confirm the CDN honours it: `curl -sI "https://foxlog.flatlogic.app/static/css/custom.css?cb=test$(date +%s)" | grep -i cache` — expect `cf-cache-status: MISS` then `HIT` on repeat -3. If the Django URL still looks like `?v=1.0` (constant), `deployment_timestamp` isn't being injected — check that `core.context_processors.project_context` is listed in `TEMPLATES[0]['OPTIONS']['context_processors']` in `config/settings.py` +3. If you've just deployed a CSS change and the old file is still showing: confirm `collectstatic` ran on the VM after pull (Flatlogic doesn't auto-run it). Without collectstatic, the mtime of the collected copy under `staticfiles/` stays the same, so the token doesn't bump and Cloudflare keeps serving the old file from its 4h edge cache. +4. If `deployment_timestamp` isn't being injected at all (the `?v=` query string is missing from the rendered URL): check that `core.context_processors.project_context` is listed in `TEMPLATES[0]['OPTIONS']['context_processors']` in `config/settings.py`. ### `collectstatic` is required after CSS/JS changes on production Flatlogic's rebuild does NOT automatically run `collectstatic`. If new CSS is on diff --git a/core/tests.py b/core/tests.py index 48b6c8d..0e4ad8b 100644 --- a/core/tests.py +++ b/core/tests.py @@ -1269,13 +1269,14 @@ class CacheBustTokenTests(TestCase): container pre-collectstatic), we must NOT crash. We fall back to int(time.time()) so every page still renders.""" import core.context_processors as cp - original = cp._compute_cache_bust_token try: # Monkey-patch so the function sees a guaranteed-missing path. + # (The function itself is not patched — only the path constant.) cp._CSS_PATH_FOR_TOKEN = cp.Path('/definitely/does/not/exist.css') # Should return an int and NOT raise. token = cp._compute_cache_bust_token() self.assertIsInstance(token, int) finally: - # Reset the module-level cache so other tests get the real value. + # Reset the module-level path constant so other tests (or reruns) + # get the real CSS file back. cp._CSS_PATH_FOR_TOKEN = cp.Path(settings.BASE_DIR) / 'static' / 'css' / 'custom.css'