Source Code

;; insurance-claim - Clarity 4
;; Insurance claim processing and management system

(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-CLAIM-NOT-FOUND (err u101))
(define-constant ERR-ALREADY-PROCESSED (err u102))
(define-constant ERR-INVALID-AMOUNT (err u103))

(define-map insurance-claims uint
  {
    claimant: principal,
    provider: principal,
    insurer: principal,
    claim-amount: uint,
    approved-amount: (optional uint),
    claim-type: (string-ascii 50),
    diagnosis-codes: (list 5 (string-ascii 10)),
    procedure-codes: (list 5 (string-ascii 10)),
    filed-at: uint,
    processed-at: (optional uint),
    status: (string-ascii 20)
  }
)

(define-map claim-documents uint
  {
    claim-id: uint,
    document-type: (string-ascii 50),
    document-hash: (buff 64),
    uploaded-by: principal,
    uploaded-at: uint
  }
)

(define-map claim-adjudications uint
  {
    claim-id: uint,
    adjudicator: principal,
    decision: (string-ascii 20),
    reason: (string-utf8 500),
    approved-amount: uint,
    adjudicated-at: uint
  }
)

(define-map claim-appeals uint
  {
    original-claim-id: uint,
    appellant: principal,
    appeal-reason: (string-utf8 500),
    supporting-docs: (list 5 (buff 64)),
    filed-at: uint,
    appeal-status: (string-ascii 20)
  }
)

(define-data-var claim-counter uint u0)
(define-data-var document-counter uint u0)
(define-data-var adjudication-counter uint u0)
(define-data-var appeal-counter uint u0)

(define-public (file-claim
    (provider principal)
    (insurer principal)
    (claim-amount uint)
    (claim-type (string-ascii 50))
    (diagnosis-codes (list 5 (string-ascii 10)))
    (procedure-codes (list 5 (string-ascii 10))))
  (let ((claim-id (+ (var-get claim-counter) u1)))
    (asserts! (> claim-amount u0) ERR-INVALID-AMOUNT)
    (map-set insurance-claims claim-id
      {
        claimant: tx-sender,
        provider: provider,
        insurer: insurer,
        claim-amount: claim-amount,
        approved-amount: none,
        claim-type: claim-type,
        diagnosis-codes: diagnosis-codes,
        procedure-codes: procedure-codes,
        filed-at: stacks-block-time,
        processed-at: none,
        status: "pending"
      })
    (var-set claim-counter claim-id)
    (ok claim-id)))

(define-public (upload-claim-document
    (claim-id uint)
    (document-type (string-ascii 50))
    (document-hash (buff 64)))
  (let ((claim (unwrap! (map-get? insurance-claims claim-id) ERR-CLAIM-NOT-FOUND))
        (document-id (+ (var-get document-counter) u1)))
    (asserts! (or (is-eq tx-sender (get claimant claim))
                  (is-eq tx-sender (get provider claim))) ERR-NOT-AUTHORIZED)
    (map-set claim-documents document-id
      {
        claim-id: claim-id,
        document-type: document-type,
        document-hash: document-hash,
        uploaded-by: tx-sender,
        uploaded-at: stacks-block-time
      })
    (var-set document-counter document-id)
    (ok document-id)))

(define-public (adjudicate-claim
    (claim-id uint)
    (decision (string-ascii 20))
    (reason (string-utf8 500))
    (approved-amount uint))
  (let ((claim (unwrap! (map-get? insurance-claims claim-id) ERR-CLAIM-NOT-FOUND))
        (adjudication-id (+ (var-get adjudication-counter) u1)))
    (asserts! (is-eq tx-sender (get insurer claim)) ERR-NOT-AUTHORIZED)
    (asserts! (is-eq (get status claim) "pending") ERR-ALREADY-PROCESSED)
    (map-set claim-adjudications adjudication-id
      {
        claim-id: claim-id,
        adjudicator: tx-sender,
        decision: decision,
        reason: reason,
        approved-amount: approved-amount,
        adjudicated-at: stacks-block-time
      })
    (map-set insurance-claims claim-id
      (merge claim {
        approved-amount: (some approved-amount),
        processed-at: (some stacks-block-time),
        status: decision
      }))
    (var-set adjudication-counter adjudication-id)
    (ok adjudication-id)))

(define-public (file-appeal
    (claim-id uint)
    (appeal-reason (string-utf8 500))
    (supporting-docs (list 5 (buff 64))))
  (let ((claim (unwrap! (map-get? insurance-claims claim-id) ERR-CLAIM-NOT-FOUND))
        (appeal-id (+ (var-get appeal-counter) u1)))
    (asserts! (is-eq tx-sender (get claimant claim)) ERR-NOT-AUTHORIZED)
    (asserts! (not (is-eq (get status claim) "pending")) ERR-NOT-AUTHORIZED)
    (map-set claim-appeals appeal-id
      {
        original-claim-id: claim-id,
        appellant: tx-sender,
        appeal-reason: appeal-reason,
        supporting-docs: supporting-docs,
        filed-at: stacks-block-time,
        appeal-status: "pending"
      })
    (var-set appeal-counter appeal-id)
    (ok appeal-id)))

(define-public (update-claim-status
    (claim-id uint)
    (new-status (string-ascii 20)))
  (let ((claim (unwrap! (map-get? insurance-claims claim-id) ERR-CLAIM-NOT-FOUND)))
    (asserts! (is-eq tx-sender (get insurer claim)) ERR-NOT-AUTHORIZED)
    (ok (map-set insurance-claims claim-id
      (merge claim { status: new-status })))))

(define-read-only (get-claim (claim-id uint))
  (ok (map-get? insurance-claims claim-id)))

(define-read-only (get-claim-document (document-id uint))
  (ok (map-get? claim-documents document-id)))

(define-read-only (get-adjudication (adjudication-id uint))
  (ok (map-get? claim-adjudications adjudication-id)))

(define-read-only (get-appeal (appeal-id uint))
  (ok (map-get? claim-appeals appeal-id)))

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

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

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

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

Functions (13)

FunctionAccessArgs
get-adjudicationread-onlyadjudication-id: uint
get-appealread-onlyappeal-id: uint
validate-principalread-onlyp: principal
format-claim-idread-onlyclaim-id: uint
parse-claim-idread-onlyid-str: (string-ascii 20
get-bitcoin-blockread-only
get-claimread-onlyclaim-id: uint
get-claim-documentread-onlydocument-id: uint
file-claimpublicprovider: principal, insurer: principal, claim-amount: uint, claim-type: (string-ascii 50
upload-claim-documentpublicclaim-id: uint, document-type: (string-ascii 50
adjudicate-claimpublicclaim-id: uint, decision: (string-ascii 20
file-appealpublicclaim-id: uint, appeal-reason: (string-utf8 500
update-claim-statuspublicclaim-id: uint, new-status: (string-ascii 20