$id: https://github.com/CMSgov/qpp-measures-data/blob/master/measures/2021/measures-schema.yaml
$schema: http://json-schema.org/draft-07/schema
type: array
items: { $ref: '#/definitions/measure' }
uniqueItemProperties: ['measureId'] # used by ajv-keywords

definitions:
  measure:
    title: 'Measure'
    type: object
    anyOf:
      - { $ref: '#/definitions/iaMeasure' }
      - { $ref: '#/definitions/piMeasure' }
      - { $ref: '#/definitions/qualityMeasure' }
      - { $ref: '#/definitions/aggregateCostMeasure' }

  baseMeasure:
    title: 'Base Measure'
    type: object
    properties:
      measureId:
        type: string
        description: For quality measures, the measureId is the same as the quality number. For a Promoting Interoperability (PI, formerly ACI) measure, the measureId is the measure identifier for the PI measure, and for an improvement activity (IA) measure, the measureId is the measure identifier for the IA measure.
      title: { type: string }
      description: { type: string }
      category:
        description: 'QPP scoring category to which the measure belongs: Improvement Activities, Quality, Promoting Interoperability (formerly Advancing Care Information), and Cost.'
        enum: [ia, quality, pi, cost]
      metricType:
        description: Type of measurement that the measure requires in order to attest.
        enum: [boolean, proportion, singlePerformanceRate, multiPerformanceRate, registrySinglePerformanceRate, registryMultiPerformanceRate, nonProportion, cahps, costScore]
      firstPerformanceYear:
        description: Year in which the measure was introduced.
        type: integer
        default: 2017
      lastPerformanceYear:
        description: Year in which the measure was deprecated.
        type: [integer, 'null']
        default: 'null'
      measureSpecification:
        description: URL link for Measure Specification PDF to download by Submission Method.
        anyOf:
          - { $ref: '#/definitions/measureSpecification' }
          - { type: 'null' }
      measureSets:
        description: Quality measures can belong to multiple measure sets that represent different specialties.
        type: array
        items: { $ref: '#/definitions/measureSets' }
    required: [measureId, title, description, category, metricType, firstPerformanceYear, lastPerformanceYear]

  iaMeasure:
    $merge:
      source:
        { $ref: '#/definitions/baseMeasure' }
      with:
        title: 'IA Measure'
        type: object
        additionalProperties: false
        properties:
          category:
            enum: [ia]
          weight:
            description: Determines the points granted for attesting to the measure.
            enum: [null, medium, high]
            default: medium
          subcategoryId:
            description: IA category which the measure incentivizes.
            oneOf: [{ $ref: '#/definitions/subcategoryIds' }]
        required: [weight, subcategoryId]

  piMeasure:
    $merge:
      source:
        { $ref: '#/definitions/baseMeasure' }
      with:
        title: 'PI Measure'
        type: object
        additionalProperties: false
        properties:
          category:
            enum: [pi]
          reportingCategory:
            description: The reporting category of the PI measure.
            enum: [required, bonus, exclusion, null]
          objective:
            description: PI category which the measure incentivizes.
            oneOf: [{ $ref: '#/definitions/objectives' }]
          isRequired:
            description: If true, attesting to the measure is required in order to receive a non-zero PI score.
            type: boolean
            default: false
          isBonus:
            description: If true, attesting to the measure will qualify the provider for PI bonus points.
            type: boolean
            default: false
          substitutes:
            description: Identifiers of other PI measures that can be used instead of the current measure.
            oneOf: [{ $ref: '#/definitions/arrayOfStringIdentifiers' }]
          exclusion:
            description: Identifiers of other PI measures that can be submitted instead of current measure. Cannot submit both current measure and the exclusion measure.
        required: [objective, isRequired, isBonus, measureSets]

  aggregateCostMeasure:
    $merge:
      source:
        { $ref: '#/definitions/baseMeasure' }
      with:
        title: 'Cost Measure'
        type: object
        additionalProperties: false
        properties:
          category:
            enum: [cost]
          isInverse:
            description: If true, a lower performance rate correlates with better performance.
            type: boolean
            default: false
          overallAlgorithm:
            description: Formula to determine the overall performance rate, given multiple strata of performance rates. Only applicable to multiPerformanceRate measures.
            type: ['null', string]
          submissionMethods:
            description: Possible methods for submitting performance data for the measure.
            type: array

  qualityMeasure:
    $merge:
      source:
        { $ref: '#/definitions/baseMeasure' }
      with:
        title: 'Quality Measure'
        type: object
        additionalProperties: false
        properties:
          category:
            enum: [quality]
          nationalQualityStrategyDomain: { type: ['null', string] }
          measureType:
            description: Quality category which the measure incentivizes.
            oneOf: [{ $ref: '#/definitions/measureTypes' }]
          eMeasureId:
            description: Identifier for Electronic Clinical Quality Measures (ECQM).
            type: ['null', string]
          eMeasureUuid:
            description: UUID for Electronic Clinical Quality Measures (ECQM).
            type: string
          nqfEMeasureId:
            description: Identifier for measure specified in the Health Quality Measure Format (HQMF).
            type: ['null', string]
          nqfId:
            description: Identifier for the National Quality Forum (NQF) measure.
            type: ['null', string]
          isClinicalGuidelineChanged:
            description: True for measures that have been deemed as potentially no longer aligning with best practices or could lead to patient harm, false otherwise
            type: boolean
          clinicalGuidelineChanged:
            type: array
            items: { $ref: '#/definitions/methods' }
          isHighPriority:
            description: If true, can be used in the place of an outcome measure to satisfy quality category requirements.
            type: boolean
            default: false
          isInverse:
            description: If true, a lower performance rate correlates with better performance.
            type: boolean
            default: false
          overallAlgorithm:
            description: Formula to determine the overall performance rate, given multiple strata of performance rates. Only applicable to multiPerformanceRate measures.
            enum: [simpleAverage, weightedAverage, sumNumerators, overallStratumOnly]
          strata:
            description: Population segments for which the measure requires reporting data. Only applicable to multiPerformanceRate measures.
            type: array
            items: { $ref: '#/definitions/performanceStrata' }
          primarySteward:
            description: Organization who submits and maintains the measure.
            type: string
          submissionMethods:
            description: Possible methods for submitting performance data for the measure.
            type: array
            items: { $ref: '#/definitions/methods' }
          eligibilityOptions:
            description: Eligibility options mirror denominator options in QCDR measure specifications. Each option comprises a set of codes used to identify eligible instances of the associated measure.
            type: array
            items: { $ref: '#/definitions/eligibilityOption' }
          performanceOptions:
            description: Performance options mirror numerator options in QCDR measure specifications. Each option comprises a set of codes used to identify instances of performance met, performance not met, performance exclusion or performance exception.
            type: array
            items: { $ref: '#/definitions/performanceOption' }
          allowedPrograms:
            description: Programs that the measure can be submitted to
            type: array
            items: { $ref: '#/definitions/programs' }
          requiredForPrograms:
            description: Programs that the measure is required to be submitted to
            type: array
            items: { $ref: '#/definitions/programs' }
          allowedVendors:
            description: List of QCDR Registries that are allowed to submit the QCDR measure
            type: array
            items: { type: string }
          isRegistryMeasure:
            description: If true, this measure was authored by a QCDR (Qualified Clinical Data Registry).
            type: boolean
            default: false
          isRiskAdjusted:
            type: boolean
            default: false
          cpcPlusGroup:
            description: CPC+ group which the measure belongs
            type: string
          isIcdImpacted:
            type: boolean
            default: false
          icdImpacted:
            type: array
            items: { $ref: '#/definitions/methods' }
          benchmarks:
            type: object
            propertyNames: { $ref: '#/definitions/methods' }
            patternProperties:
              "":
                enum: [removed]

        # measures with metricType multiPerformanceRate must also have the properties overallAlgorithm and strata; other metricTypes do not
        # Note: Need to add back required: [overallAlgorithm, strata] for multiPerformanceRate, registryMultiPerformanceRate once strata data for 007 has been received
        oneOf: [
          {
            properties: {
              metricType: { enum: [multiPerformanceRate, registryMultiPerformanceRate] },
              strata: {
                type: 'array',
                minItems: 1,
                items: { $ref: '#/definitions/performanceStrata' }
              }
            },
            required: [overallAlgorithm, strata]
          },
          {
            properties: {
              metricType: { enum: [singlePerformanceRate, nonProportion, cahps, registrySinglePerformanceRate, costScore] }
            }
          }
        ]
        required: [nationalQualityStrategyDomain, measureType, eMeasureId, nqfEMeasureId, nqfId, isHighPriority, isInverse, primarySteward, submissionMethods, allowedPrograms, isRegistryMeasure, isIcdImpacted]

  performanceStrata:
    type: object
    properties:
      description:
        type: string
      name:
        type: string
        maxLength: 20
      eMeasureUuids:
        type: object
        properties:
          initialPopulationUuid:
            type: string
          denominatorUuid:
            type: string
          numeratorUuid:
            type: string
          denominatorExclusionUuid:
            type: string
          denominatorExceptionUuid:
            type: string

  subcategoryIds:
    enum:
      - null
      - achievingHealthEquity
      - behavioralAndMentalHealth
      - beneficiaryEngagement
      - careCoordination
      - emergencyResponseAndPreparedness
      - expandedPracticeAccess
      - patientSafetyAndPracticeAssessment
      - populationManagement

  objectives:
    enum:
      - attestation
      - publicHealthAndClinicalDataRegistryReporting
      - healthInformationExchange
      - electronicPrescribing
      - coordinationOfCareThroughPatientEngagement
      - patientElectronicAccess
      - protectPatientHealthInformation
      - publicHealthReporting
      - medicationReconciliation
      - patientSpecificEducation
      - secureMessaging
      - publicHealthAndClinicalDataExchange
      - providerToPatientExchange

  measureTypes:
    enum:
      - efficiency
      - intermediateOutcome
      - outcome
      - patientEngagementExperience
      - process
      - structure
      - patientReportedOutcome

  methods:
    enum:
      - administrativeClaims
      - claims
      - certifiedSurveyVendor
      - cmsWebInterface
      - electronicHealthRecord
      - registry

  measureSpecification:
    type: object
    properties:
      default:
        type: string
      registry:
        type: string
      claims:
        type: string
      cmsWebInterface:
        type: string
      measureInformation:
        type: string

  measureSets:
    enum:
      - transition # PI only
      - allergyImmunology
      - anesthesiology
      - cardiology
      - dentistry
      - dermatology
      - diagnosticRadiology
      - electrophysiologyCardiacSpecialist
      - emergencyMedicine
      - gastroenterology
      - generalSurgery
      - hospitalists
      - infectiousDisease
      - internalMedicine
      - interventionalRadiology
      - mentalBehavioralHealth
      - nephrology
      - neurology
      - neurosurgical
      - obstetricsGynecology
      - ophthalmology
      - orthopedicSurgery
      - otolaryngology
      - pathology
      - pediatrics
      - physicalMedicine
      - plasticSurgery
      - podiatry
      - preventiveMedicine
      - radiationOncology
      - rheumatology
      - thoracicSurgery
      - urology
      - vascularSurgery
      - familyMedicine
      - oncology
      - physicalTherapyOccupationalTherapy
      - geriatrics
      - urgentCare
      - skilledNursingFacility
      - generalPracticeFamilyMedicine
      - endocrinology
      - nutritionDietician
      - pulmonology
      - chiropracticMedicine
      - clinicalSocialWork
      - audiology
      - speechLanguagePathology

  eligibilityOption:
    type: object
    properties:
      sexCode:
        description: Gender identifier in the case of measures that apply to one gender only.
        enum: [M, F]
      minAge:
        description: The minimum patient age required for eligibility.
        type: number
      maxAge:
        description: The maximum patient age required for eligibility.
        type: number
      diagnosisCodes: { $ref: '#/definitions/arrayOfStringIdentifiers' }
      additionalDiagnosisCodes: { $ref: '#/definitions/arrayOfStringIdentifiers' }
      procedureCodes:
        description: A list of HCPCS or CPT codes, at least one of which must be present to meet the eligibility option.
        type: array
        items: { $ref: '#/definitions/codeObject' }
      additionalProcedureCodes:
        description: A list of HCPCS or CPT codes, at least one of which must be present to meet the eligibility option. If present, this field imposes a requirement in addition to the one from the procedureCodes field.
        type: array
        items: { $ref: '#/definitions/codeObject' }
      optionGroup:
        description: An identifier for grouping eligibility options together that need to be met together.
        type: string
    anyOf:
      - required: ['procedureCodes']
      - required: ['diagnosisCodes']

  performanceOption:
    type: object
    properties:
      optionType:
        description: The specific performance option corresponding to the quality codes (performance met, performance not met, etc.).
        enum: [performanceMet, performanceNotMet, eligiblePopulationExclusion, eligiblePopulationException]
      qualityCodes:
        description: A list of quality codes, all of which must be present to meet the performance option.
        type: array
        items: { $ref: '#/definitions/codeObject' }
      optionGroup:
        description: An identifier for grouping eligibility options together that need to be met together.
        type: string
    required: [optionType, qualityCodes]

  programs:
    enum:
      - mips
      - cpcPlus
      - pcf
      - app1

  codeObject:
    type: object
    properties:
      code:
        description: The HCPCS or CPT code represented as a string.
        type: string
      modifiers:  { $ref: '#/definitions/arrayOfStringIdentifiers' }
      modifierExclusions:  { $ref: '#/definitions/arrayOfStringIdentifiers' }
      placesOfService:  { $ref: '#/definitions/arrayOfStringIdentifiers' }
      placesOfServiceExclusions:  { $ref: '#/definitions/arrayOfStringIdentifiers' }
    required: [code]

  qualityCodesSubmissionMethods:
    type: array
    items:
      enum:
        - claims
        - registry

  arrayOfStringIdentifiers:
    type: array
    items:
      type: string
