Skip to content

Fix stratum value placement for component-based stratifiers (CDO-656)#1034

Draft
lukedegruchy wants to merge 1 commit into
mainfrom
ld-20260514-fix-value-component-stratifier-values
Draft

Fix stratum value placement for component-based stratifiers (CDO-656)#1034
lukedegruchy wants to merge 1 commit into
mainfrom
ld-20260514-fix-value-component-stratifier-values

Conversation

@lukedegruchy
Copy link
Copy Markdown
Contributor

@lukedegruchy lukedegruchy commented May 14, 2026

For Measure stratifiers declared with stratifier.component[], the resulting MeasureReport put the stratum value at stratum.value instead of inside stratum.component[].value. Multi-component stratifiers worked by accident; a single component fell through to the non-component path because the gate was valueDefs.size() > 1.

Drive the output shape from the Measure definition (stratifierDef.components()), not the runtime value count, in both R4StratifierBuilder.buildStratum and R4MeasureReportUtils .matchesStratumValue. Also populate stratum.component[].id from the Measure component def.

Example - non-subject value stratifier (Encounter basis):

CQL:

    define function "Age Function" (e Encounter):
        AgeInYearsAt(start of e.period)

Measure.stratifier:

{ 
   "id": "stratifier-age", 
   "code": { "text": "Age" },
   "component": [
   {
        "id": "strat-1-comp-1",
        "code": { 
             "text": "Age" 
        },
        "criteria": { 
              "language": "text/cql.identifier",
              "expression": "Age Function" 
        }
    }
    ]
}

MeasureReport.stratum, before:

{ 
  "value": { 
         "text": "35" 
   }, 
   "population": 
    [ ... ] 
}

MeasureReport.stratum, after:

{ 
"component": [
    {
        "id": "strat-1-comp-1",
        "code":  { "text": "Age" },
        "value": { "text": "35" }
    }
   ],
   "population": [ ... ] 
}

Behavior change: consumers reading stratum.value.text for single-component stratifiers must now read
stratum.component[0].value.text. DSTU3 is unaffected (no stratifier.component in spec); no dedicated R5 builder exists.

For Measure stratifiers declared with `stratifier.component[]`, the
resulting MeasureReport put the stratum value at `stratum.value` instead
of inside `stratum.component[].value`. Multi-component stratifiers worked
by accident; a single component fell through to the non-component path
because the gate was `valueDefs.size() > 1`.

Drive the output shape from the Measure definition
(`stratifierDef.components()`), not the runtime value count, in both
`R4StratifierBuilder.buildStratum` and `R4MeasureReportUtils
.matchesStratumValue`. Also populate `stratum.component[].id` from the
Measure component def.

Example - non-subject value stratifier (Encounter basis):

CQL:
    define function "Age Function" (e Encounter):
        AgeInYearsAt(start of e.period)

Measure.stratifier:
    { "id": "stratifier-age", "code": { "text": "Age" },
      "component": [{
        "id": "strat-1-comp-1",
        "code": { "text": "Age" },
        "criteria": { "language": "text/cql.identifier",
                      "expression": "Age Function" }}]}

MeasureReport.stratum, before:
    { "value": { "text": "35" }, "population": [ ... ] }

MeasureReport.stratum, after:
    { "component": [{
        "id": "strat-1-comp-1",
        "code":  { "text": "Age" },
        "value": { "text": "35" }}],
      "population": [ ... ] }

Behavior change: consumers reading `stratum.value.text` for
single-component stratifiers must now read
`stratum.component[0].value.text`. DSTU3 is unaffected (no
`stratifier.component` in spec); no dedicated R5 builder exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Formatting check succeeded!

@sonarqubecloud
Copy link
Copy Markdown

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.

1 participant