Source Code

;; genome-versioning - Clarity 4
;; Version control for genomic datasets

(define-constant ERR-VERSION-NOT-FOUND (err u100))
(define-constant ERR-NOT-AUTHORIZED (err u101))
(define-constant ERR-INVALID-VERSION (err u102))
(define-constant ERR-VERSION-CONFLICT (err u103))

(define-map versions uint
  {
    data-id: uint,
    version-number: uint,
    data-hash: (buff 64),
    created-by: principal,
    created-at: uint,
    notes: (string-utf8 200),
    parent-version: (optional uint),
    is-stable: bool,
    changelog: (string-utf8 500)
  }
)

(define-map version-metadata uint
  {
    version-id: uint,
    file-size: uint,
    compression-type: (string-ascii 20),
    checksum: (buff 32),
    format-version: (string-ascii 20),
    schema-version: uint
  }
)

(define-map version-tags { version-id: uint, tag-name: (string-ascii 50) }
  {
    tag-type: (string-ascii 20),
    created-at: uint,
    created-by: principal,
    description: (string-utf8 200)
  }
)

(define-map version-branches uint
  {
    data-id: uint,
    branch-name: (string-ascii 50),
    base-version: uint,
    head-version: uint,
    created-by: principal,
    created-at: uint,
    is-merged: bool
  }
)

(define-map version-diffs uint
  {
    from-version: uint,
    to-version: uint,
    diff-hash: (buff 64),
    changes-count: uint,
    computed-at: uint,
    computed-by: principal
  }
)

(define-map merge-operations uint
  {
    source-version: uint,
    target-version: uint,
    merged-version: uint,
    merge-strategy: (string-ascii 50),
    conflicts-count: uint,
    merged-by: principal,
    merged-at: uint
  }
)

(define-data-var version-counter uint u0)
(define-data-var metadata-counter uint u0)
(define-data-var branch-counter uint u0)
(define-data-var diff-counter uint u0)
(define-data-var merge-counter uint u0)

(define-public (create-version
    (data-id uint)
    (version-number uint)
    (data-hash (buff 64))
    (notes (string-utf8 200))
    (parent-version (optional uint))
    (changelog (string-utf8 500)))
  (let ((version-id (+ (var-get version-counter) u1)))
    (map-set versions version-id
      {
        data-id: data-id,
        version-number: version-number,
        data-hash: data-hash,
        created-by: tx-sender,
        created-at: stacks-block-time,
        notes: notes,
        parent-version: parent-version,
        is-stable: false,
        changelog: changelog
      })
    (var-set version-counter version-id)
    (ok version-id)))

(define-public (add-version-metadata
    (version-id uint)
    (file-size uint)
    (compression-type (string-ascii 20))
    (checksum (buff 32))
    (format-version (string-ascii 20))
    (schema-version uint))
  (let ((metadata-id (+ (var-get metadata-counter) u1)))
    (asserts! (is-some (map-get? versions version-id)) ERR-VERSION-NOT-FOUND)
    (map-set version-metadata metadata-id
      {
        version-id: version-id,
        file-size: file-size,
        compression-type: compression-type,
        checksum: checksum,
        format-version: format-version,
        schema-version: schema-version
      })
    (var-set metadata-counter metadata-id)
    (ok metadata-id)))

(define-public (tag-version
    (version-id uint)
    (tag-name (string-ascii 50))
    (tag-type (string-ascii 20))
    (description (string-utf8 200)))
  (begin
    (asserts! (is-some (map-get? versions version-id)) ERR-VERSION-NOT-FOUND)
    (map-set version-tags { version-id: version-id, tag-name: tag-name }
      {
        tag-type: tag-type,
        created-at: stacks-block-time,
        created-by: tx-sender,
        description: description
      })
    (ok true)))

(define-public (create-branch
    (data-id uint)
    (branch-name (string-ascii 50))
    (base-version uint))
  (let ((branch-id (+ (var-get branch-counter) u1)))
    (asserts! (is-some (map-get? versions base-version)) ERR-VERSION-NOT-FOUND)
    (map-set version-branches branch-id
      {
        data-id: data-id,
        branch-name: branch-name,
        base-version: base-version,
        head-version: base-version,
        created-by: tx-sender,
        created-at: stacks-block-time,
        is-merged: false
      })
    (var-set branch-counter branch-id)
    (ok branch-id)))

(define-public (compute-diff
    (from-version uint)
    (to-version uint)
    (diff-hash (buff 64))
    (changes-count uint))
  (let ((diff-id (+ (var-get diff-counter) u1)))
    (asserts! (is-some (map-get? versions from-version)) ERR-VERSION-NOT-FOUND)
    (asserts! (is-some (map-get? versions to-version)) ERR-VERSION-NOT-FOUND)
    (map-set version-diffs diff-id
      {
        from-version: from-version,
        to-version: to-version,
        diff-hash: diff-hash,
        changes-count: changes-count,
        computed-at: stacks-block-time,
        computed-by: tx-sender
      })
    (var-set diff-counter diff-id)
    (ok diff-id)))

(define-public (merge-versions
    (source-version uint)
    (target-version uint)
    (merged-version uint)
    (merge-strategy (string-ascii 50))
    (conflicts-count uint))
  (let ((merge-id (+ (var-get merge-counter) u1)))
    (map-set merge-operations merge-id
      {
        source-version: source-version,
        target-version: target-version,
        merged-version: merged-version,
        merge-strategy: merge-strategy,
        conflicts-count: conflicts-count,
        merged-by: tx-sender,
        merged-at: stacks-block-time
      })
    (var-set merge-counter merge-id)
    (ok merge-id)))

(define-public (mark-stable (version-id uint))
  (let ((version (unwrap! (map-get? versions version-id) ERR-VERSION-NOT-FOUND)))
    (asserts! (is-eq tx-sender (get created-by version)) ERR-NOT-AUTHORIZED)
    (ok (map-set versions version-id
      (merge version { is-stable: true })))))

(define-read-only (get-version (version-id uint))
  (ok (map-get? versions version-id)))

(define-read-only (get-version-metadata (metadata-id uint))
  (ok (map-get? version-metadata metadata-id)))

(define-read-only (get-version-tag (version-id uint) (tag-name (string-ascii 50)))
  (ok (map-get? version-tags { version-id: version-id, tag-name: tag-name })))

(define-read-only (get-branch (branch-id uint))
  (ok (map-get? version-branches branch-id)))

(define-read-only (get-diff (diff-id uint))
  (ok (map-get? version-diffs diff-id)))

(define-read-only (get-merge (merge-id uint))
  (ok (map-get? merge-operations merge-id)))

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

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

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

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

Functions (17)

FunctionAccessArgs
get-diffread-onlydiff-id: uint
create-versionpublicdata-id: uint, version-number: uint, data-hash: (buff 64
add-version-metadatapublicversion-id: uint, file-size: uint, compression-type: (string-ascii 20
tag-versionpublicversion-id: uint, tag-name: (string-ascii 50
create-branchpublicdata-id: uint, branch-name: (string-ascii 50
compute-diffpublicfrom-version: uint, to-version: uint, diff-hash: (buff 64
merge-versionspublicsource-version: uint, target-version: uint, merged-version: uint, merge-strategy: (string-ascii 50
mark-stablepublicversion-id: uint
get-versionread-onlyversion-id: uint
get-version-metadataread-onlymetadata-id: uint
get-version-tagread-onlyversion-id: uint, tag-name: (string-ascii 50
get-branchread-onlybranch-id: uint
get-mergeread-onlymerge-id: uint
validate-creatorread-onlycreator: principal
format-version-idread-onlyversion-id: uint
parse-version-idread-onlyid-str: (string-ascii 20
get-bitcoin-blockread-only