Skip to content

[BACK-4528] Skip patient summary updates older than the stored stats - #265

Open
toddkazakov wants to merge 1 commit into
masterfrom
tk-conditional-summary-updates
Open

[BACK-4528] Skip patient summary updates older than the stored stats#265
toddkazakov wants to merge 1 commit into
masterfrom
tk-conditional-summary-updates

Conversation

@toddkazakov

Copy link
Copy Markdown
Contributor

Why

UpdatePatientSummary (POST /v1/patients/{patientId}/summary) unconditionally overwrites the stored cgmStats/bgmStats. Its reporters deliver at least once with no ordering guarantee, which allows a delayed report to arrive after one carrying a newer calculation and regress the stored stats until the user's next calculation.

Today's CDC consumer (clinic-worker patientsummary) is protected by Kafka partition ordering, but the upload-postprocess work processor in platform (which is taking over summary reporting — see platform upload-postprocess-work) is not: a processor reaped mid-report (>5-minute stall) can complete its UpdatePatientSummary after another pod's retry already pushed newer stats. The EHR sync generates reports from this stored copy, so a regression is visible downstream.

What

UpdateSummaryInAllClinics now applies each stats type only when the incoming dates.lastUpdatedDate (the calculation date) is not older than the stored one, using a $cond pipeline update per type — each patient document and each stats type is compared independently, in the same single UpdateMany.

Rules (falling out of BSON comparison order, missing < null < date):

incoming date stored stats result
any absent applied
newer or equal dated applied
older dated kept (regression refused)
none dated kept
none undated applied

Equal dates still apply, so an at-least-once reporter re-delivering the same report remains idempotent. updatedTime is still always bumped and the ErrSummaryNotFound (204) semantics for users who are not a patient of any clinic are unchanged, as is the nil-body unset path. The incoming stats are wrapped in $literal so they are stored verbatim rather than evaluated as aggregation expressions.

Tests

New repository specs (against Mongo): stores when no stats exist; replaces on newer and on equal calculation dates; keeps stored stats against an older report and against an undated report; applies per type independently in one call (cgm replaced while bgm kept); ErrSummaryNotFound for non-patients. go test ./patients/... green.

@toddkazakov toddkazakov changed the title Skip patient summary updates older than the stored stats [BACK-4528] Skip patient summary updates older than the stored stats Sep 2, 2026
Expect(stored.BGM.Id).To(Equal(newest.BGM.Id))
})

It("keeps stats without a calculation date away from a report without one", func() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't appear to match its name. It's not clear which was intended.

The test's name seems to indicate its testing the case where neither the existing summary or new summary have dates. The test itself however, tests a case where there's an existing date, but the new summary provides no date.

Maybe "keeps stats with a calculation date away from an update without one" is better?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants