# adl-lims.yaml
#
# Next-Generation Sequencing LIMS — ADL Domain Definition
# ADL version: 0.3.1
#
# Resources: Project, Sample, Instrument, Protocol, Run, Analysis
# Relations: Sample belongsTo Project
# Project hasMany Sample
# Run belongsTo Instrument
# Run belongsTo Protocol
# Run belongsToMany Sample (via RunSamples junction)
# Analysis belongsTo Run
# Run hasMany Analysis
#
# ADL features exercised:
# CRUD — Full CRUD on all 6 resources
# Relationships — belongsTo (4), hasMany (3), belongsToMany (1 — Run ↔ Sample)
# State machines — Sample workflow (7-state), Run workflow (5-state),
# Analysis workflow (4-state with retry loop)
# Rich enums — SampleType (4), SampleStatus (7), RunStatus (5),
# InstrumentStatus (4), AnalysisStatus (4), Organism (5),
# LibraryPrepKit (5), SequencingPlatform (4)
# Types — decimal, percentage, date, datetime, integer, email, boolean,
# set, url, text
# Audit trail — Project, Sample, Run, Analysis (track workflow transitions)
# Search — Project, Sample, Protocol, Run (full-text)
# Export — Sample, Run (data export for external reporting)
# Permissions — Role-based: admin, pi, lab_tech, authenticated
#
# Roles referenced:
# admin — Full access to all resources
# pi — Principal investigator — creates projects, views all data
# lab_tech — Lab technician — processes samples, operates instruments, runs analyses
# authenticated — Can list/read all resources
#
# State machine — Sample:
#
# received ──pass_qc──▶ qc_passed ──begin_library_prep──▶ library_prep
# ▲ │ │
# │ fail_qc begin_sequencing
# │ ▼ ▼
# │ qc_failed sequencing
# │ │ │
# └─resubmit┘ begin_analysis
# ▼
# analysis
# │
# complete
# ▼
# complete (final)
#
# State machine — Run:
#
# planned ──begin_loading──▶ loading ──start_run──▶ running ──complete──▶ completed
# │
# fail
# ▼
# failed
#
# State machine — Analysis:
#
# queued ──start──▶ running ──complete──▶ completed
# │
# fail
# ▼
# failed ──retry──▶ queued (loop)
domain:
name: lims
version: "1.0.0"
description: >
Next-generation sequencing laboratory information management system.
Tracks the complete NGS workflow from sample receipt through quality
control, library preparation, sequencing on high-throughput instruments,
and bioinformatics analysis. Supports Illumina (NovaSeq, NextSeq, MiSeq)
and Oxford Nanopore platforms. Designed for a core facility processing
50-200 samples per week across multiple research groups.
api: {}
# ─── Shared objects ────────────────────────────────────────────
objects:
Timestamp:
createdAt: { type: datetime, autoNow: create }
updatedAt: { type: datetime, autoNow: update }
# ─── Shared properties ─────────────────────────────────────────
properties:
slug:
type: slug
unique: true
maxLength: 255
# ─── Enums ─────────────────────────────────────────────────────
enums:
SampleType:
values:
dna:
label: "Genomic DNA"
description: "Extracted genomic DNA for whole-genome or targeted sequencing"
color: "#3b82f6"
rna:
label: "Total RNA"
description: "Extracted total RNA for RNA-seq or small RNA sequencing"
color: "#10b981"
cfDNA:
label: "Cell-free DNA"
description: "Circulating cell-free DNA from plasma for liquid biopsy"
color: "#8b5cf6"
ffpe:
label: "FFPE"
description: "Formalin-fixed paraffin-embedded tissue DNA/RNA"
color: "#f59e0b"
SampleStatus:
values:
received:
label: "Received"
description: "Sample received and accessioned into the system"
color: "#94a3b8"
qc_passed:
label: "QC Passed"
description: "Sample passed quality control — ready for library prep"
color: "#3b82f6"
qc_failed:
label: "QC Failed"
description: "Sample failed QC — insufficient quality or quantity"
color: "#ef4444"
library_prep:
label: "Library Prep"
description: "Library preparation in progress"
color: "#8b5cf6"
sequencing:
label: "Sequencing"
description: "On the sequencer — data generation in progress"
color: "#f59e0b"
analysis:
label: "Analysis"
description: "Bioinformatics analysis in progress"
color: "#06b6d4"
complete:
label: "Complete"
description: "All processing finished — results delivered"
color: "#10b981"
final: true
RunStatus:
values:
planned:
label: "Planned"
description: "Run is scheduled but not yet started"
color: "#94a3b8"
loading:
label: "Loading"
description: "Flow cell is being loaded with libraries"
color: "#f59e0b"
running:
label: "Running"
description: "Sequencer is actively generating data"
color: "#3b82f6"
completed:
label: "Completed"
description: "Sequencing finished — data available for analysis"
color: "#10b981"
failed:
label: "Failed"
description: "Run failed — check instrument logs and flow cell"
color: "#ef4444"
InstrumentStatus:
values:
available:
label: "Available"
description: "Instrument is operational and ready for use"
color: "#10b981"
in_use:
label: "In Use"
description: "Currently running a sequencing experiment"
color: "#3b82f6"
maintenance:
label: "Maintenance"
description: "Scheduled or unscheduled maintenance in progress"
color: "#f59e0b"
offline:
label: "Offline"
description: "Instrument is down — repair or decommission pending"
color: "#ef4444"
AnalysisStatus:
values:
queued:
label: "Queued"
description: "Waiting for compute resources"
color: "#94a3b8"
running:
label: "Running"
description: "Pipeline is actively processing data"
color: "#3b82f6"
completed:
label: "Completed"
description: "Analysis finished — results available"
color: "#10b981"
failed:
label: "Failed"
description: "Pipeline failed — check error log for details"
color: "#ef4444"
Organism:
values:
human:
label: "Human (Homo sapiens)"
description: "GRCh38/hg38 reference genome"
color: "#3b82f6"
mouse:
label: "Mouse (Mus musculus)"
description: "GRCm39/mm39 reference genome"
color: "#94a3b8"
rat:
label: "Rat (Rattus norvegicus)"
description: "mRatBN7.2/rn7 reference genome"
color: "#94a3b8"
ecoli:
label: "E. coli (K-12)"
description: "Standard laboratory strain"
color: "#f59e0b"
custom:
label: "Custom / Other"
description: "Non-standard organism — specify in project notes"
color: "#8b5cf6"
LibraryPrepKit:
values:
nextera_dna_flex:
label: "Nextera DNA Flex"
description: "Illumina tagmentation-based DNA library prep (1-500ng input)"
color: "#3b82f6"
truseq_stranded_mrna:
label: "TruSeq Stranded mRNA"
description: "Illumina poly-A selection RNA-seq library prep"
color: "#10b981"
truseq_stranded_total_rna:
label: "TruSeq Stranded Total RNA"
description: "Illumina ribo-depletion total RNA library prep"
color: "#8b5cf6"
twist_exome:
label: "Twist Bioscience Exome"
description: "Twist Human Core Exome panel for whole-exome sequencing"
color: "#f59e0b"
nanopore_ligation:
label: "ONT Ligation Sequencing"
description: "Oxford Nanopore ligation-based long-read library prep"
color: "#94a3b8"
SequencingPlatform:
values:
novaseq_6000:
label: "NovaSeq 6000"
description: "Illumina high-throughput, up to 6 Tb per run"
color: "#3b82f6"
nextseq_2000:
label: "NextSeq 2000"
description: "Illumina mid-throughput, XLEAP chemistry"
color: "#8b5cf6"
miseq:
label: "MiSeq"
description: "Illumina benchtop, ideal for amplicon and small genome"
color: "#10b981"
minion:
label: "MinION"
description: "Oxford Nanopore portable long-read sequencer"
color: "#f59e0b"
# ─── Resources ─────────────────────────────────────────────────
resources:
# ╔══════════════════════════════════════════════════════════════╗
# ║ Project ║
# ╚══════════════════════════════════════════════════════════════╝
Project:
description: >
A sequencing project grouping related samples from a single
research group or grant. Projects define the organism, sequencing
objectives, and timeline. All samples within a project share the
same organism and are tracked toward a common delivery date.
object:
id:
type: uuid
primaryKey: true
name:
type: string
required: true
maxLength: 200
slug:
$ref: '#/properties/slug'
from: name
description:
type: text
maxLength: 3000
description: "Research objectives, sample types expected, and special requirements"
organism:
$ref: '#/enums/Organism'
required: true
referenceGenome:
type: string
maxLength: 50
description: "Reference genome build (e.g. GRCh38, GRCm39, custom assembly)"
piName:
type: string
required: true
maxLength: 200
piEmail:
type: email
labName:
type: string
maxLength: 200
description: "Research group or lab name"
department:
type: string
maxLength: 200
description: "Academic department"
grantNumber:
type: string
maxLength: 50
description: "Funding grant award number for billing"
sequencingObjective:
type: string
maxLength: 200
description: "e.g. Whole Genome 30x, RNA-seq (polyA), Exome, 16S Amplicon"
targetSampleCount:
type: integer
description: "Expected number of samples"
samplesReceived:
type: integer
default: 0
description: "Number of samples received so far"
samplesCompleted:
type: integer
default: 0
description: "Number of samples fully processed"
startDate:
type: date
targetDate:
type: date
description: "Desired completion date"
active:
type: boolean
default: true
notes:
type: text
maxLength: 5000
description: "Special handling instructions, billing notes, communication log"
$merge:
- { $ref: '#/objects/Timestamp' }
relationships:
samples:
type: hasMany
target: Sample
foreignKey: projectId
indexes:
- fields: [organism]
description: "Filter projects by organism"
- fields: [piName]
description: "Filter projects by PI"
- fields: [active]
description: "Filter active/completed projects"
features:
search: true
audit: true
audit:
track: [name, organism, piName, targetSampleCount, samplesReceived, samplesCompleted, active]
exclude: [updatedAt]
permissions:
list: [authenticated]
read: [authenticated]
create: [pi, admin]
update: [owner, pi, admin]
delete: [admin]
# ╔══════════════════════════════════════════════════════════════╗
# ║ Sample ║
# ╚══════════════════════════════════════════════════════════════╝
Sample:
description: >
A biological sample progressing through the NGS workflow.
Samples arrive at the core facility, undergo quality control,
library preparation, sequencing, and bioinformatics analysis.
Each stage is a state machine transition. Samples carry
quantitative QC metrics (concentration, volume, quality score)
and are linked to a project and optionally to specific library
prep kits.
object:
id:
type: uuid
primaryKey: true
name:
type: string
required: true
maxLength: 200
description: "Lab-assigned sample identifier"
externalId:
type: string
maxLength: 100
description: "Client's own sample ID for cross-referencing"
sampleType:
$ref: '#/enums/SampleType'
required: true
status:
$ref: '#/enums/SampleStatus'
default: received
organism:
$ref: '#/enums/Organism'
description: "Overrides project organism if different"
tissue:
type: string
maxLength: 100
description: "Tissue or cell type (e.g. whole blood, liver, tumor, PBMC)"
preservationMethod:
type: string
maxLength: 100
description: "e.g. Fresh frozen, FFPE, RNAlater, ethanol-fixed"
collectionDate:
type: date
description: "Date the sample was collected from the subject"
receivedAt:
type: datetime
description: "When the sample arrived at the core facility"
# ─── QC Metrics ───────────────────────────────────────────
concentration:
type: decimal
description: "Concentration in ng/µL (measured by Qubit or NanoDrop)"
volume:
type: decimal
description: "Volume in µL"
totalAmount:
type: decimal
description: "Total mass in ng (concentration × volume)"
a260_280:
type: decimal
description: "A260/A280 absorbance ratio — purity indicator (DNA ~1.8, RNA ~2.0)"
a260_230:
type: decimal
description: "A260/A230 absorbance ratio — contaminant indicator (ideal 2.0-2.2)"
rin:
type: decimal
description: "RNA Integrity Number (1-10, RNA only, measured by Bioanalyzer)"
din:
type: decimal
description: "DNA Integrity Number (1-10, DNA only, measured by TapeStation)"
fragmentSize:
type: integer
description: "Average fragment size in bp (from Bioanalyzer or TapeStation)"
qcNotes:
type: text
maxLength: 2000
description: "QC observations, Bioanalyzer trace notes, degradation assessment"
qcPassedAt:
type: datetime
description: "When QC was completed"
qcPerformedBy:
type: string
maxLength: 100
description: "Username of the technician who performed QC"
# ─── Library Prep ─────────────────────────────────────────
libraryPrepKit:
$ref: '#/enums/LibraryPrepKit'
description: "Kit used for library preparation"
libraryPrepDate:
type: date
indexSequence:
type: string
maxLength: 50
description: "i7/i5 index barcode sequence for demultiplexing (e.g. ATCACG-TTAGGC)"
libraryConcentration:
type: decimal
description: "Post-prep library concentration in nM"
libraryFragmentSize:
type: integer
description: "Post-prep average fragment size in bp"
libraryPrepNotes:
type: text
maxLength: 2000
# ─── Project Link ─────────────────────────────────────────
projectId:
type: uuid
required: true
projectName:
type: string
maxLength: 200
description: "Denormalized project name for display"
# ─── General ──────────────────────────────────────────────
notes:
type: text
maxLength: 3000
description: "General notes, special handling, client communications"
completedAt:
type: datetime
description: "When all processing was finished"
$merge:
- { $ref: '#/objects/Timestamp' }
relationships:
project:
type: belongsTo
target: Project
foreignKey: projectId
indexes:
- fields: [projectId]
description: "List samples by project"
- fields: [status]
description: "Filter by processing status"
- fields: [sampleType]
description: "Filter by sample type"
- fields: [organism]
description: "Filter by organism"
- fields: [projectId, status]
description: "Composite: project samples by status"
- fields: [libraryPrepKit]
description: "Filter by prep kit"
features:
audit: true
search: true
export: true
audit:
track: [name, status, concentration, volume, rin, din, qcNotes, libraryPrepKit, indexSequence]
exclude: [updatedAt]
# ─── State machine ──────────────────────────────────────────
stateMachine:
field: status
initial: received
states:
received:
description: "Sample accessioned — awaiting QC"
transitions:
pass_qc:
to: qc_passed
guards: [lab_tech, admin]
sets:
qcPassedAt: now()
fail_qc:
to: qc_failed
guards: [lab_tech, admin]
sets:
qcPassedAt: now()
qc_passed:
description: "QC passed — ready for library preparation"
transitions:
begin_library_prep:
to: library_prep
guards: [lab_tech, admin]
qc_failed:
description: "QC failed — sample may need re-extraction or replacement"
transitions:
resubmit:
to: received
guards: [lab_tech, admin]
sets:
qcPassedAt: null
qcNotes: null
concentration: null
volume: null
totalAmount: null
a260_280: null
a260_230: null
rin: null
din: null
library_prep:
description: "Library preparation in progress"
transitions:
begin_sequencing:
to: sequencing
guards: [lab_tech, admin]
sequencing:
description: "Sample is on the sequencer"
transitions:
begin_analysis:
to: analysis
guards: [lab_tech, admin]
analysis:
description: "Bioinformatics analysis in progress"
transitions:
complete:
to: complete
guards: [lab_tech, admin]
sets:
completedAt: now()
complete:
description: "All processing finished — results delivered to PI"
# ─── Permissions ─────────────────────────────────────────────
permissions:
list: [authenticated]
read: [authenticated]
create: [lab_tech, pi, admin]
update: [lab_tech, admin]
delete: [admin]
# ╔══════════════════════════════════════════════════════════════╗
# ║ Instrument ║
# ╚══════════════════════════════════════════════════════════════╝
Instrument:
description: >
A sequencing instrument in the core facility. Each instrument
has a model, serial number, platform type, and operational
status. Instruments are linked to sequencing runs. Maintenance
schedules are tracked to minimize downtime.
object:
id:
type: uuid
primaryKey: true
name:
type: string
required: true
maxLength: 100
description: "Friendly name (e.g. NovaSeq-1, MiSeq-Bench3)"
platform:
$ref: '#/enums/SequencingPlatform'
required: true
model:
type: string
required: true
maxLength: 100
description: "Full model name (e.g. NovaSeq 6000, NextSeq 2000, MinION Mk1C)"
serialNumber:
type: string
unique: true
maxLength: 50
status:
$ref: '#/enums/InstrumentStatus'
default: available
location:
type: string
maxLength: 100
description: "Room and bench location (e.g. Sequencing Core, Room 312, Bench A)"
ipAddress:
type: string
maxLength: 45
description: "Network IP for instrument control software"
softwareVersion:
type: string
maxLength: 50
description: "Current control software version"
purchaseDate:
type: date
warrantyExpires:
type: date
lastMaintenanceDate:
type: date
nextMaintenanceDate:
type: date
totalRuns:
type: integer
default: 0
description: "Cumulative number of runs on this instrument"
notes:
type: text
maxLength: 3000
description: "Maintenance history, known issues, performance notes"
$merge:
- { $ref: '#/objects/Timestamp' }
relationships:
runs:
type: hasMany
target: Run
foreignKey: instrumentId
indexes:
- fields: [platform]
description: "Filter by sequencing platform"
- fields: [status]
description: "Filter by operational status"
features:
audit: true
audit:
track: [name, status, softwareVersion, lastMaintenanceDate, nextMaintenanceDate, totalRuns]
exclude: [updatedAt]
permissions:
list: [authenticated]
read: [authenticated]
create: [admin]
update: [lab_tech, admin]
delete: [admin]
# ╔══════════════════════════════════════════════════════════════╗
# ║ Protocol ║
# ╚══════════════════════════════════════════════════════════════╝
Protocol:
description: >
Standard operating procedures for library preparation and
sequencing. Each protocol has a name, version, and description
of the workflow steps. Protocols specify which sample types
they support and estimated processing time. Lab technicians
select a protocol when setting up a sequencing run.
object:
id:
type: uuid
primaryKey: true
name:
type: string
required: true
maxLength: 200
description: "Protocol name (e.g. WGS 30x Human, RNA-seq polyA, 16S V3-V4)"
version:
type: string
required: true
maxLength: 20
description: "Protocol version (e.g. 3.1, 2024-Q4)"
category:
type: string
maxLength: 100
description: "e.g. Whole Genome, RNA-seq, Exome, Amplicon, Metagenomics"
description:
type: text
maxLength: 5000
description: "Detailed protocol steps, reagent list, and quality checkpoints"
applicableSampleTypes:
type: set
description: "Which sample types this protocol supports (dna, rna, cfDNA, ffpe)"
applicablePlatforms:
type: set
description: "Which sequencing platforms this protocol targets"
recommendedKit:
$ref: '#/enums/LibraryPrepKit'
description: "Recommended library prep kit for this protocol"
inputRequirements:
type: text
maxLength: 1000
description: "Minimum input requirements (e.g. 100ng DNA, RIN >= 7, DIN >= 6)"
estimatedDuration:
type: string
maxLength: 50
description: "Estimated hands-on time (e.g. 4 hours, 2 days)"
estimatedTurnaround:
type: string
maxLength: 50
description: "Total turnaround including sequencing (e.g. 5 business days)"
readConfiguration:
type: string
maxLength: 50
description: "Default read length and type (e.g. 2×150bp PE, 1×75bp SE, 2×250bp PE)"
targetCoverage:
type: string
maxLength: 50
description: "Target coverage or read depth (e.g. 30x, 50M reads, 100k reads/sample)"
active:
type: boolean
default: true
description: "Whether this protocol is currently in use"
author:
type: string
maxLength: 200
description: "Protocol developer or responsible scientist"
approvedDate:
type: date
description: "Date the protocol was approved for production use"
$merge:
- { $ref: '#/objects/Timestamp' }
indexes:
- fields: [category]
description: "Filter by protocol category"
- fields: [active]
description: "Filter active protocols"
features:
search: true
permissions:
list: [authenticated]
read: [authenticated]
create: [admin]
update: [admin]
delete: [admin]
# ╔══════════════════════════════════════════════════════════════╗
# ║ Run ║
# ╚══════════════════════════════════════════════════════════════╝
Run:
description: >
A sequencing run on an instrument. Each run processes one or
more samples (via the RunSamples junction table), follows a
protocol, and produces raw sequencing data. Runs progress
through a state machine: planned → loading → running →
completed (or failed). QC metrics (total reads, pass filter
percentage, Q30 score) are recorded after the run completes.
object:
id:
type: uuid
primaryKey: true
name:
type: string
required: true
maxLength: 200
description: "Run identifier (e.g. NS6K-20260315-WGS-001)"
flowCellId:
type: string
maxLength: 50
description: "Flow cell barcode (e.g. HXXXXXXXX)"
flowCellType:
type: string
maxLength: 50
description: "Flow cell type (e.g. SP, S1, S2, S4 for NovaSeq)"
status:
$ref: '#/enums/RunStatus'
default: planned
instrumentId:
type: uuid
required: true
instrumentName:
type: string
maxLength: 100
description: "Denormalized instrument name"
protocolId:
type: uuid
protocolName:
type: string
maxLength: 200
description: "Denormalized protocol name"
operatorId:
type: string
maxLength: 100
description: "Username of the lab technician running the instrument"
operatorName:
type: string
maxLength: 200
readLength:
type: string
maxLength: 50
description: "Actual read configuration (e.g. 2×150bp, 1×300bp)"
indexReads:
type: string
maxLength: 50
description: "Index read configuration (e.g. 8+8bp, 10+10bp)"
loadingConcentration:
type: decimal
description: "Library loading concentration in pM"
phiXPercent:
type: percentage
description: "Percentage of PhiX spike-in control"
# ─── Post-run QC metrics ──────────────────────────────────
totalReads:
type: integer
description: "Total clusters / reads generated (millions)"
readsPassFilter:
type: integer
description: "Reads passing quality filter (millions)"
passFilterPercent:
type: percentage
description: "Percentage of clusters passing filter"
q30Percent:
type: percentage
description: "Percentage of bases with quality score >= Q30"
meanQuality:
type: decimal
description: "Mean quality score across all bases"
errorRate:
type: decimal
description: "Estimated sequencing error rate (percentage)"
yieldGb:
type: decimal
description: "Total data yield in gigabases"
clusterDensity:
type: decimal
description: "Cluster density (K/mm²) — Illumina only"
# ─── Timing ───────────────────────────────────────────────
scheduledDate:
type: date
description: "Planned run date"
startedAt:
type: datetime
completedAt:
type: datetime
estimatedCompletion:
type: datetime
description: "Estimated completion time (calculated from run parameters)"
# ─── General ──────────────────────────────────────────────
outputPath:
type: string
maxLength: 500
description: "Path to raw data output directory on the file server"
notes:
type: text
maxLength: 3000
description: "Run observations, issues encountered, post-run assessment"
$merge:
- { $ref: '#/objects/Timestamp' }
relationships:
instrument:
type: belongsTo
target: Instrument
foreignKey: instrumentId
protocol:
type: belongsTo
target: Protocol
foreignKey: protocolId
samples:
type: belongsToMany
target: Sample
through: RunSamples
foreignKey: runId
otherKey: sampleId
analyses:
type: hasMany
target: Analysis
foreignKey: runId
indexes:
- fields: [instrumentId]
description: "List runs by instrument"
- fields: [status]
description: "Filter by run status"
- fields: [protocolId]
description: "List runs by protocol"
- fields: [operatorId]
description: "List runs by operator"
- fields: [scheduledDate]
description: "Sort by scheduled date"
- fields: [instrumentId, status]
description: "Composite: instrument runs by status"
features:
audit: true
search: true
export: true
audit:
track: [name, status, instrumentId, totalReads, q30Percent, passFilterPercent, yieldGb]
exclude: [updatedAt]
# ─── State machine ──────────────────────────────────────────
stateMachine:
field: status
initial: planned
states:
planned:
description: "Run is scheduled — loading date set, samples selected"
transitions:
begin_loading:
to: loading
guards: [lab_tech, admin]
loading:
description: "Flow cell is being loaded with pooled libraries"
transitions:
start_run:
to: running
guards: [lab_tech, admin]
sets:
startedAt: now()
running:
description: "Sequencer is actively generating data"
transitions:
complete:
to: completed
guards: [lab_tech, admin]
sets:
completedAt: now()
fail:
to: failed
guards: [lab_tech, admin]
sets:
completedAt: now()
completed:
description: "Run finished successfully — data ready for analysis"
failed:
description: "Run failed — check instrument logs and flow cell integrity"
# ─── Permissions ─────────────────────────────────────────────
permissions:
list: [authenticated]
read: [authenticated]
create: [lab_tech, admin]
update: [lab_tech, admin]
delete: [admin]
# ╔══════════════════════════════════════════════════════════════╗
# ║ Analysis ║
# ╚══════════════════════════════════════════════════════════════╝
Analysis:
description: >
A bioinformatics analysis of sequencing run data. Each analysis
runs a specific pipeline (e.g. GATK, bcl2fastq, nf-core/rnaseq)
on the data from a sequencing run. Analyses progress through a
state machine: queued → running → completed (or failed with
retry option). Failed analyses can be retried, which clears
the error state and re-queues the job.
object:
id:
type: uuid
primaryKey: true
name:
type: string
required: true
maxLength: 200
description: "Analysis identifier (e.g. WGS-Alignment-Run001, RNAseq-DGE-Proj42)"
pipeline:
type: string
required: true
maxLength: 100
description: "Pipeline name (e.g. bcl2fastq, GATK-HaplotypeCaller, nf-core/rnaseq, nf-core/sarek)"
pipelineVersion:
type: string
maxLength: 20
description: "Pipeline version (e.g. 3.12.0, 2024.1)"
referenceGenome:
type: string
maxLength: 50
description: "Reference genome used (e.g. GRCh38, GRCm39)"
status:
$ref: '#/enums/AnalysisStatus'
default: queued
runId:
type: uuid
required: true
runName:
type: string
maxLength: 200
description: "Denormalized run name"
submittedBy:
type: string
maxLength: 100
description: "Username of the person who submitted the analysis"
submittedByName:
type: string
maxLength: 200
# ─── Compute ──────────────────────────────────────────────
computeNode:
type: string
maxLength: 100
description: "HPC node or cloud instance running the analysis"
cpuHours:
type: decimal
description: "CPU hours consumed"
peakMemoryGb:
type: decimal
description: "Peak memory usage in GB"
wallTimeHours:
type: decimal
description: "Wall-clock time in hours"
# ─── Timing ───────────────────────────────────────────────
startedAt:
type: datetime
completedAt:
type: datetime
# ─── Results ──────────────────────────────────────────────
outputPath:
type: string
maxLength: 500
description: "Path to analysis output directory"
reportUrl:
type: url
description: "URL to the MultiQC or analysis report"
totalVariants:
type: integer
description: "Number of variants called (for variant calling pipelines)"
alignmentRate:
type: percentage
description: "Percentage of reads aligned to reference"
duplicationRate:
type: percentage
description: "Percentage of duplicate reads"
meanCoverage:
type: decimal
description: "Mean genome coverage (for WGS/WES)"
# ─── Error handling ───────────────────────────────────────
errorLog:
type: text
maxLength: 10000
description: "Error output from the pipeline (captured on failure)"
retryCount:
type: integer
default: 0
description: "Number of times this analysis has been retried"
notes:
type: text
maxLength: 3000
$merge:
- { $ref: '#/objects/Timestamp' }
relationships:
run:
type: belongsTo
target: Run
foreignKey: runId
indexes:
- fields: [runId]
description: "List analyses by run"
- fields: [status]
description: "Filter by analysis status"
- fields: [pipeline]
description: "Filter by pipeline"
- fields: [runId, status]
description: "Composite: run analyses by status"
features:
audit: true
audit:
track: [name, status, pipeline, startedAt, completedAt, errorLog, retryCount]
exclude: [updatedAt]
# ─── State machine ──────────────────────────────────────────
stateMachine:
field: status
initial: queued
states:
queued:
description: "Waiting for compute resources on the HPC cluster"
transitions:
start:
to: running
guards: [lab_tech, admin]
sets:
startedAt: now()
running:
description: "Pipeline is actively processing sequencing data"
transitions:
complete:
to: completed
guards: [lab_tech, admin]
sets:
completedAt: now()
fail:
to: failed
guards: [lab_tech, admin]
sets:
completedAt: now()
completed:
description: "Analysis complete — results available at outputPath"
failed:
description: "Pipeline failed — check errorLog for diagnostics"
transitions:
retry:
to: queued
guards: [lab_tech, admin]
sets:
startedAt: null
completedAt: null
errorLog: null
# ─── Permissions ─────────────────────────────────────────────
permissions:
list: [authenticated]
read: [authenticated]
create: [lab_tech, admin]
update: [lab_tech, admin]
delete: [admin]