@peopl-health/nexus 5.71.6 → 5.71.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -77,7 +77,7 @@ function gradeEstimateSchema(description) {
|
|
|
77
77
|
source: {
|
|
78
78
|
type: 'string',
|
|
79
79
|
enum: GRADE_SOURCES,
|
|
80
|
-
description: 'Where this grade came from. Required whenever you set best_estimate. `proctcae_composite`: you are carrying over the number the PRO-CTCAE triage already computed — say this even when you agree with it. When what the patient tells you this turn contradicts that number (they can do today what the questionnaire said they could not), what they tell you now wins: grade it yourself as `agent_adjudicated`. `agent_adjudicated`: you read the grade_scale clauses yourself against what the patient said. `carried_forward`: the case\'s previous grade, unchanged, with no new evidence this turn.',
|
|
80
|
+
description: 'Where this grade came from. Required whenever you set best_estimate. `proctcae_composite`: you are carrying over the number the PRO-CTCAE triage already computed — say this even when you agree with it. When what the patient tells you this turn contradicts that number (they can do today what the questionnaire said they could not), what they tell you now wins: when the term has a grade_scale, grade it yourself as `agent_adjudicated`. `agent_adjudicated`: you read the grade_scale clauses yourself against what the patient said. `carried_forward`: the case\'s previous grade, unchanged, with no new evidence this turn.',
|
|
81
81
|
},
|
|
82
82
|
matched_grade: {
|
|
83
83
|
type: ['integer', 'null'],
|
|
@@ -70,7 +70,7 @@ function gradeAnchorNotice({ ctcaeTerm, grade, anchor }) {
|
|
|
70
70
|
const named = leaned === 'self_care' ? 'self-care' : 'instrumental';
|
|
71
71
|
if (rulesOutFunctionalPart(leaned, anchor)) {
|
|
72
72
|
return `Grade ${grade} of ${ctcaeTerm} can only stand on the non-functional part of its clause: the patient is not limited in ${named} ADL. `
|
|
73
|
-
+ '`reasoning` must name that criterion; if it is not met, record the grade below.';
|
|
73
|
+
+ '`reasoning` must name that criterion; if it is not met, record the grade below and name in `improvement_basis` what rules this grade out.';
|
|
74
74
|
}
|
|
75
75
|
return `Grade ${grade} of ${ctcaeTerm} was recorded without the ${named} ADL limitation its clause mentions. `
|
|
76
76
|
+ 'That is fine when another part of the clause is met or the whole picture makes it the most likely grade — `reasoning` must name which. '
|
|
@@ -52,9 +52,9 @@ const GUARDS = [
|
|
|
52
52
|
}),
|
|
53
53
|
];
|
|
54
54
|
|
|
55
|
-
function gradeClaimError({ ctcaeTerm, grade, stated = null, previous = null, restatesPriorEvidence = true,
|
|
55
|
+
function gradeClaimError({ ctcaeTerm, grade, stated = null, previous = null, restatesPriorEvidence = true, recordsOngoingRead = false, trace = null }) {
|
|
56
56
|
const resolved = grade || {};
|
|
57
|
-
const claim = { ctcaeTerm, grade: resolved, stated: stated || resolved, previous, restatesPriorEvidence,
|
|
57
|
+
const claim = { ctcaeTerm, grade: resolved, stated: stated || resolved, previous, restatesPriorEvidence, recordsOngoingRead, trace };
|
|
58
58
|
for (const guard of GUARDS) {
|
|
59
59
|
const error = guard(claim);
|
|
60
60
|
if (error) return error;
|
|
@@ -121,7 +121,6 @@ function buildAssessment(condition, previous, args, runtime, restatesPriorEviden
|
|
|
121
121
|
stated: parseGradeEstimate(args.grade_estimate),
|
|
122
122
|
previous: previous.grade,
|
|
123
123
|
restatesPriorEvidence,
|
|
124
|
-
continuesEpisode,
|
|
125
124
|
recordsOngoingRead: ONGOING_READ_EVENTS.includes(normalisedEvent(args)),
|
|
126
125
|
trace: runtime?.trace || null,
|
|
127
126
|
});
|
|
@@ -175,6 +174,10 @@ function requireCeilingGap(args, event) {
|
|
|
175
174
|
return error ? fail(error) : null;
|
|
176
175
|
}
|
|
177
176
|
|
|
177
|
+
function sameGradeAndAnchor(a, b) {
|
|
178
|
+
return !!a && !!b && a.bestEstimate === b.bestEstimate && a.functionalAnchor === b.functionalAnchor;
|
|
179
|
+
}
|
|
180
|
+
|
|
178
181
|
function sameGrade(a, b) {
|
|
179
182
|
return JSON.stringify(projectGradeRead(a)) === JSON.stringify(projectGradeRead(b));
|
|
180
183
|
}
|
|
@@ -351,7 +354,9 @@ async function handler(args = {}, context = {}) {
|
|
|
351
354
|
|
|
352
355
|
const { condition, latestAssessment } = result;
|
|
353
356
|
const consistency = inputConsistency(args);
|
|
354
|
-
|
|
357
|
+
// A hold of the same grade on the same anchor was already advised; repeating it re-asks the patient every turn.
|
|
358
|
+
const heldAsAdvised = event === 'add_evidence' && sameGradeAndAnchor(existing.latestAssessment?.grade, latestAssessment.grade);
|
|
359
|
+
const freshRead = ONGOING_READ_EVENTS.includes(event) && hasGradeSignal(args?.grade_estimate) && !isCarriedForward(args.grade_estimate) && !heldAsAdvised;
|
|
355
360
|
const gradeNotice = freshRead ? gradeClaimNotice({ ctcaeTerm: condition.ctcaeTerm, grade: latestAssessment.grade }) : null;
|
|
356
361
|
return JSON.stringify({
|
|
357
362
|
success: true,
|