@nexalink/coding-contracts 0.3.0 → 0.4.0
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.
- package/README.md +2 -2
- package/dist/cjs/index.cjs +460 -16
- package/dist/index.d.ts +57 -5
- package/dist/index.js +456 -14
- package/package.json +8 -2
- package/schemas/coding-reviewer-action.schema.json +13 -2
- package/schemas/rcm-reviewer-event.schema.json +160 -0
- package/schemas/rcm-workflow-catalog.schema.json +62 -5
- package/versions.json +8 -3
- package/workflow-constants.json +2 -1
package/README.md
CHANGED
|
@@ -110,12 +110,12 @@ approved evidence set.
|
|
|
110
110
|
|
|
111
111
|
| Category | Exports |
|
|
112
112
|
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
113
|
-
| Types | `RcmCodingInput`, `RcmCodingOutput`, `RcmSupportingReference`, `RcmModelPrompt`, `RcmRetrievalMetadata`, `RcmRuntimeEvent`, `RcmWorkflowCatalog`
|
|
113
|
+
| Types | `RcmCodingInput`, `RcmCodingOutput`, `RcmSupportingReference`, `RcmModelPrompt`, `RcmRetrievalMetadata`, `RcmRuntimeEvent`, `RcmReviewerEvent`, `RcmWorkflowCatalog` |
|
|
114
114
|
| Case models | `CodingCase`, `CodingCaseContext`, `CodingCasePayer`, `CodingCaseClinical`, `CodingServiceLine`, `CodingExtension`, `CodingBatch` |
|
|
115
115
|
| Decision models | `CodingDecision`, `CodingDecisionLine`, `CodingEvidence`, `CodingRuleResult`, `CodingReviewerAction` |
|
|
116
116
|
| Zod schemas | `rcmCodingInputSchema`, `rcmCodingOutputSchema`, `codingCaseSchema`, `codingDecisionSchema`, and one schema for each additional contract type |
|
|
117
117
|
| Validation | `rcm*ValidationError` functions, `coding*ValidationError` functions, and `valid*` boolean helpers |
|
|
118
|
-
| Workflow policy | `RCM_WORKFLOW_ID`, `RCM_MODEL_POLICY_ID`, `RCM_HUMAN_REVIEW_POLICY_ID`, `RCM_HUMAN_REVIEW_INSTRUCTION`, `RCM_OUTPUT_SCHEMA_NAME`
|
|
118
|
+
| Workflow policy | `RCM_WORKFLOW_ID`, `PIN_TIME_WORKFLOW_ID`, `RCM_MODEL_POLICY_ID`, `RCM_HUMAN_REVIEW_POLICY_ID`, `RCM_HUMAN_REVIEW_INSTRUCTION`, `RCM_OUTPUT_SCHEMA_NAME` |
|
|
119
119
|
| Schema versions | `RCM_INPUT_SCHEMA_VERSION`, `RCM_OUTPUT_SCHEMA_VERSION`, `RCM_REFERENCE_SCHEMA_VERSION`, `CODING_CASE_SCHEMA_VERSION`, `CODING_DECISION_SCHEMA_VERSION`, and the other contract wire-version constants |
|
|
120
120
|
| Schema documents | `Rcm*SchemaJson`, `Coding*SchemaJson` values, JSON Schema package subpaths, `versions.json`, and `workflow-constants.json` |
|
|
121
121
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// GENERATED FILE. DO NOT EDIT.
|
|
3
3
|
// Source: coding-contracts schemas/ (run: bun run contracts:gen)
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
6
|
-
exports.RcmWorkflowCatalogSchemaJson = exports.validRcmWorkflowCatalog = exports.rcmWorkflowCatalogSchema = exports.RcmRuntimeEventSchemaJson = exports.validRcmRuntimeEvent = exports.rcmRuntimeEventSchema = exports.RcmRetrievalMetadataSchemaJson = exports.validRcmRetrievalMetadata = exports.rcmRetrievalMetadataSchema = exports.RcmModelPromptSchemaJson = exports.validRcmModelPrompt = exports.rcmModelPromptSchema = exports.RcmCodingOutputSchemaJson = exports.validRcmCodingOutput = exports.rcmCodingOutputSchema = exports.RcmCodingInputSchemaJson = exports.validRcmCodingInput = exports.rcmCodingInputSchema = exports.RcmSupportingReferenceSchemaJson = exports.validRcmSupportingReference = exports.rcmSupportingReferenceSchema = exports.CodingDecisionSchemaJson = exports.validCodingDecision = exports.codingDecisionSchema = exports.CodingReviewerActionSchemaJson = exports.validCodingReviewerAction = exports.codingReviewerActionSchema = exports.CodingRuleResultSchemaJson = exports.validCodingRuleResult = exports.codingRuleResultSchema = exports.CodingEvidenceSchemaJson = void 0;
|
|
5
|
+
exports.CodingDecisionLineSchemaJson = exports.validCodingDecisionLine = exports.codingDecisionLineSchema = exports.CodingBatchSchemaJson = exports.validCodingBatch = exports.codingBatchSchema = exports.CodingCaseSchemaJson = exports.validCodingCase = exports.codingCaseSchema = exports.CodingExtensionSchemaJson = exports.validCodingExtension = exports.codingExtensionSchema = exports.CodingServiceLineSchemaJson = exports.validCodingServiceLine = exports.codingServiceLineSchema = exports.CodingCaseClinicalSchemaJson = exports.validCodingCaseClinical = exports.codingCaseClinicalSchema = exports.CodingCasePayerSchemaJson = exports.validCodingCasePayer = exports.codingCasePayerSchema = exports.CodingCaseContextSchemaJson = exports.validCodingCaseContext = exports.codingCaseContextSchema = exports.RCM_WORKFLOW_CATALOG_SCHEMA_VERSION = exports.RCM_RUNTIME_EVENT_SCHEMA_VERSION = exports.RCM_REVIEWER_EVENT_SCHEMA_VERSION = exports.RCM_RETRIEVAL_SCHEMA_VERSION = exports.RCM_MODEL_PROMPT_SCHEMA_VERSION = exports.RCM_OUTPUT_SCHEMA_VERSION = exports.RCM_INPUT_SCHEMA_VERSION = exports.RCM_REFERENCE_SCHEMA_VERSION = exports.CODING_DECISION_SCHEMA_VERSION = exports.CODING_REVIEWER_ACTION_SCHEMA_VERSION = exports.CODING_RULE_RESULT_SCHEMA_VERSION = exports.CODING_EVIDENCE_SCHEMA_VERSION = exports.CODING_DECISION_LINE_SCHEMA_VERSION = exports.CODING_BATCH_SCHEMA_VERSION = exports.CODING_CASE_SCHEMA_VERSION = exports.CODING_EXTENSION_SCHEMA_VERSION = exports.CODING_SERVICE_LINE_SCHEMA_VERSION = exports.CODING_CASE_CLINICAL_SCHEMA_VERSION = exports.CODING_CASE_PAYER_SCHEMA_VERSION = exports.CODING_CASE_CONTEXT_SCHEMA_VERSION = exports.PIN_TIME_WORKFLOW_ID = exports.RCM_HUMAN_REVIEW_INSTRUCTION = exports.RCM_OUTPUT_SCHEMA_NAME = exports.RCM_HUMAN_REVIEW_POLICY_ID = exports.RCM_MODEL_POLICY_ID = exports.RCM_WORKFLOW_ID = void 0;
|
|
6
|
+
exports.RcmWorkflowCatalogSchemaJson = exports.validRcmWorkflowCatalog = exports.rcmWorkflowCatalogSchema = exports.RcmRuntimeEventSchemaJson = exports.validRcmRuntimeEvent = exports.rcmRuntimeEventSchema = exports.RcmReviewerEventSchemaJson = exports.validRcmReviewerEvent = exports.rcmReviewerEventSchema = exports.RcmRetrievalMetadataSchemaJson = exports.validRcmRetrievalMetadata = exports.rcmRetrievalMetadataSchema = exports.RcmModelPromptSchemaJson = exports.validRcmModelPrompt = exports.rcmModelPromptSchema = exports.RcmCodingOutputSchemaJson = exports.validRcmCodingOutput = exports.rcmCodingOutputSchema = exports.RcmCodingInputSchemaJson = exports.validRcmCodingInput = exports.rcmCodingInputSchema = exports.RcmSupportingReferenceSchemaJson = exports.validRcmSupportingReference = exports.rcmSupportingReferenceSchema = exports.CodingDecisionSchemaJson = exports.validCodingDecision = exports.codingDecisionSchema = exports.CodingReviewerActionSchemaJson = exports.validCodingReviewerAction = exports.codingReviewerActionSchema = exports.CodingRuleResultSchemaJson = exports.validCodingRuleResult = exports.codingRuleResultSchema = exports.CodingEvidenceSchemaJson = exports.validCodingEvidence = exports.codingEvidenceSchema = void 0;
|
|
7
7
|
exports.codingCaseContextValidationError = codingCaseContextValidationError;
|
|
8
8
|
exports.codingCasePayerValidationError = codingCasePayerValidationError;
|
|
9
9
|
exports.codingCaseClinicalValidationError = codingCaseClinicalValidationError;
|
|
@@ -21,6 +21,7 @@ exports.rcmCodingInputValidationError = rcmCodingInputValidationError;
|
|
|
21
21
|
exports.rcmCodingOutputValidationError = rcmCodingOutputValidationError;
|
|
22
22
|
exports.rcmModelPromptValidationError = rcmModelPromptValidationError;
|
|
23
23
|
exports.rcmRetrievalMetadataValidationError = rcmRetrievalMetadataValidationError;
|
|
24
|
+
exports.rcmReviewerEventValidationError = rcmReviewerEventValidationError;
|
|
24
25
|
exports.rcmRuntimeEventValidationError = rcmRuntimeEventValidationError;
|
|
25
26
|
exports.rcmWorkflowCatalogValidationError = rcmWorkflowCatalogValidationError;
|
|
26
27
|
const zod_1 = require("zod");
|
|
@@ -64,6 +65,7 @@ exports.RCM_MODEL_POLICY_ID = "carecompass-rcm-review-v1";
|
|
|
64
65
|
exports.RCM_HUMAN_REVIEW_POLICY_ID = "qualified-coder-review-v1";
|
|
65
66
|
exports.RCM_OUTPUT_SCHEMA_NAME = "carecompass_rcm_grounded_review";
|
|
66
67
|
exports.RCM_HUMAN_REVIEW_INSTRUCTION = "Qualified human coder review is required before billing, coding, or claim submission.";
|
|
68
|
+
exports.PIN_TIME_WORKFLOW_ID = "monthly-pin-time-aggregation";
|
|
67
69
|
// Schema wire versions (source: schemas/*.schema.json).
|
|
68
70
|
exports.CODING_CASE_CONTEXT_SCHEMA_VERSION = "coding-case-context-v1";
|
|
69
71
|
exports.CODING_CASE_PAYER_SCHEMA_VERSION = "coding-case-payer-v1";
|
|
@@ -82,6 +84,7 @@ exports.RCM_INPUT_SCHEMA_VERSION = "rcm-coding-input-v1";
|
|
|
82
84
|
exports.RCM_OUTPUT_SCHEMA_VERSION = "rcm-grounded-human-review-v2";
|
|
83
85
|
exports.RCM_MODEL_PROMPT_SCHEMA_VERSION = "rcm-model-prompt-v1";
|
|
84
86
|
exports.RCM_RETRIEVAL_SCHEMA_VERSION = "rcm-retrieval-metadata-v1";
|
|
87
|
+
exports.RCM_REVIEWER_EVENT_SCHEMA_VERSION = "rcm-reviewer-event-v1";
|
|
85
88
|
exports.RCM_RUNTIME_EVENT_SCHEMA_VERSION = "rcm-runtime-event-v1";
|
|
86
89
|
exports.RCM_WORKFLOW_CATALOG_SCHEMA_VERSION = "rcm-workflow-catalog-v1";
|
|
87
90
|
// --------------------------------------------------------------------
|
|
@@ -3199,7 +3202,7 @@ exports.CodingRuleResultSchemaJson = {
|
|
|
3199
3202
|
},
|
|
3200
3203
|
};
|
|
3201
3204
|
// --------------------------------------------------------------------
|
|
3202
|
-
// CodingReviewerAction (schema 1.
|
|
3205
|
+
// CodingReviewerAction (schema 1.1.0, wire coding-reviewer-action-v1)
|
|
3203
3206
|
// --------------------------------------------------------------------
|
|
3204
3207
|
exports.codingReviewerActionSchema = zod_1.z
|
|
3205
3208
|
.object({
|
|
@@ -3212,6 +3215,15 @@ exports.codingReviewerActionSchema = zod_1.z
|
|
|
3212
3215
|
"escalated",
|
|
3213
3216
|
]),
|
|
3214
3217
|
resolutionCode: zod_1.z.string().min(1).max(80).optional(),
|
|
3218
|
+
reviewOutcomeCategory: zod_1.z
|
|
3219
|
+
.enum([
|
|
3220
|
+
"unsupported_or_excessive",
|
|
3221
|
+
"missed_supported",
|
|
3222
|
+
"unchanged_supported",
|
|
3223
|
+
"missing_evidence",
|
|
3224
|
+
"escalation",
|
|
3225
|
+
])
|
|
3226
|
+
.optional(),
|
|
3215
3227
|
notes: zod_1.z
|
|
3216
3228
|
.string()
|
|
3217
3229
|
.min(1)
|
|
@@ -3235,6 +3247,7 @@ function codingReviewerActionValidationError(value) {
|
|
|
3235
3247
|
"reviewerRole",
|
|
3236
3248
|
"action",
|
|
3237
3249
|
"resolutionCode",
|
|
3250
|
+
"reviewOutcomeCategory",
|
|
3238
3251
|
"notes",
|
|
3239
3252
|
"occurredAt",
|
|
3240
3253
|
].includes(key)))
|
|
@@ -3262,6 +3275,18 @@ function codingReviewerActionValidationError(value) {
|
|
|
3262
3275
|
value_resolutionCode.length > 80)
|
|
3263
3276
|
return "reviewer_action_resolution_code";
|
|
3264
3277
|
}
|
|
3278
|
+
if (value["reviewOutcomeCategory"] !== undefined) {
|
|
3279
|
+
const value_reviewOutcomeCategory = value["reviewOutcomeCategory"];
|
|
3280
|
+
if (typeof value_reviewOutcomeCategory !== "string" ||
|
|
3281
|
+
![
|
|
3282
|
+
"unsupported_or_excessive",
|
|
3283
|
+
"missed_supported",
|
|
3284
|
+
"unchanged_supported",
|
|
3285
|
+
"missing_evidence",
|
|
3286
|
+
"escalation",
|
|
3287
|
+
].includes(value_reviewOutcomeCategory))
|
|
3288
|
+
return "reviewer_action_outcome_category";
|
|
3289
|
+
}
|
|
3265
3290
|
if (value["notes"] !== undefined) {
|
|
3266
3291
|
const value_notes = value["notes"];
|
|
3267
3292
|
if (typeof value_notes !== "string" ||
|
|
@@ -3284,8 +3309,8 @@ exports.CodingReviewerActionSchemaJson = {
|
|
|
3284
3309
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
3285
3310
|
$id: "https://nexalink.care/contracts/coding-reviewer-action.schema.json",
|
|
3286
3311
|
title: "CodingReviewerAction",
|
|
3287
|
-
description: "Attributable human-review disposition appended to an otherwise immutable decision. A decision plus its reviewer actions remains replayable: original and reviewer versions are both preserved.",
|
|
3288
|
-
version: "1.
|
|
3312
|
+
description: "Attributable human-review disposition appended to an otherwise immutable decision. A decision plus its reviewer actions remains replayable: original and reviewer versions are both preserved. Review outcome categories are reviewer-adjudicated observations and never inferred from payment, code, or reimbursement changes.",
|
|
3313
|
+
version: "1.1.0",
|
|
3289
3314
|
type: "object",
|
|
3290
3315
|
additionalProperties: false,
|
|
3291
3316
|
required: ["reviewerId", "action", "occurredAt"],
|
|
@@ -3309,6 +3334,16 @@ exports.CodingReviewerActionSchemaJson = {
|
|
|
3309
3334
|
minLength: 1,
|
|
3310
3335
|
maxLength: 80,
|
|
3311
3336
|
},
|
|
3337
|
+
reviewOutcomeCategory: {
|
|
3338
|
+
type: "string",
|
|
3339
|
+
enum: [
|
|
3340
|
+
"unsupported_or_excessive",
|
|
3341
|
+
"missed_supported",
|
|
3342
|
+
"unchanged_supported",
|
|
3343
|
+
"missing_evidence",
|
|
3344
|
+
"escalation",
|
|
3345
|
+
],
|
|
3346
|
+
},
|
|
3312
3347
|
notes: {
|
|
3313
3348
|
type: "string",
|
|
3314
3349
|
minLength: 1,
|
|
@@ -3500,7 +3535,7 @@ exports.codingDecisionSchema = zod_1.z
|
|
|
3500
3535
|
});
|
|
3501
3536
|
}
|
|
3502
3537
|
});
|
|
3503
|
-
function codingDecisionValidationError(value
|
|
3538
|
+
function codingDecisionValidationError(value) {
|
|
3504
3539
|
if (!isRecord(value))
|
|
3505
3540
|
return "coding_decision";
|
|
3506
3541
|
if (![
|
|
@@ -5243,6 +5278,342 @@ exports.RcmRetrievalMetadataSchemaJson = {
|
|
|
5243
5278
|
},
|
|
5244
5279
|
};
|
|
5245
5280
|
// --------------------------------------------------------------------
|
|
5281
|
+
// RcmReviewerEvent (schema 1.0.0, wire rcm-reviewer-event-v1)
|
|
5282
|
+
// --------------------------------------------------------------------
|
|
5283
|
+
exports.rcmReviewerEventSchema = zod_1.z
|
|
5284
|
+
.object({
|
|
5285
|
+
eventName: zod_1.z.enum([
|
|
5286
|
+
"review_opened",
|
|
5287
|
+
"decision_shown",
|
|
5288
|
+
"evidence_opened",
|
|
5289
|
+
"evidence_copied",
|
|
5290
|
+
"review_active_time",
|
|
5291
|
+
]),
|
|
5292
|
+
occurredAt: zod_1.z
|
|
5293
|
+
.string()
|
|
5294
|
+
.regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$"))
|
|
5295
|
+
.refine(isRfc3339DateTime)
|
|
5296
|
+
.max(64),
|
|
5297
|
+
tenantRef: zod_1.z
|
|
5298
|
+
.string()
|
|
5299
|
+
.regex(new RegExp("^[A-Za-z0-9_.:-]+$"))
|
|
5300
|
+
.min(1)
|
|
5301
|
+
.max(128),
|
|
5302
|
+
caseRef: zod_1.z.string().regex(new RegExp("^[A-Za-z0-9_.:-]+$")).min(1).max(128),
|
|
5303
|
+
reviewId: zod_1.z
|
|
5304
|
+
.string()
|
|
5305
|
+
.regex(new RegExp("^[A-Za-z0-9_.:-]+$"))
|
|
5306
|
+
.min(1)
|
|
5307
|
+
.max(128)
|
|
5308
|
+
.optional(),
|
|
5309
|
+
workflowId: zod_1.z.enum([
|
|
5310
|
+
"rcm-coding-assistance",
|
|
5311
|
+
"monthly-pin-time-aggregation",
|
|
5312
|
+
]),
|
|
5313
|
+
packId: zod_1.z
|
|
5314
|
+
.string()
|
|
5315
|
+
.regex(new RegExp("^[A-Za-z0-9_.:-]+$"))
|
|
5316
|
+
.min(1)
|
|
5317
|
+
.max(80)
|
|
5318
|
+
.optional(),
|
|
5319
|
+
packVersion: zod_1.z
|
|
5320
|
+
.string()
|
|
5321
|
+
.regex(new RegExp("^[A-Za-z0-9_.:-]+$"))
|
|
5322
|
+
.min(1)
|
|
5323
|
+
.max(80)
|
|
5324
|
+
.optional(),
|
|
5325
|
+
environment: zod_1.z.enum(["development", "staging", "production"]).optional(),
|
|
5326
|
+
source: zod_1.z.enum(["portal", "embed"]),
|
|
5327
|
+
evidenceId: zod_1.z
|
|
5328
|
+
.string()
|
|
5329
|
+
.regex(new RegExp("^[A-Za-z0-9_.:-]{1,64}$"))
|
|
5330
|
+
.min(1)
|
|
5331
|
+
.max(64)
|
|
5332
|
+
.optional(),
|
|
5333
|
+
activeSeconds: zod_1.z.number().int().min(0).max(86400).optional(),
|
|
5334
|
+
idlePaused: zod_1.z.boolean().optional(),
|
|
5335
|
+
})
|
|
5336
|
+
.strict()
|
|
5337
|
+
.superRefine((value, ctx) => {
|
|
5338
|
+
const isEvidenceEvent = value["eventName"] === "evidence_opened" ||
|
|
5339
|
+
value["eventName"] === "evidence_copied";
|
|
5340
|
+
const isActiveTimeEvent = value["eventName"] === "review_active_time";
|
|
5341
|
+
if (isEvidenceEvent !== (value.evidenceId !== undefined) ||
|
|
5342
|
+
isActiveTimeEvent !== (value.activeSeconds !== undefined) ||
|
|
5343
|
+
(!isActiveTimeEvent && value.idlePaused !== undefined)) {
|
|
5344
|
+
ctx.addIssue({
|
|
5345
|
+
code: "custom",
|
|
5346
|
+
path: ["eventName"],
|
|
5347
|
+
message: "reviewer_event_shape",
|
|
5348
|
+
});
|
|
5349
|
+
}
|
|
5350
|
+
});
|
|
5351
|
+
function rcmReviewerEventValidationError(value) {
|
|
5352
|
+
if (!isRecord(value))
|
|
5353
|
+
return "reviewer_event";
|
|
5354
|
+
if (![
|
|
5355
|
+
"eventName",
|
|
5356
|
+
"occurredAt",
|
|
5357
|
+
"tenantRef",
|
|
5358
|
+
"caseRef",
|
|
5359
|
+
"workflowId",
|
|
5360
|
+
"source",
|
|
5361
|
+
].every((key) => key in value))
|
|
5362
|
+
return "reviewer_event_keys";
|
|
5363
|
+
if (!Object.keys(value).every((key) => [
|
|
5364
|
+
"eventName",
|
|
5365
|
+
"occurredAt",
|
|
5366
|
+
"tenantRef",
|
|
5367
|
+
"caseRef",
|
|
5368
|
+
"reviewId",
|
|
5369
|
+
"workflowId",
|
|
5370
|
+
"packId",
|
|
5371
|
+
"packVersion",
|
|
5372
|
+
"environment",
|
|
5373
|
+
"source",
|
|
5374
|
+
"evidenceId",
|
|
5375
|
+
"activeSeconds",
|
|
5376
|
+
"idlePaused",
|
|
5377
|
+
].includes(key)))
|
|
5378
|
+
return "reviewer_event_keys";
|
|
5379
|
+
const value_eventName = value["eventName"];
|
|
5380
|
+
if (typeof value_eventName !== "string" ||
|
|
5381
|
+
![
|
|
5382
|
+
"review_opened",
|
|
5383
|
+
"decision_shown",
|
|
5384
|
+
"evidence_opened",
|
|
5385
|
+
"evidence_copied",
|
|
5386
|
+
"review_active_time",
|
|
5387
|
+
].includes(value_eventName))
|
|
5388
|
+
return "reviewer_event_name";
|
|
5389
|
+
const value_occurredAt = value["occurredAt"];
|
|
5390
|
+
if (typeof value_occurredAt !== "string" ||
|
|
5391
|
+
value_occurredAt.length > 64 ||
|
|
5392
|
+
!new RegExp("^\\d{4}-\\d{2}-\\d{2}T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$").test(value_occurredAt) ||
|
|
5393
|
+
!isRfc3339DateTime(value_occurredAt))
|
|
5394
|
+
return "reviewer_event_occurred_at";
|
|
5395
|
+
const value_tenantRef = value["tenantRef"];
|
|
5396
|
+
if (typeof value_tenantRef !== "string" ||
|
|
5397
|
+
value_tenantRef.length < 1 ||
|
|
5398
|
+
value_tenantRef.length > 128 ||
|
|
5399
|
+
!new RegExp("^[A-Za-z0-9_.:-]+$").test(value_tenantRef))
|
|
5400
|
+
return "reviewer_event_tenant_ref";
|
|
5401
|
+
const value_caseRef = value["caseRef"];
|
|
5402
|
+
if (typeof value_caseRef !== "string" ||
|
|
5403
|
+
value_caseRef.length < 1 ||
|
|
5404
|
+
value_caseRef.length > 128 ||
|
|
5405
|
+
!new RegExp("^[A-Za-z0-9_.:-]+$").test(value_caseRef))
|
|
5406
|
+
return "reviewer_event_case_ref";
|
|
5407
|
+
if (value["reviewId"] !== undefined) {
|
|
5408
|
+
const value_reviewId = value["reviewId"];
|
|
5409
|
+
if (typeof value_reviewId !== "string" ||
|
|
5410
|
+
value_reviewId.length < 1 ||
|
|
5411
|
+
value_reviewId.length > 128 ||
|
|
5412
|
+
!new RegExp("^[A-Za-z0-9_.:-]+$").test(value_reviewId))
|
|
5413
|
+
return "reviewer_event_review_id";
|
|
5414
|
+
}
|
|
5415
|
+
const value_workflowId = value["workflowId"];
|
|
5416
|
+
if (typeof value_workflowId !== "string" ||
|
|
5417
|
+
!["rcm-coding-assistance", "monthly-pin-time-aggregation"].includes(value_workflowId))
|
|
5418
|
+
return "reviewer_event_workflow_id";
|
|
5419
|
+
if (value["packId"] !== undefined) {
|
|
5420
|
+
const value_packId = value["packId"];
|
|
5421
|
+
if (typeof value_packId !== "string" ||
|
|
5422
|
+
value_packId.length < 1 ||
|
|
5423
|
+
value_packId.length > 80 ||
|
|
5424
|
+
!new RegExp("^[A-Za-z0-9_.:-]+$").test(value_packId))
|
|
5425
|
+
return "reviewer_event_pack_id";
|
|
5426
|
+
}
|
|
5427
|
+
if (value["packVersion"] !== undefined) {
|
|
5428
|
+
const value_packVersion = value["packVersion"];
|
|
5429
|
+
if (typeof value_packVersion !== "string" ||
|
|
5430
|
+
value_packVersion.length < 1 ||
|
|
5431
|
+
value_packVersion.length > 80 ||
|
|
5432
|
+
!new RegExp("^[A-Za-z0-9_.:-]+$").test(value_packVersion))
|
|
5433
|
+
return "reviewer_event_pack_version";
|
|
5434
|
+
}
|
|
5435
|
+
if (value["environment"] !== undefined) {
|
|
5436
|
+
const value_environment = value["environment"];
|
|
5437
|
+
if (typeof value_environment !== "string" ||
|
|
5438
|
+
!["development", "staging", "production"].includes(value_environment))
|
|
5439
|
+
return "reviewer_event_environment";
|
|
5440
|
+
}
|
|
5441
|
+
const value_source = value["source"];
|
|
5442
|
+
if (typeof value_source !== "string" ||
|
|
5443
|
+
!["portal", "embed"].includes(value_source))
|
|
5444
|
+
return "reviewer_event_source";
|
|
5445
|
+
if (value["evidenceId"] !== undefined) {
|
|
5446
|
+
const value_evidenceId = value["evidenceId"];
|
|
5447
|
+
if (typeof value_evidenceId !== "string" ||
|
|
5448
|
+
value_evidenceId.length < 1 ||
|
|
5449
|
+
value_evidenceId.length > 64 ||
|
|
5450
|
+
!new RegExp("^[A-Za-z0-9_.:-]{1,64}$").test(value_evidenceId))
|
|
5451
|
+
return "reviewer_event_evidence_id";
|
|
5452
|
+
}
|
|
5453
|
+
if (value["activeSeconds"] !== undefined) {
|
|
5454
|
+
const value_activeSeconds = value["activeSeconds"];
|
|
5455
|
+
if (typeof value_activeSeconds !== "number" ||
|
|
5456
|
+
Number.isNaN(value_activeSeconds) ||
|
|
5457
|
+
!Number.isInteger(value_activeSeconds) ||
|
|
5458
|
+
value_activeSeconds < 0 ||
|
|
5459
|
+
value_activeSeconds > 86400)
|
|
5460
|
+
return "reviewer_event_active_seconds";
|
|
5461
|
+
}
|
|
5462
|
+
if (value["idlePaused"] !== undefined) {
|
|
5463
|
+
const value_idlePaused = value["idlePaused"];
|
|
5464
|
+
if (typeof value_idlePaused !== "boolean")
|
|
5465
|
+
return "reviewer_event_idle_paused";
|
|
5466
|
+
}
|
|
5467
|
+
const eventName = value["eventName"];
|
|
5468
|
+
const isEvidenceEvent = eventName === "evidence_opened" || eventName === "evidence_copied";
|
|
5469
|
+
if (isEvidenceEvent !== (value["evidenceId"] !== undefined))
|
|
5470
|
+
return "reviewer_event_shape";
|
|
5471
|
+
const isActiveTimeEvent = eventName === "review_active_time";
|
|
5472
|
+
if (isActiveTimeEvent !== (value["activeSeconds"] !== undefined))
|
|
5473
|
+
return "reviewer_event_shape";
|
|
5474
|
+
if (!isActiveTimeEvent && value["idlePaused"] !== undefined)
|
|
5475
|
+
return "reviewer_event_shape";
|
|
5476
|
+
return null;
|
|
5477
|
+
}
|
|
5478
|
+
const validRcmReviewerEvent = (value) => rcmReviewerEventValidationError(value) === null;
|
|
5479
|
+
exports.validRcmReviewerEvent = validRcmReviewerEvent;
|
|
5480
|
+
exports.RcmReviewerEventSchemaJson = {
|
|
5481
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
5482
|
+
$id: "https://nexalink.care/contracts/rcm-reviewer-event.schema.json",
|
|
5483
|
+
title: "RcmReviewerEvent",
|
|
5484
|
+
description: "Tenant-scoped, PHI-free reviewer engagement event for CareCompass RCM workflows. Events carry only an opaque case reference, categorical engagement facts, and aggregate durations. They never carry prompts, model responses, document contents, patient or member identifiers, claim identifiers, or free text.",
|
|
5485
|
+
version: "1.0.0",
|
|
5486
|
+
type: "object",
|
|
5487
|
+
additionalProperties: false,
|
|
5488
|
+
required: [
|
|
5489
|
+
"eventName",
|
|
5490
|
+
"occurredAt",
|
|
5491
|
+
"tenantRef",
|
|
5492
|
+
"caseRef",
|
|
5493
|
+
"workflowId",
|
|
5494
|
+
"source",
|
|
5495
|
+
],
|
|
5496
|
+
properties: {
|
|
5497
|
+
eventName: {
|
|
5498
|
+
type: "string",
|
|
5499
|
+
enum: [
|
|
5500
|
+
"review_opened",
|
|
5501
|
+
"decision_shown",
|
|
5502
|
+
"evidence_opened",
|
|
5503
|
+
"evidence_copied",
|
|
5504
|
+
"review_active_time",
|
|
5505
|
+
],
|
|
5506
|
+
},
|
|
5507
|
+
occurredAt: {
|
|
5508
|
+
type: "string",
|
|
5509
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$",
|
|
5510
|
+
format: "date-time",
|
|
5511
|
+
maxLength: 64,
|
|
5512
|
+
},
|
|
5513
|
+
tenantRef: {
|
|
5514
|
+
type: "string",
|
|
5515
|
+
minLength: 1,
|
|
5516
|
+
maxLength: 128,
|
|
5517
|
+
pattern: "^[A-Za-z0-9_.:-]+$",
|
|
5518
|
+
},
|
|
5519
|
+
caseRef: {
|
|
5520
|
+
type: "string",
|
|
5521
|
+
minLength: 1,
|
|
5522
|
+
maxLength: 128,
|
|
5523
|
+
pattern: "^[A-Za-z0-9_.:-]+$",
|
|
5524
|
+
},
|
|
5525
|
+
reviewId: {
|
|
5526
|
+
type: "string",
|
|
5527
|
+
minLength: 1,
|
|
5528
|
+
maxLength: 128,
|
|
5529
|
+
pattern: "^[A-Za-z0-9_.:-]+$",
|
|
5530
|
+
},
|
|
5531
|
+
workflowId: {
|
|
5532
|
+
type: "string",
|
|
5533
|
+
enum: ["rcm-coding-assistance", "monthly-pin-time-aggregation"],
|
|
5534
|
+
},
|
|
5535
|
+
packId: {
|
|
5536
|
+
type: "string",
|
|
5537
|
+
minLength: 1,
|
|
5538
|
+
maxLength: 80,
|
|
5539
|
+
pattern: "^[A-Za-z0-9_.:-]+$",
|
|
5540
|
+
},
|
|
5541
|
+
packVersion: {
|
|
5542
|
+
type: "string",
|
|
5543
|
+
minLength: 1,
|
|
5544
|
+
maxLength: 80,
|
|
5545
|
+
pattern: "^[A-Za-z0-9_.:-]+$",
|
|
5546
|
+
},
|
|
5547
|
+
environment: {
|
|
5548
|
+
type: "string",
|
|
5549
|
+
enum: ["development", "staging", "production"],
|
|
5550
|
+
},
|
|
5551
|
+
source: {
|
|
5552
|
+
type: "string",
|
|
5553
|
+
enum: ["portal", "embed"],
|
|
5554
|
+
},
|
|
5555
|
+
evidenceId: {
|
|
5556
|
+
type: "string",
|
|
5557
|
+
minLength: 1,
|
|
5558
|
+
pattern: "^[A-Za-z0-9_.:-]{1,64}$",
|
|
5559
|
+
maxLength: 64,
|
|
5560
|
+
},
|
|
5561
|
+
activeSeconds: {
|
|
5562
|
+
type: "integer",
|
|
5563
|
+
minimum: 0,
|
|
5564
|
+
maximum: 86400,
|
|
5565
|
+
},
|
|
5566
|
+
idlePaused: {
|
|
5567
|
+
type: "boolean",
|
|
5568
|
+
},
|
|
5569
|
+
},
|
|
5570
|
+
allOf: [
|
|
5571
|
+
{
|
|
5572
|
+
if: {
|
|
5573
|
+
properties: {
|
|
5574
|
+
eventName: {
|
|
5575
|
+
enum: ["evidence_opened", "evidence_copied"],
|
|
5576
|
+
},
|
|
5577
|
+
},
|
|
5578
|
+
required: ["eventName"],
|
|
5579
|
+
},
|
|
5580
|
+
then: {
|
|
5581
|
+
required: ["evidenceId"],
|
|
5582
|
+
},
|
|
5583
|
+
else: {
|
|
5584
|
+
not: {
|
|
5585
|
+
required: ["evidenceId"],
|
|
5586
|
+
},
|
|
5587
|
+
},
|
|
5588
|
+
},
|
|
5589
|
+
{
|
|
5590
|
+
if: {
|
|
5591
|
+
properties: {
|
|
5592
|
+
eventName: {
|
|
5593
|
+
const: "review_active_time",
|
|
5594
|
+
},
|
|
5595
|
+
},
|
|
5596
|
+
required: ["eventName"],
|
|
5597
|
+
},
|
|
5598
|
+
then: {
|
|
5599
|
+
required: ["activeSeconds"],
|
|
5600
|
+
},
|
|
5601
|
+
else: {
|
|
5602
|
+
not: {
|
|
5603
|
+
anyOf: [
|
|
5604
|
+
{
|
|
5605
|
+
required: ["activeSeconds"],
|
|
5606
|
+
},
|
|
5607
|
+
{
|
|
5608
|
+
required: ["idlePaused"],
|
|
5609
|
+
},
|
|
5610
|
+
],
|
|
5611
|
+
},
|
|
5612
|
+
},
|
|
5613
|
+
},
|
|
5614
|
+
],
|
|
5615
|
+
};
|
|
5616
|
+
// --------------------------------------------------------------------
|
|
5246
5617
|
// RcmRuntimeEvent (schema 1.0.0, wire rcm-runtime-event-v1)
|
|
5247
5618
|
// --------------------------------------------------------------------
|
|
5248
5619
|
exports.rcmRuntimeEventSchema = zod_1.z
|
|
@@ -5601,17 +5972,20 @@ exports.RcmRuntimeEventSchemaJson = {
|
|
|
5601
5972
|
},
|
|
5602
5973
|
};
|
|
5603
5974
|
// --------------------------------------------------------------------
|
|
5604
|
-
// RcmWorkflowCatalog (schema 1.
|
|
5975
|
+
// RcmWorkflowCatalog (schema 1.1.0, wire rcm-workflow-catalog-v1)
|
|
5605
5976
|
// --------------------------------------------------------------------
|
|
5606
5977
|
exports.rcmWorkflowCatalogSchema = zod_1.z
|
|
5607
5978
|
.object({
|
|
5608
|
-
id: zod_1.z.enum(["rcm-coding-assistance"]),
|
|
5979
|
+
id: zod_1.z.enum(["rcm-coding-assistance", "monthly-pin-time-aggregation"]),
|
|
5609
5980
|
name: zod_1.z.string().min(1).max(120),
|
|
5610
5981
|
description: zod_1.z.string().min(1).max(400),
|
|
5611
5982
|
environments: zod_1.z.array(zod_1.z.enum(["development", "production"])).min(1),
|
|
5612
5983
|
modelPolicy: zod_1.z
|
|
5613
5984
|
.object({
|
|
5614
|
-
policyId: zod_1.z.
|
|
5985
|
+
policyId: zod_1.z.enum([
|
|
5986
|
+
"carecompass-rcm-review-v1",
|
|
5987
|
+
"carecompass-pin-time-policy-v1",
|
|
5988
|
+
]),
|
|
5615
5989
|
inferencePath: zod_1.z.string().max(64),
|
|
5616
5990
|
maxNewTokens: zod_1.z.number().int().min(1).max(2048),
|
|
5617
5991
|
temperature: zod_1.z.number().min(0).max(2),
|
|
@@ -5627,7 +6001,21 @@ exports.rcmWorkflowCatalogSchema = zod_1.z
|
|
|
5627
6001
|
.strict(),
|
|
5628
6002
|
outputSchemaVersion: zod_1.z.literal("rcm-grounded-human-review-v2"),
|
|
5629
6003
|
})
|
|
5630
|
-
.strict()
|
|
6004
|
+
.strict()
|
|
6005
|
+
.superRefine((value, ctx) => {
|
|
6006
|
+
const expectedPolicy = value.id === "rcm-coding-assistance"
|
|
6007
|
+
? "carecompass-rcm-review-v1"
|
|
6008
|
+
: "carecompass-pin-time-policy-v1";
|
|
6009
|
+
if (value.modelPolicy.policyId !== expectedPolicy ||
|
|
6010
|
+
(value.id === "monthly-pin-time-aggregation" &&
|
|
6011
|
+
value.environments.some((environment) => environment !== "development"))) {
|
|
6012
|
+
ctx.addIssue({
|
|
6013
|
+
code: "custom",
|
|
6014
|
+
path: ["modelPolicy"],
|
|
6015
|
+
message: "workflow_policy_binding",
|
|
6016
|
+
});
|
|
6017
|
+
}
|
|
6018
|
+
});
|
|
5631
6019
|
function rcmWorkflowCatalogValidationError(value) {
|
|
5632
6020
|
if (!isRecord(value))
|
|
5633
6021
|
return "workflow_catalog";
|
|
@@ -5653,7 +6041,7 @@ function rcmWorkflowCatalogValidationError(value) {
|
|
|
5653
6041
|
return "workflow_catalog_keys";
|
|
5654
6042
|
const value_id = value["id"];
|
|
5655
6043
|
if (typeof value_id !== "string" ||
|
|
5656
|
-
!["rcm-coding-assistance"].includes(value_id))
|
|
6044
|
+
!["rcm-coding-assistance", "monthly-pin-time-aggregation"].includes(value_id))
|
|
5657
6045
|
return "workflow_id";
|
|
5658
6046
|
const value_name = value["name"];
|
|
5659
6047
|
if (typeof value_name !== "string" ||
|
|
@@ -5696,7 +6084,7 @@ function rcmWorkflowCatalogValidationError(value) {
|
|
|
5696
6084
|
return "model_policy_keys";
|
|
5697
6085
|
const value_modelPolicy_policyId = value_modelPolicy["policyId"];
|
|
5698
6086
|
if (typeof value_modelPolicy_policyId !== "string" ||
|
|
5699
|
-
|
|
6087
|
+
!["carecompass-rcm-review-v1", "carecompass-pin-time-policy-v1"].includes(value_modelPolicy_policyId))
|
|
5700
6088
|
return "model_policy_id";
|
|
5701
6089
|
const value_modelPolicy_inferencePath = value_modelPolicy["inferencePath"];
|
|
5702
6090
|
if (typeof value_modelPolicy_inferencePath !== "string" ||
|
|
@@ -5742,6 +6130,15 @@ function rcmWorkflowCatalogValidationError(value) {
|
|
|
5742
6130
|
if (typeof value_outputSchemaVersion !== "string" ||
|
|
5743
6131
|
value_outputSchemaVersion !== "rcm-grounded-human-review-v2")
|
|
5744
6132
|
return "workflow_output_schema_version";
|
|
6133
|
+
const policy = isRecord(value["modelPolicy"]) ? value["modelPolicy"] : {};
|
|
6134
|
+
const expectedPolicy = value["id"] === "rcm-coding-assistance"
|
|
6135
|
+
? "carecompass-rcm-review-v1"
|
|
6136
|
+
: "carecompass-pin-time-policy-v1";
|
|
6137
|
+
if (policy["policyId"] !== expectedPolicy ||
|
|
6138
|
+
(value["id"] === "monthly-pin-time-aggregation" &&
|
|
6139
|
+
Array.isArray(value["environments"]) &&
|
|
6140
|
+
value["environments"].some((environment) => environment !== "development")))
|
|
6141
|
+
return "workflow_policy_binding";
|
|
5745
6142
|
return null;
|
|
5746
6143
|
}
|
|
5747
6144
|
const validRcmWorkflowCatalog = (value) => rcmWorkflowCatalogValidationError(value) === null;
|
|
@@ -5750,8 +6147,8 @@ exports.RcmWorkflowCatalogSchemaJson = {
|
|
|
5750
6147
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
5751
6148
|
$id: "https://nexalink.care/contracts/rcm-workflow-catalog.schema.json",
|
|
5752
6149
|
title: "RcmWorkflowCatalog",
|
|
5753
|
-
description: "A single authorized workflow entry. The catalog pins the workflow identifier, model policy, human-review policy, and output schema version that the runtime and portal may offer for
|
|
5754
|
-
version: "1.
|
|
6150
|
+
description: "A single authorized workflow entry. The catalog pins the workflow identifier, model policy, human-review policy, and output schema version that the runtime and portal may offer for registered coding workflows (currently rcm-coding-assistance and monthly-pin-time-aggregation). Customer configuration can never redefine these immutable server-side values.",
|
|
6151
|
+
version: "1.1.0",
|
|
5755
6152
|
type: "object",
|
|
5756
6153
|
additionalProperties: false,
|
|
5757
6154
|
required: [
|
|
@@ -5766,7 +6163,7 @@ exports.RcmWorkflowCatalogSchemaJson = {
|
|
|
5766
6163
|
properties: {
|
|
5767
6164
|
id: {
|
|
5768
6165
|
type: "string",
|
|
5769
|
-
enum: ["rcm-coding-assistance"],
|
|
6166
|
+
enum: ["rcm-coding-assistance", "monthly-pin-time-aggregation"],
|
|
5770
6167
|
},
|
|
5771
6168
|
name: {
|
|
5772
6169
|
type: "string",
|
|
@@ -5800,7 +6197,7 @@ exports.RcmWorkflowCatalogSchemaJson = {
|
|
|
5800
6197
|
properties: {
|
|
5801
6198
|
policyId: {
|
|
5802
6199
|
type: "string",
|
|
5803
|
-
|
|
6200
|
+
enum: ["carecompass-rcm-review-v1", "carecompass-pin-time-policy-v1"],
|
|
5804
6201
|
},
|
|
5805
6202
|
inferencePath: {
|
|
5806
6203
|
type: "string",
|
|
@@ -5846,4 +6243,51 @@ exports.RcmWorkflowCatalogSchemaJson = {
|
|
|
5846
6243
|
const: "rcm-grounded-human-review-v2",
|
|
5847
6244
|
},
|
|
5848
6245
|
},
|
|
6246
|
+
allOf: [
|
|
6247
|
+
{
|
|
6248
|
+
if: {
|
|
6249
|
+
properties: {
|
|
6250
|
+
id: {
|
|
6251
|
+
const: "rcm-coding-assistance",
|
|
6252
|
+
},
|
|
6253
|
+
},
|
|
6254
|
+
},
|
|
6255
|
+
then: {
|
|
6256
|
+
properties: {
|
|
6257
|
+
modelPolicy: {
|
|
6258
|
+
properties: {
|
|
6259
|
+
policyId: {
|
|
6260
|
+
const: "carecompass-rcm-review-v1",
|
|
6261
|
+
},
|
|
6262
|
+
},
|
|
6263
|
+
},
|
|
6264
|
+
},
|
|
6265
|
+
},
|
|
6266
|
+
},
|
|
6267
|
+
{
|
|
6268
|
+
if: {
|
|
6269
|
+
properties: {
|
|
6270
|
+
id: {
|
|
6271
|
+
const: "monthly-pin-time-aggregation",
|
|
6272
|
+
},
|
|
6273
|
+
},
|
|
6274
|
+
},
|
|
6275
|
+
then: {
|
|
6276
|
+
properties: {
|
|
6277
|
+
modelPolicy: {
|
|
6278
|
+
properties: {
|
|
6279
|
+
policyId: {
|
|
6280
|
+
const: "carecompass-pin-time-policy-v1",
|
|
6281
|
+
},
|
|
6282
|
+
},
|
|
6283
|
+
},
|
|
6284
|
+
environments: {
|
|
6285
|
+
items: {
|
|
6286
|
+
const: "development",
|
|
6287
|
+
},
|
|
6288
|
+
},
|
|
6289
|
+
},
|
|
6290
|
+
},
|
|
6291
|
+
},
|
|
6292
|
+
],
|
|
5849
6293
|
};
|