Skip to content

Reporting System#

oxo-flow includes a modular report generation system designed for both research and clinical use. Reports are structured documents built from composable sections.


Architecture#

graph TD
    Config["WorkflowConfig"] --> Report["Report"]
    Execution["Execution Results"] --> Report
    Report --> HTML["HTML Output"]
    Report --> JSON["JSON Output"]
    Templates["Tera Templates"] --> HTML

Core Types#

Report#

The top-level report container:

pub struct Report {
    pub title: String,
    pub workflow: String,
    pub version: String,
    pub generated_at: DateTime<Utc>,
    pub sections: Vec<ReportSection>,
}

ReportSection#

A section within a report:

pub struct ReportSection {
    pub title: String,
    pub id: String,
    pub content: ReportContent,
    pub subsections: Vec<ReportSection>,
}

ReportContent#

The content of a section, supporting multiple formats:

pub enum ReportContent {
    KeyValue { pairs: Vec<(String, String)> },
    Table { headers: Vec<String>, rows: Vec<Vec<String>> },
    Text(String),
    Html(String),
}

Output Formats#

HTML#

Self-contained single-file HTML with embedded CSS:

let html: String = report.to_html();

The HTML output includes:

  • Responsive layout
  • Table of contents generated from section headings
  • Styled tables and key-value displays
  • Print-friendly CSS

JSON#

Machine-readable structured output:

let json: String = report.to_json()?;

The JSON output mirrors the report structure and is suitable for:

  • Downstream processing scripts
  • Database ingestion
  • API responses

Generating Reports#

From the CLI#

# HTML to stdout
oxo-flow report pipeline.oxoflow

# HTML to file
oxo-flow report pipeline.oxoflow -o report.html

# JSON to file
oxo-flow report pipeline.oxoflow -f json -o report.json

Programmatically#

use oxo_flow_core::report::{Report, ReportSection, ReportContent};

let mut report = Report::new("Pipeline Report", "my-pipeline", "1.0.0");

report.add_section(ReportSection {
    title: "Quality Metrics".to_string(),
    id: "quality".to_string(),
    content: ReportContent::Table {
        headers: vec!["Sample".into(), "Reads".into(), "Quality".into()],
        rows: vec![
            vec!["sample1".into(), "50M".into(), "Q35".into()],
            vec!["sample2".into(), "48M".into(), "Q36".into()],
        ],
    },
    subsections: vec![],
});

let html = report.to_html();

Report Configuration#

Configure reports in the .oxoflow file:

[report]
template = "clinical"
format = ["html", "json"]
sections = ["summary", "variants", "quality"]

Templates#

The template field selects a report template. Built-in templates:

Template Use case
default General-purpose research report
clinical Clinical-grade report with structured sections

Templates are rendered with Tera, a Jinja2-like template engine for Rust.


Clinical Reports#

The Venus pipeline uses the reporting system to generate clinical tumor variant calling reports. These include:

  • Patient/sample metadata
  • Variant summary tables
  • Quality control metrics
  • Methodology description
  • Structured for regulatory compliance

See the Venus Pipeline reference for details.


See Also#