Same-risk SPC reissuance treated as new outlook — duplicate notifications + orphaned rows #44

Closed
opened 2026-07-18 05:31:11 +00:00 by claude-bot · 1 comment
Contributor

Dedup ids embed product_id, which changes on every SPC reissue
(app/services/spc.py:168-206). _upgrade_check
(app/services/spc_processor.py:290-356) only acts on strict upgrade/downgrade;
the equal-risk case returns an empty result, so _record_and_dispatch_outlook
inserts a fresh channel + dashboard SentAlert and dispatches again, while the
prior same-risk dashboard row is never cleared. Users see duplicate outlook
notifications on every no-change reissue (several per day), and stale
uncleared rows accumulate.

Fix: add an explicit new_idx == row_idx branch that treats the reissue as a
continuation — refresh the existing row (product id/expiry) and suppress
dispatch. Add a regression test that reissues the same risk label with a new
product_id and asserts exactly one active row and zero new dispatches.

Acceptance criteria:

  • Same-risk reissue sends no notification and leaves one active row
  • Upgrade/downgrade behavior unchanged (existing tests still pass)
  • Regression test for reissuance added

Filed from the 2026-07-17 codebase audit (docs/.internal/report-2026-07-17.md), finding F-05.

Dedup ids embed `product_id`, which changes on every SPC reissue (app/services/spc.py:168-206). `_upgrade_check` (app/services/spc_processor.py:290-356) only acts on strict upgrade/downgrade; the equal-risk case returns an empty result, so `_record_and_dispatch_outlook` inserts a fresh channel + dashboard `SentAlert` and dispatches again, while the prior same-risk dashboard row is never cleared. Users see duplicate outlook notifications on every no-change reissue (several per day), and stale uncleared rows accumulate. Fix: add an explicit `new_idx == row_idx` branch that treats the reissue as a continuation — refresh the existing row (product id/expiry) and suppress dispatch. Add a regression test that reissues the same risk label with a new product_id and asserts exactly one active row and zero new dispatches. **Acceptance criteria:** - [ ] Same-risk reissue sends no notification and leaves one active row - [ ] Upgrade/downgrade behavior unchanged (existing tests still pass) - [ ] Regression test for reissuance added --- _Filed from the 2026-07-17 codebase audit (`docs/.internal/report-2026-07-17.md`), finding F-05._
Author
Contributor

Fixed in #92 (merged to main). _upgrade_check gained an explicit equal-risk (new_idx == row_idx) continuation branch that refreshes the existing row's product id/expiry and suppresses dispatch, so a same-risk reissue no longer creates a duplicate notification or an orphaned row. Upgrade/downgrade paths unchanged; reissuance regression test asserts one active row + zero new dispatches.

Fixed in #92 (merged to `main`). `_upgrade_check` gained an explicit equal-risk (`new_idx == row_idx`) continuation branch that refreshes the existing row's product id/expiry and suppresses dispatch, so a same-risk reissue no longer creates a duplicate notification or an orphaned row. Upgrade/downgrade paths unchanged; reissuance regression test asserts one active row + zero new dispatches.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/WeatherBot#44
No description provided.