KQ-1728 · DRY/RUN

Dry Run

A data migration wizard — connect, map, rehearse, run — that shows what it would do before it writes. The rehearsal is a grey pass: one motion value walks the rows on the move ease and three counters (would create, would update, would skip) tick up as their rows pass, as figures, bars or a waffle of row batches whose cells pop as the head goes by; the real run repeats exactly the same seeded walk in colour over the grey ghost, and the actual counts land on springs.recoil beside their rehearsed figures and a delta chip. Panels swap by direction on springs.glide, the stepper's fill glides and its checks draw on springs.flick, and every step validates before Next, taking focus to whatever needs fixing.

KQ-1728 · DRY/RUN

Move meter accounts

Coldbrook billing export → Gaugeworks · Meter accounts

Draft

Rehearse the migration

Rehearsal · nothing is written

Takes a few seconds and writes nothing.

step 3 of 4 · rehearse · 1,284 rows

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/dry-run

Props

source
DryRunSource
default defaultDryRunSource
The data being moved: { name, kind, location, rows, columns, sample?, target }.
fields
DryRunField[]
default defaultDryRunFields
The target's fields: { id, label, required?, hint? }.
mapping / defaultMapping
Record<string, string | null>
default — / defaultDryRunMapping
Target field id → source column, or null to skip the field; controlled or initial.
onMappingChange
(mapping) => void
default —
Fires from the select that changed the mapping, with the whole mapping.
results
DryRunResults
default defaultDryRunResults
{ rehearsal, run, skipped }: the counts each pass lands on and the rows left out.
step / defaultStep
"connect" | "map" | "rehearse" | "run"
default — / "connect"
The current step, controlled or initial; opening later counts the earlier steps as passed.
onStepChange
(step) => void
default —
Fires from Next, Back or the stepper with the step asked for.
onConnect
() => boolean | void
default —
Fires when the connection is checked; return false to report the source unreadable.
onDryRun
(mapping) => void
default —
Fires when the rehearsal starts, with the mapping it rehearses.
onRun
(mapping) => void
default —
Fires when the real run starts, with the mapping it runs.
onPassEnd
(pass: "rehearsal" | "run", counts) => void
default —
Fires when a pass has walked every row, with that pass's counts.
onDownloadReport
(report: DryRunReport) => void
default —
Fires from Download report with source, target, mapping, both passes' counts and the skipped rows.
counterStyle
"digits" | "bars" | "waffle"
default "digits"
Counters as tiles of figures, long bars, or one waffle of row batches.
density
"compact" | "regular" | "roomy"
default "regular"
Padding, type size and figure size.
tone
"signal" | "cobalt" | "ember" | "moss"
default "signal"
The real run's colours (the rehearsal is always grey); pigments at fixed lightness.
passDuration
number
default 2400
How long each pass takes to walk the rows, in ms.
status
"ready" | "loading" | "error"
default "ready"
Loading shows placeholders; error explains and offers Try again.
onRetry
() => void
default —
Try again was pressed after the source failed to load.
title
string
default "Move meter accounts"
The migration's name, the surface's heading.
height
number
default 540
Height of the surface in px; the step body scrolls inside it.
disabled
boolean
default false
Read only: nothing can be checked, mapped or run.
className
string
default —
Classes for the surface.