Skip to main content

Appendix A: Data Used for Examples

Examples in this article are generated using randomized data in a demonstration instance of ELabLIMS. Very little data was initially present. A PowerShell script was used with SciForge mutations. The script is shown below.

# PowerShell script to populate 1000 GEN_SAMPLE semi-randomized records over the last 6 months

$GraphQLEndpoint = Read-Host "Enter GraphQL endpoint (e.g., https://demo-mtest.sciforge.net/graphql/)"
$Username = Read-Host "Enter username"
$Userkey = Read-Host "Enter userkey"

function Invoke-GraphQLRequest {
    param(
        [string]$Endpoint,
        [hashtable]$Headers,
        [string]$Query,
        [hashtable]$Variables = @{}
    )
    $body = @{
        query = $Query
        variables = $Variables
    } | ConvertTo-Json -Depth 10

    try {
        $response = Invoke-RestMethod -Uri $Endpoint -Method POST -Headers $Headers -Body $body -ContentType "application/json"
        return $response
    }
    catch {
        Write-Error "GraphQL request failed: $_"
        throw
    }
}

# Authenticate and get JWT token
Write-Host "Authenticating..." -ForegroundColor Yellow
$authHeaders = @{
    "elab-key-auth" = "$Userkey"
    "elab-user-name" = "$Username"
    "Content-Type" = "application/json"
}
$loginQuery = @"
mutation {
  LoginAppKeyJWT
}
"@
try {
    $loginResponse = Invoke-GraphQLRequest -Endpoint $GraphQLEndpoint -Headers $authHeaders -Query $loginQuery
    if ($loginResponse.errors) {
        Write-Error "Login failed: $($loginResponse.errors | ConvertTo-Json)"
        exit 1
    }
    $jwtToken = $loginResponse.data.LoginAppKeyJWT
    Write-Host "Authentication successful!" -ForegroundColor Green
} catch {
    Write-Error "Failed to authenticate: $_"
    exit 1
}
$apiHeaders = @{
    "x-auth-token" = "$jwtToken"
    "Content-Type" = "application/json"
}

# Define the mutation
$processSampleMutation = @"
mutation ProcessSample(`$input: ProcessSingleSampleInputType!) {
  processSingleSampleReceiving(input: `$input)
}
"@

# Generate 1000 samples over the last 6 months
$now = Get-Date
$startDate = $now.AddMonths(-6)
$rand = New-Object System.Random
$samples = @()

for ($i = 1; $i -le 1000; $i++) {
    # Randomly distribute collection dates over the last 6 months
    $daysAgo = $rand.Next(0, [int]($now - $startDate).TotalDays)
    $sampleDate = $now.AddDays(-$daysAgo)

    # Skew: More likely to be received if older
    $receivedProbability = 0.7 - 0.5 * ($daysAgo / (($now - $startDate).TotalDays))
    $received = $rand.NextDouble() -lt $receivedProbability

    $sample = @{
        UpdateType = "insert"
        SAMPLEDESCRIPTION = "Auto-generated sample $i"
        SAMPLECOMMENT = "Populated for PowerBI analytics"
        SAMPLEPRIORITY = $rand.Next(1, 2)
        SAMPLECOLLECTIONDATE = $sampleDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
        SAMPLECOLLECTIONBY = $rand.Next(1, 10)
        SAMPLETYPEID = $rand.Next(1, 17)
        LABID = 1
        SAMPLESTATUS = 1
        BILLABLE = $rand.NextDouble() -lt 0.8
        CREATEDBY = 1
        CREATEDDT = $sampleDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
        EDITEDBY = 1
        EDITEDDT = $sampleDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
        userID = 1
        locationID = 1
    }
    if ($received) {
        # Received date is 1-5 days after collection date, skewed toward 5 days for older samples
        $maxDays = 5
        $minDays = 1
        # Skew: older samples more likely to have longer turnaround
        $skewedDays = $minDays + [int](($maxDays - $minDays) * [Math]::Pow($rand.NextDouble(), 0.7))
        $receivedDate = $sampleDate.AddDays($skewedDays)
        $sample.SAMPLERECEIVED = $true
        $sample.SAMPLERECEIVEDDT = $receivedDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
    } else {
        $sample.SAMPLERECEIVED = $false
    }
    $samples += $sample
}

Write-Host "Generated $($samples.Count) samples." -ForegroundColor Yellow

# Process samples
$results = @()
$successCount = 0
$errorCount = 0

foreach ($sample in $samples) {
    try {
        Write-Host "Processing sample: $($sample.SAMPLENUMBER)" -ForegroundColor Cyan
        $variables = @{ input = $sample }
        $response = Invoke-GraphQLRequest -Endpoint $GraphQLEndpoint -Headers $apiHeaders -Query $processSampleMutation -Variables $variables
        if ($response.errors) {
            Write-Error "Error processing sample $($sample.SAMPLENUMBER): $($response.errors | ConvertTo-Json)"
            $errorCount++
            $results += @{
                SampleNumber = $sample.SAMPLENUMBER
                Status = "Error"
                Response = $response.errors
            }
        } else {
            $result = $response.data.processSingleSampleReceiving | ConvertFrom-Json
            Write-Host "Sample processed successfully! Key: $($result.Key)" -ForegroundColor Green
            $successCount++
            $results += @{
                SampleNumber = $sample.SAMPLENUMBER
                Status = "Success"
                Key = $result.Key
                RedirectUrl = $result.RedirectUrl
            }
        }
    } catch {
        Write-Error "Failed to process sample $($sample.SAMPLENUMBER): $_"
        $errorCount++
        $results += @{
            SampleNumber = $sample.SAMPLENUMBER
            Status = "Error"
            Error = $_.Exception.Message
        }
    }
    Start-Sleep -Milliseconds 100
}

Write-Host "`n=== PROCESSING SUMMARY ===" -ForegroundColor Magenta
Write-Host "Total samples: $($samples.Count)" -ForegroundColor White
Write-Host "Successful: $successCount" -ForegroundColor Green
Write-Host "Errors: $errorCount" -ForegroundColor Red

$resultsFile = "sample_processing_results_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"
$results | ConvertTo-Json -Depth 5 | Out-File $resultsFile
Write-Host "Results saved to: $resultsFile" -ForegroundColor Yellow