fix(massif): set reviewer on update to fix recent-changes feed - #1770
Conversation
- Add reviewer: req.token.id to cleanedData in massif/update.js, consistent with cave, entrance, organization, and rigging update controllers - The change_massif DB trigger uses id_reviewer IS NULL to distinguish 'create' from 'update' events; without this fix, every massif edit appeared as 'created' in the recent-changes feed regardless of how many times the massif had been edited - Add reviewer assertion to the update integration test
Paul-AUB
left a comment
There was a problem hiding this comment.
Verified the fix against the actual trigger definition and the surrounding code paths:
sql/0_triggers.sql:222-227—change_massif()classifies ascreateexactly whenid_reviewer IS NULL, so populatingrevieweris the right fix, and it matches theentrance/update.js:19-23pattern precisely.sql/0_triggers.sql:203—histo_update_massif()setsNEW.date_reviewed := now()itself, so not settingdateReviewedin the controller is correct.MassifService.getConvertedDataFromClientRequest(api/services/MassifService.js:224-232) returns an explicit whitelist with noreviewerkey, so the spread cannot clobber the new field.config/policies.js:240—v1/massif/updateis behindtokenAuth, soreq.token.idis always defined.converters.jsusesconvertIfObject(source.reviewer, …), so massif responses now returning a populated reviewer instead ofnullis a safe, intended change.- Other massif write paths are already correct:
MassifService.setSensitivity(api/services/MassifService.js:436-440) setsreviewer+dateReviewed, andcreate.jscorrectly leavesreviewernull so the first feed entry stayscreate.
The test fixture creates the massif with reviewer: 2 while the acting user is user1@user1.com, so the new assertion is not vacuous — it genuinely proves the reviewer was reassigned by the update.
Nice, minimal, well-targeted fix. A few non-blocking notes below.
Suggestions (Should Consider)
-
[api/controllers/v1/massif/update.js:74-81] The inline
TName.updateOne(...)block does not setreviewer, whereas the equivalent block inentrance/update.js:97-101does.histo_update_name()copiesNEW.id_reviewerintoh_name(sql/0_triggers.sql:908,923), so renaming a massif currently writes a history row attributed to the previous reviewer (orNULL). There is nolast_change_nametrigger, so this has no effect on the recent-changes feed and is not a regression from this PR — but it is the same attribution gap the PR is closing, and it might be worth fixing in the same pass:const nameUpdate = { reviewer: req.token.id };
-
[test/integration/4_routes/Massifs/update.test.js:112-115] The assertion proves the column is populated, which is a good proxy, but it does not cover the behaviour the issue actually describes — that a second edit is classified as
updaterather thancreatein the feed. Consider a regression test that issues two consecutivePUTs and asserts the resultingt_last_changerows (or the/api/v1/changes/recentpayload) contain anupdateentry for the massif.test/integration/4_routes/Changes/get-recent.test.jsalready exercises that endpoint and could serve as a starting point. This would lock in the fix even if someone later refactors the payload construction.
Nitpicks (Optional)
-
[api/controllers/v1/massif/update.js:15-18]
cave/update.js:26-28,entrance/update.js:20-21andrigging/update.js:23-24all carry a short comment next toreviewerexplaining thatdateReviewedis handled by the SQL historisation trigger. Adding the same line here would keep the four controllers visually consistent and preempt the "shouldn't we also set dateReviewed?" question on a future read:const cleanedData = { reviewer: req.token.id, // dateReviewed will be updated automatically by the SQL historisation trigger ...MassifService.getConvertedDataFromClientRequest(req), };
-
[api/controllers/v1/massif/update.js:15-18] Placing
reviewerbefore the spread matchesentrance/update.js, so the current ordering is defensible on consistency grounds. That said,organization/update.js:18-22puts it after the spread, which makes the field structurally impossible to shadow ifgetConvertedDataFromClientRequestever gains areviewerkey. Purely defensive — there is no client-controlled override path today since the service returns a fixed whitelist.
- Move reviewer after spread in cleanedData (defensive ordering, matches organization/update.js; cannot be clobbered by whitelist service today but is safer for future changes) - Add dateReviewed comment (consistency with cave, entrance, rigging update controllers) - Set reviewer on TName.updateOne so name history rows are attributed to the acting user, not the previous reviewer or null - Add regression test: creates a null-reviewer massif, issues two consecutive PUTs, and asserts reviewer stays non-null — the exact condition the change_massif trigger checks to emit 'update' vs 'create' in the recent-changes feed
|
All four points addressed in the follow-up commit:
|
Fixes massif edits always appearing as "created" in the recent-changes feed.
Why
The
change_massifDB trigger usesid_reviewer IS NULLto decide whether a row has ever been edited:massif/update.jsnever setreviewer, soid_reviewerstayedNULLpermanently. Every edit — first or hundredth — was classified ascreatein the feed. All other entity update controllers (cave, entrance, organization, rigging, etc.) already setreviewer: req.token.id.What
reviewer: req.token.idto the update payload inapi/controllers/v1/massif/update.jsRelated