Engineering Journal
Table Formatter
Table Formatter

Why I Built a QC Pipeline Tab Into My Table Editor

2026-05-11

TLDR

Writing one-off scripts to clean messy CSV imports is inefficient and non-reproducible. Building a pure-function pipeline architecture (Validate $\rightarrow$ Transform $\rightarrow$ Analyze) into the table editor enables fast, in-memory data quality checks ($<50\text{ms}$ for $10,000$ rows) without global state corruption.
Data Cleaning ApproachExecution ModelReusabilityState Integrity
Ad-Hoc One-Off ScriptsImperative DOM/File MutationsLow (Discarded after use)Risk of silent row corruption
Pure Pipeline ArchitectureComposed Pure Functions (VTA)100% Reusable JSON PipelinesImmutable In-Memory Processing

Ad-hoc validation scripts allow schema violations to leak into downstream database pipelines

Data engineering workflows frequently break because imported tables contain subtle data anomalies: blank email fields, negative revenue figures from formula errors, or duplicate entries. Writing throwaway validation scripts for every file is tedious and leaves downstream steps vulnerable to un-checked assumptions.

We introduced Lab Mode to provide a structured, three-phase quality control station (Validate, Transform, Analyze) directly inside the browser table editor.


Pure function pipeline steps enable high-performance, in-memory table validation

Each pipeline step executes pure functions that take raw row objects and parameters as inputs and return immutable results without mutating the active DOM:

   DIRTY IMPERATIVE APPROACH:
   [Raw CSV Data] ──> [DOM Table Elements] ──> [Direct Mutation Scripts] ──> [Polluted/Corrupted DOM]

CLEAN PURE-FUNCTION PIPELINE (Lab Mode): [Raw CSV Data] ──► Array of Row Primitives │ ▼ ┌──────────────────┐ │ 1. VALIDATE │ ──► [Filter Flags/Warnings] (No DOM write) └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ 2. TRANSFORM │ ──► [Immutable Map/Projection] (No DOM write) └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ 3. ANALYZE │ ──► [Reduce/Aggregate Output] └──────────────────┘ │ ▼ [Clean DOM Update] (Single, high-speed render pass)

Here is the implementation of our validation step:

// Pure validation step: Flag missing values without mutating state
export function flagEmpty(rows, params) {
  const flags = [];
  rows.forEach((row, i) => {
    const val = row[params.column];
    if (val === undefined || val === null || String(val).trim() === '') {
      flags.push({
        rowIndex: i,
        message: Missing required field: ${params.column},
        level: 'error'
      });
    }
  });
  return flags;
}

Because functions remain pure and isolated from DOM side effects, pipelines execute sequentially over plain JavaScript array primitives, running 10-step checks across 10,000 rows in under 50 milliseconds.

Rule of thumb: Structure table validation and transformation steps as pure array-to-array functions to guarantee execution speed and pipeline reproducibility.
Read this post in the full Engineering Journal →