// PolarisCoreAppConsent.fsh
// Defines the Polaris App Consent profile for patient consent to share data with third-party applications
// This profile is specifically designed to model patient consent for signing up with an app
// based on FHIR R4 Consent resource and Polaris standards.

Alias: $PolarisCoreAppConsent = https://fhir.apps.health/StructureDefinition/polaris-core-app-consent
Alias: $consent-status = http://hl7.org/fhir/consent-state-codes
Alias: $consent-category = http://terminology.hl7.org/CodeSystem/consentcategorycodes
Alias: $consent-scope = http://terminology.hl7.org/CodeSystem/consentscope
Alias: $consent-policy = http://terminology.hl7.org/CodeSystem/consentpolicycodes


// https://well-health.atlassian.net/wiki/spaces/POL/pages/6111297818/WIP+Consent+Management+-+Polaris+API+-+Technical+Musings


// Consent identifier must follow Polaris pattern
Invariant: app-consent-has-polaris-id
Description: "Must have at least one identifier whose system matches the Polaris app consent identifier pattern."
Severity: #error
Expression: "identifier.exists(system.matches('^https://fhir.apps.health/NamingSystem/[a-zA-Z0-9._-]+-app-consent-identifier$'))"

// Profile Definition
Profile:        PolarisCoreAppConsent
Parent:         Consent
Id:             polaris-core-app-consent
Title:          "Polaris App Consent Profile Core"
Description:    "Simple app consent profile: Patient X consented/refused to share information with Application Y (represented as a Device). This profile models consent for a patient to sign up with an app."
* ^url = $PolarisCoreAppConsent
* ^status = #draft
* obeys app-consent-has-polaris-id

* . ^short      = "Patient consent for app signup and data sharing Core"
* . ^definition = """
  Records whether a patient consented to or refused to sign up with a specific app and share data.
  This models the consent process when a patient decides to use a third-party application.
  The application is represented as a PolarisCoreAppDevice resource.
  """

* meta.source 0..1 MS
* meta.source ^short = "Identifies EMR instance & pipeline version the resource came from"
* meta.source ^definition = "A URI that identifies the EMR pipeline and version from which this resource originated.  This tells you which EMR instance (recommend using the instance identifier), and the version of the pipeline code/transformations."

// Essential elements only - KISS approach
* identifier 1..* MS
* identifier ^short = "Business identifier(s) for app consent"
* identifier ^definition = """
Unique identifiers for the app consent.

At least one must use the Polaris naming convention pattern.

When a source/local 'raw code' identifier exists (e.g. from source EMR),
it SHOULD be included as an additional identifier.

If the raw code's system is known and appropriate, use that.
If no recognized system exists, implementers MAY:
  • invent a URI for the system, OR
  • use the fallback URI template: https://fhir.apps.health/NamingSystem/<instance-id>-app-consent-raw-code
"""

// Identifier slicing setup
* identifier ^slicing.discriminator.type = #pattern
* identifier ^slicing.discriminator.path = "system"
* identifier ^slicing.rules = #open
* identifier ^slicing.description = "Slice identifiers by system"

// Define slices
* identifier contains
    polarisId 1..1 MS and
    rawCode 0..* MS

// Polaris ID slice (required)
* identifier[polarisId] ^short = "Polaris App Consent ID"
* identifier[polarisId] ^definition = "The primary Polaris identifier for this app consent, following the standard Polaris naming pattern"
* identifier[polarisId].system 1..1
* identifier[polarisId].system ^short = "Polaris app-consent identifier system: https://fhir.apps.health/NamingSystem/<instance-id>-app-consent-identifier"
* identifier[polarisId].system ^definition = "Must match the pattern: https://fhir.apps.health/NamingSystem/<instance-id>-app-consent-identifier"
* identifier[polarisId].system ^comment = "Example: https://fhir.apps.health/NamingSystem/clinic-12345-app-consent-identifier"
* identifier[polarisId].value 1..1
* identifier[polarisId].value ^short = "The actual Polaris app consent ID value: unique in source system"
* identifier[polarisId].use = #official

// Raw code identifier slice (optional, multiple allowed)
* identifier[rawCode] ^short = "Source EMR app consent identifier"
* identifier[rawCode] ^definition = "The original raw identifier(s) from the source EMR system"
* identifier[rawCode].system 1..1
* identifier[rawCode].system ^short = "Source system URI or https://fhir.apps.health/NamingSystem/<instance-id>-app-consent-raw-code"
* identifier[rawCode].system ^definition = """
URI identifying the code system for the raw code.
If the system is known, use the appropriate URI.
If unknown, use a constructed URI or the fallback:
`https://fhir.apps.health/NamingSystem/<instance-id>-app-consent-raw-code`
"""
* identifier[rawCode].value 1..1
* identifier[rawCode].use = #secondary
* identifier ^short = "Consent record identifier"

* status 1..1 MS
* status ^short = "active | draft | inactive | entered-in-error"
* status ^definition = "Required field in FHIR R4 Consent. Indicates the current state of this app consent."
* status from http://hl7.org/fhir/ValueSet/consent-state-codes (required)

* scope 1..1 MS
* scope ^short = "patient-privacy - Privacy consent"
* scope ^definition = "Required field in FHIR R4 Consent. For this app consent use case, always set to 'patient-privacy' as we're dealing with patient privacy consent for app data sharing."
* scope from http://hl7.org/fhir/ValueSet/consent-scope (required)
* scope ^fixedCodeableConcept.coding[0].system = "http://terminology.hl7.org/CodeSystem/consentscope"
* scope ^fixedCodeableConcept.coding[0].code = #patient-privacy
* scope ^fixedCodeableConcept.coding[0].display = "Privacy Consent"

* category 1..1 MS
* category ^short = "infa - Information Access"
* category ^definition = "Required field in FHIR R4 Consent. For this app consent use case, always set to 'infa' (Information Access) as we're controlling access to patient information by third-party apps."
* category from http://hl7.org/fhir/ValueSet/consent-category (required)
* category ^fixedCodeableConcept.coding[0].system = "http://terminology.hl7.org/CodeSystem/consentcategorycodes"
* category ^fixedCodeableConcept.coding[0].code = #infa
* category ^fixedCodeableConcept.coding[0].display = "Information Access"

* patient 1..1 MS
* patient only Reference(PolarisCorePatient)
* patient ^short = "The patient (Patient X)"

* dateTime 1..1 MS
* dateTime ^short = "When consent was given/withdrawn"

* policyRule 1..1 MS
* policyRule ^short = "cric - Common Rule Informed Consent"
* policyRule ^definition = "Required field in FHIR R4 Consent (either policy or policyRule must be present). For this app consent use case, always set to 'cric' (Common Rule Informed Consent) as this represents the consent policy framework."
* policyRule from http://hl7.org/fhir/ValueSet/consent-policy (required)
* policyRule ^fixedCodeableConcept.coding[0].system = "http://terminology.hl7.org/CodeSystem/consentpolicycodes"
* policyRule ^fixedCodeableConcept.coding[0].code = #cric
* policyRule ^fixedCodeableConcept.coding[0].display = "Common Rule Informed Consent"

// R4-compliant provision structure (complex but correct!)
* provision 1..1 MS
* provision ^short = "Consent rules for the app"
* provision ^definition = """
FHIR R4 consent modeling is complex but we follow it for compliance:
- GRANT CONSENT: Top-level provision with NO type (type not permitted in root)
- DENY CONSENT: Top-level provision with NO type + nested provision with type='deny'
- REQUEST INFO: Use status='proposed' instead of provision modeling
"""

* provision.type 0..1 MS
* provision.type ^short = "NOT used in root provision per R4 spec"
* provision.type ^definition = "Per FHIR R4: 'Not permitted in root rule, required in nested rules'. For denial, create nested provision with type='deny'."

* provision.actor 1..1 MS
* provision.actor ^short = "The third-party app (Application Y)"

* provision.actor.role 1..1 MS
* provision.actor.role ^short = "information-recipient"

* provision.actor.reference 1..1 MS
* provision.actor.reference only Reference(PolarisCoreAppDevice)
* provision.actor.reference ^short = "Reference to the app Device"

* sourceAttachment 0..1 MS
* sourceAttachment ^short = "Original consent document attachment"
* sourceAttachment ^definition = "The original consent document in the form of an attachment (text/base64/etc). Optional but useful for maintaining a record of the actual signed consent form."

