Source Code

;; institution-reputation - Clarity 4
;; Institution reputation scoring and trust management

(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-INSTITUTION-NOT-FOUND (err u101))
(define-constant ERR-INVALID-RATING (err u102))
(define-constant ERR-ALREADY-RATED (err u103))

(define-map institutions principal
  {
    institution-name: (string-utf8 200),
    institution-type: (string-ascii 50),
    registration-number: (string-ascii 100),
    reputation-score: uint,
    total-ratings: uint,
    verified-status: bool,
    registered-at: uint
  }
)

(define-map reputation-ratings { institution: principal, rater: principal }
  {
    rating-score: uint,
    rating-category: (string-ascii 50),
    comment: (string-utf8 500),
    rated-at: uint,
    is-verified: bool
  }
)

(define-map performance-metrics principal
  {
    compliance-score: uint,
    data-security-score: uint,
    response-time-score: uint,
    patient-satisfaction: uint,
    last-updated: uint
  }
)

(define-map accreditation-records uint
  {
    institution: principal,
    accrediting-body: (string-utf8 100),
    accreditation-level: (string-ascii 50),
    score: uint,
    issued-date: uint,
    expiry-date: uint
  }
)

(define-map incident-reports uint
  {
    institution: principal,
    incident-type: (string-ascii 50),
    severity: uint,
    reported-by: principal,
    reported-at: uint,
    resolution-status: (string-ascii 20),
    impact-on-reputation: uint
  }
)

(define-data-var accreditation-counter uint u0)
(define-data-var incident-counter uint u0)
(define-data-var base-reputation-score uint u50)

(define-public (register-institution
    (institution-name (string-utf8 200))
    (institution-type (string-ascii 50))
    (registration-number (string-ascii 100)))
  (ok (map-set institutions tx-sender
    {
      institution-name: institution-name,
      institution-type: institution-type,
      registration-number: registration-number,
      reputation-score: (var-get base-reputation-score),
      total-ratings: u0,
      verified-status: false,
      registered-at: stacks-block-time
    })))

(define-public (submit-rating
    (institution principal)
    (rating-score uint)
    (rating-category (string-ascii 50))
    (comment (string-utf8 500)))
  (let ((inst-data (unwrap! (map-get? institutions institution) ERR-INSTITUTION-NOT-FOUND)))
    (asserts! (<= rating-score u100) ERR-INVALID-RATING)
    (asserts! (is-none (map-get? reputation-ratings { institution: institution, rater: tx-sender })) ERR-ALREADY-RATED)
    (map-set reputation-ratings { institution: institution, rater: tx-sender }
      {
        rating-score: rating-score,
        rating-category: rating-category,
        comment: comment,
        rated-at: stacks-block-time,
        is-verified: false
      })
    (try! (update-reputation-score institution rating-score))
    (ok true)))

(define-public (update-performance-metrics
    (compliance-score uint)
    (data-security-score uint)
    (response-time-score uint)
    (patient-satisfaction uint))
  (let ((inst-data (unwrap! (map-get? institutions tx-sender) ERR-INSTITUTION-NOT-FOUND)))
    (ok (map-set performance-metrics tx-sender
      {
        compliance-score: compliance-score,
        data-security-score: data-security-score,
        response-time-score: response-time-score,
        patient-satisfaction: patient-satisfaction,
        last-updated: stacks-block-time
      }))))

(define-public (add-accreditation
    (accrediting-body (string-utf8 100))
    (accreditation-level (string-ascii 50))
    (score uint)
    (expiry-date uint))
  (let ((accred-id (+ (var-get accreditation-counter) u1))
        (inst-data (unwrap! (map-get? institutions tx-sender) ERR-INSTITUTION-NOT-FOUND)))
    (map-set accreditation-records accred-id
      {
        institution: tx-sender,
        accrediting-body: accrediting-body,
        accreditation-level: accreditation-level,
        score: score,
        issued-date: stacks-block-time,
        expiry-date: expiry-date
      })
    (var-set accreditation-counter accred-id)
    (ok accred-id)))

(define-public (report-incident
    (institution principal)
    (incident-type (string-ascii 50))
    (severity uint))
  (let ((incident-id (+ (var-get incident-counter) u1))
        (inst-data (unwrap! (map-get? institutions institution) ERR-INSTITUTION-NOT-FOUND)))
    (map-set incident-reports incident-id
      {
        institution: institution,
        incident-type: incident-type,
        severity: severity,
        reported-by: tx-sender,
        reported-at: stacks-block-time,
        resolution-status: "open",
        impact-on-reputation: severity
      })
    (try! (adjust-reputation-for-incident institution severity))
    (var-set incident-counter incident-id)
    (ok incident-id)))

(define-public (verify-institution (institution principal))
  (let ((inst-data (unwrap! (map-get? institutions institution) ERR-INSTITUTION-NOT-FOUND)))
    (ok (map-set institutions institution
      (merge inst-data { verified-status: true })))))

(define-private (update-reputation-score (institution principal) (new-rating uint))
  (let ((inst-data (unwrap! (map-get? institutions institution) ERR-INSTITUTION-NOT-FOUND))
        (current-score (get reputation-score inst-data))
        (total-ratings (get total-ratings inst-data))
        (new-total-ratings (+ total-ratings u1))
        (new-score (/ (+ (* current-score total-ratings) new-rating) new-total-ratings)))
    (map-set institutions institution
      (merge inst-data {
        reputation-score: new-score,
        total-ratings: new-total-ratings
      }))
    (ok true)))

(define-private (adjust-reputation-for-incident (institution principal) (severity uint))
  (let ((inst-data (unwrap! (map-get? institutions institution) ERR-INSTITUTION-NOT-FOUND))
        (penalty (/ severity u2))
        (new-score (if (>= (get reputation-score inst-data) penalty)
                      (- (get reputation-score inst-data) penalty)
                      u0)))
    (map-set institutions institution
      (merge inst-data { reputation-score: new-score }))
    (ok true)))

(define-read-only (get-institution (institution principal))
  (ok (map-get? institutions institution)))

(define-read-only (get-rating (institution principal) (rater principal))
  (ok (map-get? reputation-ratings { institution: institution, rater: rater })))

(define-read-only (get-performance-metrics (institution principal))
  (ok (map-get? performance-metrics institution)))

(define-read-only (get-accreditation (accreditation-id uint))
  (ok (map-get? accreditation-records accreditation-id)))

(define-read-only (get-incident (incident-id uint))
  (ok (map-get? incident-reports incident-id)))

(define-read-only (validate-principal (p principal))
  (principal-destruct? p))

(define-read-only (format-incident-id (incident-id uint))
  (ok (int-to-ascii incident-id)))

(define-read-only (parse-incident-id (id-str (string-ascii 20)))
  (string-to-uint? id-str))

(define-read-only (get-bitcoin-block)
  (ok burn-block-height))

Functions (17)

FunctionAccessArgs
register-institutionpublicinstitution-name: (string-utf8 200
submit-ratingpublicinstitution: principal, rating-score: uint, rating-category: (string-ascii 50
update-performance-metricspubliccompliance-score: uint, data-security-score: uint, response-time-score: uint, patient-satisfaction: uint
add-accreditationpublicaccrediting-body: (string-utf8 100
report-incidentpublicinstitution: principal, incident-type: (string-ascii 50
verify-institutionpublicinstitution: principal
update-reputation-scoreprivateinstitution: principal, new-rating: uint
adjust-reputation-for-incidentprivateinstitution: principal, severity: uint
get-institutionread-onlyinstitution: principal
get-ratingread-onlyinstitution: principal, rater: principal
get-performance-metricsread-onlyinstitution: principal
get-accreditationread-onlyaccreditation-id: uint
get-incidentread-onlyincident-id: uint
validate-principalread-onlyp: principal
format-incident-idread-onlyincident-id: uint
parse-incident-idread-onlyid-str: (string-ascii 20
get-bitcoin-blockread-only