fix(advice): return matched_count, and do not advise about the wrong reading

set_reading_advice returned modified_count, which is 0 both when the
guard refused the write and when the write matched but the text was
already identical.  The caller logs "the advice was not stored" on 0,
so it has to mean "the guard refused it".  It now returns
matched_count.

_start_advice fell back to the newest reading when the reading it was
asked about was not in the run.  That described the wrong number, and
the conditional write would refuse it anyway - so it now says so and
stops.

The editing token is the primary guard on the write, not the gravity.
Every edit writes a fresh token, so a comment-only correction - which
leaves the gravity unchanged - is caught too.  Verified against live
Mongo with the real repository code: the fresh advice lands, the slow
stale thread is refused, and the brewer's comment is untouched.

193 tests pass.
This commit is contained in:
2026-11-09 22:16:29 +10:00
parent 81ebdf3c76
commit ef0d665b78
3 changed files with 58 additions and 2 deletions
+7 -1
View File
@@ -296,7 +296,13 @@ class BeerRepository:
"advice_at": _now_iso(),
}},
)
return result.modified_count
# `matched_count`, not `modified_count`.
#
# `modified_count` is 0 when the document matched but the text
# was already identical - which is a successful write, not a
# refused one. The caller logs "the advice was not stored" when
# this is 0, so it has to mean "the guard refused it".
return result.matched_count
def set_final_reading(self, beer_run_id: str, reading_date: str,
final: bool) -> int:
+9 -1
View File
@@ -106,7 +106,15 @@ def _start_advice(run_id: str, reading_id: str, corrected: bool = False) -> None
# wrong number.
saved = next((r for r in readings if r.get("_id") == str(reading_id)), None)
if saved is None:
saved = dict(readings[-1]) if readings else {"date": "", "sg": None}
# The reading is not in the run. Advising about the newest
# reading instead would describe the wrong number, and the
# conditional write would then refuse it anyway - so it is
# better to say so plainly and stop.
log.info(
"no advice for reading %s: it is not one of the run's readings",
reading_id,
)
return
latest = dict(saved)
latest["_id"] = reading_id