Source Code

;; title: STXMainLedge
;; version:
;; summary:
;; description:

;; Enables transparent tracking of health equipment lifecycle and validations

;; title: health
;; version:
;; summary:
;; description:
(define-trait health-equipment-tracking-trait (
  (register-equipment
    (uint uint)
    (response bool uint)
  )
  (update-equipment-phase
    (uint uint)
    (response bool uint)
  )
  (get-equipment-timeline
    (uint)
    (
      response       (list 10 {
      phase: uint,
      timestamp: uint,
    })
      uint
    )
  )
  (add-validation
    (uint uint principal)
    (response bool uint)
  )
  (verify-validation
    (uint uint)
    (response bool uint)
  )
))

;; traits
;;
;; Define equipment phase constants
(define-constant EQUIPMENT_PHASE_PRODUCED u1)
(define-constant EQUIPMENT_PHASE_EVALUATION u2)
(define-constant EQUIPMENT_PHASE_ACTIVE u3)
(define-constant EQUIPMENT_PHASE_SERVICED u4)

;; token definitions
;;
;; Define validation type constants
(define-constant VALIDATION_TYPE_FDA u1)
(define-constant VALIDATION_TYPE_CE u2)
(define-constant VALIDATION_TYPE_ISO u3)
(define-constant VALIDATION_TYPE_SAFETY u4)

;; constants
;;
;; Error constants
(define-constant ERR_UNAUTHORIZED (err u1))
(define-constant ERR_INVALID_EQUIPMENT (err u2))
(define-constant ERR_PHASE_UPDATE_FAILED (err u3))
(define-constant ERR_INVALID_PHASE (err u4))
(define-constant ERR_INVALID_VALIDATION (err u5))
(define-constant ERR_VALIDATION_EXISTS (err u6))

;; data vars
;;
;; Contract owner
(define-data-var admin-principal principal tx-sender)

;; data maps
;;
;; Current timestamp counter
(define-data-var time-sequence uint u0)

;; public functions
;;
;; Equipment tracking map
(define-map equipment-data
  { equipment-id: uint }
  {
    owner: principal,
    current-phase: uint,
    timeline: (list 10 {
      phase: uint,
      timestamp: uint,
    }),
  }
)

;; read only functions
;;
;; Validation tracking map
(define-map equipment-validations
  {
    equipment-id: uint,
    validation-type: uint,
  }
  {
    validator: principal,
    timestamp: uint,
    active: bool,
  }
)

;; private functions
;;
;; Approved regulatory authorities
(define-map regulatory-authorities
  {
    authority: principal,
    validation-type: uint,
  }
  { approved: bool }
)

;; Get current timestamp and increment counter
(define-private (get-current-time)
  (begin
    (var-set time-sequence (+ (var-get time-sequence) u1))
    (var-get time-sequence)
  )
)

;; Only contract admin can perform certain actions
(define-read-only (is-admin (sender principal))
  (is-eq sender (var-get admin-principal))
)

;; Validate phase
(define-private (is-valid-phase (phase uint))
  (or
    (is-eq phase EQUIPMENT_PHASE_PRODUCED)
    (is-eq phase EQUIPMENT_PHASE_EVALUATION)
    (is-eq phase EQUIPMENT_PHASE_ACTIVE)
    (is-eq phase EQUIPMENT_PHASE_SERVICED)
  )
)

;; Validate validation type
(define-private (is-valid-validation-type (validation-type uint))
  (or
    (is-eq validation-type VALIDATION_TYPE_FDA)
    (is-eq validation-type VALIDATION_TYPE_CE)
    (is-eq validation-type VALIDATION_TYPE_ISO)
    (is-eq validation-type VALIDATION_TYPE_SAFETY)
  )
)

;; Validate equipment ID
(define-private (is-valid-equipment-id (equipment-id uint))
  (and (> equipment-id u0) (<= equipment-id u1000000))
)

;; Check if sender is approved regulatory authority
(define-private (is-regulatory-authority
    (authority principal)
    (validation-type uint)
  )
  (default-to false
    (get approved
      (map-get? regulatory-authorities {
        authority: authority,
        validation-type: validation-type,
      })
    ))
)

;; Register a new equipment
(define-public (register-equipment
    (equipment-id uint)
    (initial-phase uint)
  )
  (begin
    (asserts! (is-valid-equipment-id equipment-id) ERR_INVALID_EQUIPMENT)
    (asserts! (is-valid-phase initial-phase) ERR_INVALID_PHASE)
    (asserts!
      (or (is-admin tx-sender) (is-eq initial-phase EQUIPMENT_PHASE_PRODUCED))
      ERR_UNAUTHORIZED
    )

    (map-set equipment-data { equipment-id: equipment-id } {
      owner: tx-sender,
      current-phase: initial-phase,
      timeline: (list {
        phase: initial-phase,
        timestamp: (get-current-time),
      }),
    })
    (ok true)
  )
)

;; Update equipment phase
(define-public (update-equipment-phase
    (equipment-id uint)
    (new-phase uint)
  )
  (let ((equipment (unwrap! (map-get? equipment-data { equipment-id: equipment-id })
      ERR_INVALID_EQUIPMENT
    )))
    (asserts! (is-valid-equipment-id equipment-id) ERR_INVALID_EQUIPMENT)
    (asserts! (is-valid-phase new-phase) ERR_INVALID_PHASE)
    (asserts!
      (or
        (is-admin tx-sender)
        (is-eq (get owner equipment) tx-sender)
      )
      ERR_UNAUTHORIZED
    )

    (map-set equipment-data { equipment-id: equipment-id }
      (merge equipment {
        current-phase: new-phase,
        timeline: (unwrap-panic (as-max-len?
          (append (get timeline equipment) {
            phase: new-phase,
            timestamp: (get-current-time),
          })
          u10
        )),
      })
    )
    (ok true)
  )
)

;; Validate authority principal
(define-private (is-valid-authority (authority principal))
  (and
    (not (is-eq authority (var-get admin-principal))) ;; Authority can't be contract admin
    (not (is-eq authority tx-sender)) ;; Authority can't be the sender
    (not (is-eq authority 'SP000000000000000000002Q6VF78)) ;; Not zero address
  )
)

;; Add regulatory authority with additional validation
(define-public (add-regulatory-authority
    (authority principal)
    (validation-type uint)
  )
  (begin
    (asserts! (is-admin tx-sender) ERR_UNAUTHORIZED)
    (asserts! (is-valid-validation-type validation-type) ERR_INVALID_VALIDATION)
    (asserts! (is-valid-authority authority) ERR_UNAUTHORIZED)

    ;; After validation, we can safely use the authority
    (map-set regulatory-authorities {
      authority: authority,
      validation-type: validation-type,
    } { approved: true }
    )
    (ok true)
  )
)

;; Add validation to equipment
(define-public (add-validation
    (equipment-id uint)
    (validation-type uint)
  )
  (begin
    (asserts! (is-valid-equipment-id equipment-id) ERR_INVALID_EQUIPMENT)
    (asserts! (is-valid-validation-type validation-type) ERR_INVALID_VALIDATION)
    (asserts! (is-regulatory-authority tx-sender validation-type)
      ERR_UNAUTHORIZED
    )

    (asserts!
      (is-none (map-get? equipment-validations {
        equipment-id: equipment-id,
        validation-type: validation-type,
      }))
      ERR_VALIDATION_EXISTS
    )

    (let (
        (validated-equipment-id equipment-id)
        (validated-validation-type validation-type)
      )
      (map-set equipment-validations {
        equipment-id: validated-equipment-id,
        validation-type: validated-validation-type,
      } {
        validator: tx-sender,
        timestamp: (get-current-time),
        active: true,
      })
      (ok true)
    )
  )
)

;; Verify equipment validation
(define-read-only (verify-validation
    (equipment-id uint)
    (validation-type uint)
  )
  (let ((validation (unwrap!
      (map-get? equipment-validations {
        equipment-id: equipment-id,
        validation-type: validation-type,
      })
      ERR_INVALID_VALIDATION
    )))
    (ok (get active validation))
  )
)

;; Revoke validation
(define-public (revoke-validation
    (equipment-id uint)
    (validation-type uint)
  )
  (begin
    (asserts! (is-valid-equipment-id equipment-id) ERR_INVALID_EQUIPMENT)
    (asserts! (is-valid-validation-type validation-type) ERR_INVALID_VALIDATION)

    (let (
        (validation (unwrap!
          (map-get? equipment-validations {
            equipment-id: equipment-id,
            validation-type: validation-type,
          })
          ERR_INVALID_VALIDATION
        ))
        (validated-equipment-id equipment-id)
        (validated-validation-type validation-type)
      )
      (asserts!
        (or
          (is-admin tx-sender)
          (is-eq (get validator validation) tx-sender)
        )
        ERR_UNAUTHORIZED
      )

      (map-set equipment-validations {
        equipment-id: validated-equipment-id,
        validation-type: validated-validation-type,
      }
        (merge validation { active: false })
      )
      (ok true)
    )
  )
)

;; Get equipment timeline
(define-read-only (get-equipment-timeline (equipment-id uint))
  (let ((equipment (unwrap! (map-get? equipment-data { equipment-id: equipment-id })
      ERR_INVALID_EQUIPMENT
    )))
    (ok (get timeline equipment))
  )
)

;; Get current equipment phase
(define-read-only (get-equipment-phase (equipment-id uint))
  (let ((equipment (unwrap! (map-get? equipment-data { equipment-id: equipment-id })
      ERR_INVALID_EQUIPMENT
    )))
    (ok (get current-phase equipment))
  )
)

;; Get validation details
(define-read-only (get-validation-details
    (equipment-id uint)
    (validation-type uint)
  )
  (ok (map-get? equipment-validations {
    equipment-id: equipment-id,
    validation-type: validation-type,
  }))
)

Functions (8)

FunctionAccessArgs
get-equipment-phaseread-onlyequipment-id: uint
get-current-timeprivate
is-adminread-onlysender: principal
is-valid-phaseprivatephase: uint
is-valid-validation-typeprivatevalidation-type: uint
is-valid-equipment-idprivateequipment-id: uint
is-valid-authorityprivateauthority: principal
get-equipment-timelineread-onlyequipment-id: uint