PackagesCanonicalsLogsProblems
    Packages
    io.health-samurai.core.r5@0.2604.2
    http://health-samurai.io/fhir/core/StructureDefinition/de-identification
{
  "description": "Extension for ViewDefinition columns that specifies a de-identification method and its parameters. Applied during SQL generation to wrap column expressions with the corresponding aidbox_deident_* PostgreSQL function.",
  "_filename": "StructureDefinition-de-identification.json",
  "package_name": "io.health-samurai.core.r5",
  "date": null,
  "derivation": "constraint",
  "publisher": null,
  "fhirVersion": "5.0.0",
  "name": "deIdentification",
  "abstract": false,
  "type": "Extension",
  "experimental": null,
  "resourceType": "StructureDefinition",
  "title": "De-Identification",
  "package_version": "0.2604.2",
  "status": "active",
  "id": "bccdc55e-8c6f-4c00-aab0-29ed1f7f8d49",
  "kind": "complex-type",
  "url": "http://health-samurai.io/fhir/core/StructureDefinition/de-identification",
  "context": [ {
    "type": "element",
    "expression": "Element"
  } ],
  "version": "0.2604.2",
  "differential": {
    "element": [ {
      "id": "Extension",
      "path": "Extension",
      "short": "De-identification method and parameters for a ViewDefinition column.",
      "constraint": [ {
        "key": "deident-1",
        "human": "cryptoHash method requires cryptoHashKey",
        "severity": "error",
        "expression": "extension.where(url='method').value = 'cryptoHash' implies extension.where(url='cryptoHashKey').exists()"
      }, {
        "key": "deident-2",
        "human": "dateshift method requires dateShiftKey",
        "severity": "error",
        "expression": "extension.where(url='method').value = 'dateshift' implies extension.where(url='dateShiftKey').exists()"
      }, {
        "key": "deident-3",
        "human": "encrypt method requires encryptKey",
        "severity": "error",
        "expression": "extension.where(url='method').value = 'encrypt' implies extension.where(url='encryptKey').exists()"
      }, {
        "key": "deident-4",
        "human": "substitute method requires replaceWith",
        "severity": "error",
        "expression": "extension.where(url='method').value = 'substitute' implies extension.where(url='replaceWith').exists()"
      }, {
        "key": "deident-5",
        "human": "custom_function method requires custom_function name",
        "severity": "error",
        "expression": "extension.where(url='method').value = 'custom_function' implies extension.where(url='custom_function').exists()"
      }, {
        "key": "deident-6",
        "human": "Must specify either method or custom_function",
        "severity": "error",
        "expression": "extension.where(url='method').exists() or extension.where(url='custom_function').exists()"
      } ],
      "definition": "Specifies which de-identification method to apply to a ViewDefinition column expression during SQL generation, along with method-specific parameters such as cryptographic keys or noise ranges."
    }, {
      "id": "Extension.extension",
      "min": 1,
      "path": "Extension.extension",
      "slicing": {
        "rules": "closed",
        "discriminator": [ {
          "path": "url",
          "type": "value"
        } ]
      }
    }, {
      "id": "Extension.extension:method",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "De-identification method to apply. Required unless custom_function is used.",
      "sliceName": "method"
    }, {
      "id": "Extension.extension:method.url",
      "path": "Extension.extension.url",
      "fixedUri": "method"
    }, {
      "id": "Extension.extension:method.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "code"
      } ],
      "binding": {
        "strength": "extensible",
        "valueSet": "http://health-samurai.io/fhir/core/ValueSet/de-identification-method"
      }
    }, {
      "id": "Extension.extension:cryptoHashKey",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "HMAC-SHA256 key for cryptoHash method.",
      "sliceName": "cryptoHashKey"
    }, {
      "id": "Extension.extension:cryptoHashKey.url",
      "path": "Extension.extension.url",
      "fixedUri": "cryptoHashKey"
    }, {
      "id": "Extension.extension:cryptoHashKey.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "string"
      } ]
    }, {
      "id": "Extension.extension:dateShiftKey",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "HMAC key for deterministic date shifting. Offset is derived from HMAC(key, resource.id).",
      "sliceName": "dateShiftKey"
    }, {
      "id": "Extension.extension:dateShiftKey.url",
      "path": "Extension.extension.url",
      "fixedUri": "dateShiftKey"
    }, {
      "id": "Extension.extension:dateShiftKey.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "string"
      } ]
    }, {
      "id": "Extension.extension:encryptKey",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "AES-128-CBC encryption key as hex string (32 hex chars = 16 bytes).",
      "sliceName": "encryptKey"
    }, {
      "id": "Extension.extension:encryptKey.url",
      "path": "Extension.extension.url",
      "fixedUri": "encryptKey"
    }, {
      "id": "Extension.extension:encryptKey.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "string"
      } ],
      "constraint": [ {
        "key": "deident-encryptkey-1",
        "human": "Encryption key must be 8-32 hex characters (0-9, a-f)",
        "severity": "error",
        "expression": "$this.matches('^[0-9a-fA-F]{8,32}$') and ($this.length() mod 2 = 0)"
      } ]
    }, {
      "id": "Extension.extension:replaceWith",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "Fixed replacement value for substitute method.",
      "sliceName": "replaceWith"
    }, {
      "id": "Extension.extension:replaceWith.url",
      "path": "Extension.extension.url",
      "fixedUri": "replaceWith"
    }, {
      "id": "Extension.extension:replaceWith.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "string"
      } ]
    }, {
      "id": "Extension.extension:span",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "Noise magnitude for perturb method.",
      "sliceName": "span"
    }, {
      "id": "Extension.extension:span.url",
      "path": "Extension.extension.url",
      "fixedUri": "span"
    }, {
      "id": "Extension.extension:span.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "decimal"
      } ]
    }, {
      "id": "Extension.extension:rangeType",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "Noise range type for perturb: fixed (absolute) or proportional (relative to value).",
      "sliceName": "rangeType"
    }, {
      "id": "Extension.extension:rangeType.url",
      "path": "Extension.extension.url",
      "fixedUri": "rangeType"
    }, {
      "id": "Extension.extension:rangeType.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "code"
      } ],
      "binding": {
        "strength": "extensible",
        "valueSet": "http://health-samurai.io/fhir/core/ValueSet/perturb-range-type"
      }
    }, {
      "id": "Extension.extension:roundTo",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "Decimal places to round to after perturbation. 0 means round to integer.",
      "sliceName": "roundTo"
    }, {
      "id": "Extension.extension:roundTo.url",
      "path": "Extension.extension.url",
      "fixedUri": "roundTo"
    }, {
      "id": "Extension.extension:roundTo.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "integer"
      } ]
    }, {
      "id": "Extension.extension:custom_function",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "Name of a custom PostgreSQL function to apply. First argument is the column value (text), optional second argument via custom_arg.",
      "sliceName": "custom_function"
    }, {
      "id": "Extension.extension:custom_function.url",
      "path": "Extension.extension.url",
      "fixedUri": "custom_function"
    }, {
      "id": "Extension.extension:custom_function.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "string"
      } ],
      "constraint": [ {
        "key": "deident-customfn-1",
        "human": "Function name must be a valid SQL identifier (letters, digits, underscores, dots)",
        "severity": "error",
        "expression": "$this.matches('^[a-zA-Z][a-zA-Z0-9_.]*$')"
      } ]
    }, {
      "id": "Extension.extension:custom_arg",
      "max": "1",
      "min": 0,
      "path": "Extension.extension",
      "short": "Optional second argument passed to the custom function.",
      "sliceName": "custom_arg"
    }, {
      "id": "Extension.extension:custom_arg.url",
      "path": "Extension.extension.url",
      "fixedUri": "custom_arg"
    }, {
      "id": "Extension.extension:custom_arg.value[x]",
      "min": 1,
      "path": "Extension.extension.value[x]",
      "type": [ {
        "code": "string"
      }, {
        "code": "integer"
      }, {
        "code": "decimal"
      }, {
        "code": "boolean"
      }, {
        "code": "code"
      } ]
    }, {
      "id": "Extension.url",
      "path": "Extension.url",
      "fixedUri": "http://health-samurai.io/fhir/core/StructureDefinition/de-identification"
    }, {
      "id": "Extension.value[x]",
      "max": "0",
      "path": "Extension.value[x]"
    } ]
  },
  "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Extension"
}