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