Skip to content

Commit f418714

Browse files
tom-cloydclaude
andcommitted
Move the build note into the version line, drop its standalone box
The "NEW VERSION NOTE" box that appeared above the Welcome heading whenever no update was pending duplicated the version-line information and stuck around persistently after every update. It's gone now — the always-visible "Current version date" line carries the note in parentheses instead, so it only ever needs one home. Also documents the home page's status lines and update-check timing in a new user-manual.md tour section (Part 3.A) and a fuller technical writeup in README-numa-documentation.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent dda0ac1 commit f418714

5 files changed

Lines changed: 44 additions & 28 deletions

File tree

README-numa-documentation.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A nutritional analysis web app written in Python (FastAPI). Analyzes individual food portions, recipes, and complete meals using data pooled from six nutrition databases — USDA FoodData Central, Open Food Facts, the Canadian Nutrient File, and the UK CoFID, Australian AFCD, and French CIQUAL static datasets. The program presents itself to users as **NutriMagnus ("nutrition wizard")**.
44

5-
UPDATED: 2026-08-30:1043
5+
UPDATED: 2026-08-31:2157
66

77
Last monthly accuracy check: 2026-08-30.
88

@@ -1072,6 +1072,14 @@ The navbar marks the active section by comparing `request.url.path` to each nav
10721072

10731073
Renders the content of `home.md` (project root) as HTML. The markdown file is rendered once at startup and cached in `web/home_body.cache`; the cache is invalidated if `home.md` is newer.
10741074

1075+
**Status lines below the Welcome heading.** Three lines, `<br>`-separated inside one `<p class="muted mb-0"><small>` block: dietary preference, active profile, and `Current version date: {{ version_date }}``version_date` is `index()`'s full `VERSION` string (`web/backend.py`), i.e. the `yyyy-mm-dd:hhmm` stamp from `version.py`, not just its date portion. Whenever `NEW_VERSION_NOTE` (`version.py`) is non-empty it's appended in parentheses on that same line as `(Version note: {{ version_note }})`. This is the only place the build note shows when no update is available — there is no separate standalone box for it (there used to be; removed since it duplicated the same information already on this line).
1076+
1077+
**Update-check flow.** `index()` calls `_update_check.check_for_update(VERSION)` (`numa_app/services/update_check.py`) on every load of `/` — launch, manual reload, or navigating back to Home from elsewhere — except immediately after a successful in-place update (`updated=1` query param), since the running process's in-memory `VERSION` is still stale until relaunch. `check_for_update()` compares the tag-ified current version against GitHub's latest-release tag via plain string comparison (safe because `VERSION` is a fixed-width, lexically-sortable stamp) and returns `{"tag": ..., "url": ...}` or `None`; it never raises, so a network failure or offline state is silently treated as "no update." Its own module-level cache (`_CACHE_TTL_SECONDS = 6 * 60 * 60`) means repeated home-page loads within a 6-hour window reuse the last GitHub response rather than making a fresh call each time; the cache key includes the version string, so it self-invalidates the moment `VERSION` changes (e.g. right after a self-update).
1078+
1079+
**Notification-frequency gate.** Even when `check_for_update()` reports a real update, `index()` only lets the **UPDATE AVAILABLE** banner through if `_should_show_update_notice()` (`web/backend.py`) says so — otherwise it sets `update_available = None` before rendering, same as the post-update suppression case. That helper reads the saved `update_notify_frequency` pref (`"daily"` / `"weekly"` / `"monthly"`, default `"daily"`, validated against `_VALID_UPDATE_NOTIFY_FREQS`) and an `update_notice_last_shown_at` ISO date, both in `prefs.json`; if fewer days than the frequency's interval (`_UPDATE_NOTIFY_FREQ_DAYS`: 1/7/30) have elapsed since the last time the banner was shown, it returns `False` without touching `prefs.json`. Otherwise it stamps today's date into `update_notice_last_shown_at` and returns `True`. This is a display throttle only — it never affects the 6-hour network-cache TTL above, which keeps polling GitHub at its own fixed cadence regardless of the user's notification preference. The setting itself lives in Settings → "Update Notifications" (`settings.html`, `POST /settings/update-notify-frequency`), following the same radio-button/`prefs.json` pattern as the Dietary Preferences section (`diet_pref`).
1080+
1081+
**When the banner does show**, its build-note line also names the current frequency setting in a muted aside with a link to `/settings#update-notifications`, so the note doubles as a reminder of how often you've asked to be told.
1082+
10751083
#### `search.html`
10761084

10771085
Food search results. Shows a results table with food name, data type, brand, and source badge (`pantry` / `cache` / `recipe` / `usda` / `off`). Each row links to `/food/{fdc_id}`. Used for both the Foods → Search page and as a reusable search partial.

tests/test_web.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,25 +1871,24 @@ def test_home_page_shows_db_integrity_banner(client: TestClient, cached_food, db
18711871

18721872
def test_home_page_shows_version_note_prominently(client: TestClient) -> None:
18731873
"""version_note (version.py's NEW_VERSION_NOTE) describes what changed
1874-
in the build you're actually running — it needs to be somewhere a user
1875-
will see it, not just in the fine print at the very bottom."""
1874+
in the build you're actually running — with no update pending, it shows
1875+
in parentheses next to the "Current version date" line below Welcome,
1876+
not just in the fine print at the very bottom, and not in a standalone
1877+
box of its own."""
18761878
from version import NEW_VERSION_NOTE
18771879

18781880
resp = client.get("/")
18791881
assert NEW_VERSION_NOTE in resp.text
1880-
# The note appears in its own prominent box, ahead of the "Welcome to
1881-
# NutriMagnus" heading — not only in the small print at the page foot.
1882-
note_pos = resp.text.index(NEW_VERSION_NOTE)
1883-
welcome_pos = resp.text.index("Welcome to NutriMagnus")
1884-
assert note_pos < welcome_pos
1885-
assert f"NEW VERSION NOTE: {NEW_VERSION_NOTE}" in resp.text
1882+
assert f"(Version note: {NEW_VERSION_NOTE})" in resp.text
1883+
assert "alert-secondary" not in resp.text
1884+
assert "NEW VERSION NOTE:" not in resp.text
18861885

18871886

18881887
def test_version_note_sits_inside_update_available_banner(client: TestClient, monkeypatch: pytest.MonkeyPatch) -> None:
18891888
"""When there's an update available, NEW_VERSION_NOTE appears inside
18901889
that same alert box, directly below the first line — not as a separate
1891-
box, and not repeated in the always-visible "Current version date" line
1892-
below the Welcome heading (that line shows only the date, not the note)."""
1890+
box. It also appears a second time, in parentheses on the always-visible
1891+
"Current version date" line below the Welcome heading."""
18931892
from numa_app.services import update_check as _update_check
18941893
from version import NEW_VERSION_NOTE
18951894

@@ -1898,9 +1897,9 @@ def test_version_note_sits_inside_update_available_banner(client: TestClient, mo
18981897
lambda *a, **kw: {"tag": "v2099-01-01-0000", "url": "https://github.com/tom-cloyd/NutriMagnus/releases/tag/v2099-01-01-0000"},
18991898
)
19001899
resp = client.get("/")
1901-
assert resp.text.count(NEW_VERSION_NOTE) == 1
1900+
assert resp.text.count(NEW_VERSION_NOTE) == 2
19021901
assert f"NEW VERSION NOTE: {NEW_VERSION_NOTE}" in resp.text
1903-
assert f"Current version date:" in resp.text
1902+
assert f"(Version note: {NEW_VERSION_NOTE})" in resp.text
19041903
update_banner_pos = resp.text.index("UPDATE AVAILABLE:")
19051904
note_pos = resp.text.index(NEW_VERSION_NOTE)
19061905
welcome_pos = resp.text.index("Welcome to NutriMagnus")

user-manual.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# NutriMagnus User Manual
22

3-
*Updated 2026-08-31:2135* / Reading time: 4 hours, 24 minutes
3+
*Updated 2026-08-31:2157* / Reading time: 4 hours, 25 minutes
44

55
*Last full audit: 2026-08-30*
66

@@ -259,6 +259,18 @@ NuMa's web app runs in your ordinary browser. This makes program development, wh
259259

260260
Launch NuMa the way it was set up on your computer — a desktop icon, an Applications-menu entry, or a shortcut someone set up for you. It opens automatically in your browser, normally at a browser address like `http://127.0.0.1:8000` — this just means "this computer, talking to itself," not an address on the internet, so don't worry if the exact numbers you see differ. If the page doesn't load right away, wait a few seconds and reload — the program is still starting up.
261261

262+
#### What you see on the home page {: #home-page-tour}
263+
264+
Right below the **Welcome to NutriMagnus** heading is a small block of status lines:
265+
266+
- **Dietary preferences** — your current setting (e.g. "All animal foods"), with a link straight to Settings to change it.
267+
- **Active profile** — a one-line summary of your profile (age, sex, weight, height, activity level), or "not set" with a link to configure one if you haven't yet.
268+
- **Current version date** — the exact build you're running, as `yyyy-mm-dd:hhmm`. Whenever `version.py`'s build note is set, it follows in parentheses as "(Version note: ...)" — a short plain-language description of what changed in that build.
269+
270+
Above all of that, a few one-time or conditional banners can appear when relevant: a database-integrity warning, an "update installed" confirmation right after using Update Now, an update-failed message, and an **UPDATE AVAILABLE** banner when a newer release exists on GitHub (with an **Update Now** button if you're running the packaged Linux install, otherwise a plain link to what's new). That banner repeats the build note as its own line, plus a note on how often you're being notified about new releases and a link to change that in **Settings → Update Notifications** (daily, weekly, or monthly — daily by default).
271+
272+
**When does NuMa actually check for a new release?** Every time the home page loads — at launch, on a manual reload, or by navigating back to it from anywhere else in the program — it asks whether a newer version exists. That check itself is cached for a few hours, so bouncing back to the home page repeatedly doesn't re-contact GitHub every time; it just reuses the last answer until the cache expires. Separately, even when a newer version genuinely is available, whether the **UPDATE AVAILABLE** banner is actually shown to you on a given visit is throttled again by your daily/weekly/monthly notification-frequency setting — so you won't see it more often than you asked to.
273+
262274
### B. Finding your way around
263275

264276
Every page has the same navigation bar across the top: **NuMa** (takes you home), **Foods**, **Recipes**, **Meals & Log**, **Analysis**, **Settings**, and **Manual** (this document). **Foods** and **Analysis** open as drop-down menus with several choices each; the others go straight to their page.
@@ -477,7 +489,7 @@ If you'd rather fix the underlying recipe yourself instead of using Retry, re-ed
477489

478490
A one-time banner also appears on the home page whenever there's a System Issues entry you haven't seen yet, with a **Got it. Don't remind me again.** checkbox — checking it hides the banner (the entry still stays listed under Settings until it's actually resolved), and any *new* failure after that brings the banner back.
479491

480-
**The home page also checks GitHub for a newer NuMa release**, showing an **UPDATE AVAILABLE** banner with a link to what's new if one exists. This check is quick (a couple of seconds at most) and fails silently if you're offline or GitHub is unreachable — it never blocks the home page from loading. A short plain-language note about what changed in your current build, labeled **NEW VERSION NOTE:** (e.g. "NEW VERSION NOTE: minor problem fixes"), always appears near the top of the home page in its own light box — directly below the UPDATE AVAILABLE banner when one is showing — whether or not an update is available. The bare version number also stays in the small print at the very bottom, for reference.
492+
**The home page also checks GitHub for a newer NuMa release**, showing an **UPDATE AVAILABLE** banner with a link to what's new if one exists. This check is quick (a couple of seconds at most) and fails silently if you're offline or GitHub is unreachable — it never blocks the home page from loading. See [What you see on the home page](#home-page-tour) for exactly where the current build's version stamp and build note appear, how often the check itself runs, and how the **Settings → Update Notifications** frequency setting controls how often the banner is shown.
481493

482494
**If you installed NuMa via the Linux installer, the banner also has an Update Now button** that downloads and installs the new version for you — no terminal, no manual download. Click it, confirm, and NuMa fetches the latest release and swaps itself in place; your data is completely untouched (it lives in a separate location the update never touches). You'll see a message telling you to close the browser tab and relaunch NuMa once it's done — the version you're currently running keeps working right up until you do. If you're running NuMa from source instead (a developer checkout), the button doesn't appear — you'll see the plain "what's new on GitHub" link instead, since there's no packaged install for it to replace.
483495

@@ -2595,16 +2607,18 @@ Each entry below has a bold title and a plain-language description — anywhere
25952607

25962608
**CHOOSE HOW OFTEN YOU'RE TOLD ABOUT NEW VERSIONS, AND ALWAYS SEE YOUR CURRENT ONE**
25972609

2598-
Settings now has an "Update Notifications" section where you can set how often the "new version available" banner shows up on the home page: daily (the default), weekly, or monthly. The banner's build note also names that setting directly, with a link to change it. Separately, the home page now always shows a line under the Welcome heading — "Current version date: yyyy-mm-dd:hhmm" — so you can check exactly what you're running, down to the minute, without scrolling to the page footer; that line shows only the version stamp, not the build note, which stays exclusive to the update-available banner.
2610+
Settings now has an "Update Notifications" section where you can set how often the "new version available" banner shows up on the home page: daily (the default), weekly, or monthly. The banner's build note also names that setting directly, with a link to change it. Separately, the home page now always shows a line under the Welcome heading — "Current version date: yyyy-mm-dd:hhmm" — so you can check exactly what you're running, down to the minute, without scrolling to the page footer; whenever a build note is set it follows in parentheses as "(Version note: ...)" on that same line. The build note no longer gets its own standalone box further up the page. See [What you see on the home page](#home-page-tour) for the full rundown, including exactly when the update check itself runs.
25992611

26002612
```
26012613
Scope: web/backend.py (_current_update_notify_frequency(), _should_show_update_notice()
26022614
gating index()'s update_available via a saved prefs.json frequency + last-shown-date pair;
26032615
new POST /settings/update-notify-frequency route; version_date passed as the full
2604-
VERSION stamp, not just its date portion). web/templates/settings.html (new "Update
2605-
Notifications" section). web/templates/home.html (frequency note added next to NEW
2606-
VERSION NOTE in the banner; new always-visible "Current version date" line below
2607-
Welcome showing the full date:time stamp). tests/test_web.py (updated accordingly).
2616+
VERSION stamp). web/templates/settings.html (new "Update Notifications" section).
2617+
web/templates/home.html (frequency note added next to NEW VERSION NOTE in the banner;
2618+
the old standalone "NEW VERSION NOTE" box removed; the always-visible "Current version
2619+
date" line below Welcome now carries the build note in parentheses). tests/test_web.py
2620+
(updated accordingly). user-manual.md (new "What you see on the home page" tour, Part 3
2621+
Section A). README-numa-documentation.md (matching, fuller technical writeup).
26082622
```
26092623

26102624
**BUILD-NOTE LINE NOW LABELED "NEW VERSION NOTE:", AND ITS BROKEN RENAME FIXED**

version.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = "2026-08-31:2135"
1+
VERSION = "2026-08-31:2157"
22

33
# A short, plain-language note shown next to VERSION on the home page and
44
# used to describe this build in the update-available banner (see
@@ -9,4 +9,4 @@
99
# "minor problem fixes"
1010
# "minor function added or improved"
1111
# "significant improvements implemented — see top of User Manual for details"
12-
NEW_VERSION_NOTE = "minor function added or improved: version date now includes time."
12+
NEW_VERSION_NOTE = "minor function added or improved"

web/templates/home.html

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@
4343
{% endif %}
4444
</div>
4545
{% endif %}
46-
{% if version_note and not update_available %}
47-
<div class="alert alert-secondary mt-4 mb-0 py-2">
48-
<small>NEW VERSION NOTE: {{ version_note }}</small>
49-
</div>
50-
{% endif %}
5146
{% if unacked_errors %}
5247
<div class="alert alert-warning mt-4">
5348
<strong>{{ unacked_errors|length }} recalculation{{ 's' if unacked_errors|length != 1 }} failed</strong> and
@@ -72,7 +67,7 @@ <h1>Welcome to NutriMagnus</h1>
7267
{% else %}
7368
Active profile: not set — <a href="/settings">configure under Settings</a>
7469
{% endif %}
75-
<br>Current version date: {{ version_date }}
70+
<br>Current version date: {{ version_date }}{% if version_note %} (Version note: {{ version_note }}){% endif %}
7671
</small></p>
7772
</div>
7873

0 commit comments

Comments
 (0)