This is the feature-complete release: dqcheckrGUI now
enters maintenance mode and will receive bug fixes and
compatibility updates only. Configuration features are developed in
dqcheckr itself, which offers a script-based workflow that
does not need this interface. Existing deployments continue to work
unchanged.
Version 0.2.1 was developed but never published to CRAN, so upgrading from the published 0.2.0 brings the changes listed under both headings below.
snapshot_db at the dataset level
were silently absent. A note above the table now names any such datasets
when they are present, so the omission is visible rather than hidden.
(Drift comparison already reads each dataset’s own database and is
unaffected. Merging histories across databases remains a known
limitation — see the “Browsing history” section of the vignette.)The drift-comparison report link now works again. The GUI located
the rendered drift report by reconstructing its filename with a fixed
pattern, which stopped matching once dqcheckr’s drift filenames gained a
snapshot-id suffix — so every drift comparison reported “report not
found” even though it rendered. The GUI now uses the report path
compare_snapshots() returns directly (requires dqcheckr
>= 0.2.5 behaviour), removing the fragile filename contract.
Report links in the dataset panel now account for a report that
is still rendering. A snapshot whose render_status is
"pending" (dqcheckr 0.2.5+) no longer gets a clickable
“Open” link to a file that is not yet on disk; it shows “rendering…”
until the report is written. A filename is only reconstructed for a
genuine pre-0.2.3 row, not whenever one is absent.
The dqcheckr dependency floor was raised to the
version whose behaviour the report and drift link builders rely
on.
Config-file writes are now crash-safe. Both dataset configs and
the global dqcheckr.yml are written to a temporary file and
renamed into place, so an interrupted write (process killed, power loss,
a contended OneDrive/network share) can no longer leave the sole config
for a dataset truncated and unparseable.
A malformed global dqcheckr.yml no longer crashes
the session at startup or gets silently overwritten with a trimmed copy
on save. Startup falls back to the built-in defaults with a warning, and
a save aborts with “Save failed” rather than wiping keys it could not
read.
Read failures are no longer disguised as empty results. A corrupt or unreachable snapshot database is reported distinctly instead of showing “No run history found”, and editing a dataset whose YAML cannot be parsed now shows an explicit error and leaves the file untouched, rather than opening a blank wizard that would overwrite it on save.
Background-process races were fixed. Clicking Stop on a run that finished in the same instant now reports its real PASS/WARN/FAIL result instead of “stopped”, and a second drift comparison launched while one is still running is refused rather than orphaning the first.
A renamed-header CSV config no longer loses its
col_names/csv_skip when edited and saved
without re-visiting the structure step, and the step-3 encoding sniffer
no longer crashes on a large, mostly-ASCII file whose charset detector
returns an indeterminate result.
Hardened the observers behind client-settable inputs so a malformed payload can no longer error them, and added test coverage for the run panel, the global-config reader, and the dataset-name JavaScript escaper.
The step-3 encoding sniffer no longer writes
encoding: ASCII into dataset configs.
readr::guess_encoding()’s head sample confidently reports
“ASCII” whenever the first accented byte sits beyond the sample — and
that config value later hard-crashed the run’s R subprocess (“Invalid
multibyte sequence” inside vroom/iconv) once a delivery contained
non-ASCII bytes. Step 3 now scans the entire file: valid UTF-8
(which includes pure ASCII) is applied as UTF-8 with
certainty; only when the file is genuinely not UTF-8 does the
statistical detector run — seeded with a chunk that actually contains
the non-ASCII bytes — and its legacy-encoding candidates go through the
usual confirm flow. New dependency: stringi.
An encoding: ASCII in an existing config (written by
hand or by an older GUI) is normalised to UTF-8 when the
config is read, so editing and re-saving a dataset upgrades it. ASCII is
a strict subset of UTF-8, so the change is lossless.
Wizard state can no longer leak between datasets: opening the wizard now always resets to defaults before loading a config (edit mode previously overlaid the config on the previous session’s leftovers), and positional step-3/4/5 inputs are namespaced per wizard open so stale checkbox/select values from an earlier dataset can never be collected into the current one.
The step-5 regex “Test” buttons are handled by a single delegated observer; previously a new set of observers was registered on every column-list change without destroying the old ones.
Report links now honour per-dataset
report_output_dir overrides (each override directory is
served under its own resource path), the resource paths are
re-registered after every completed run (covering projects whose
reports/ directory is first created by dqcheckr itself),
runs whose report rendering failed show “render failed” instead of a
dead “Open” link, and links prefer the exact filename recorded by
dqcheckr >= 0.2.3 over reconstructing it from the run
timestamp.
Renaming a dataset in edit mode now removes the old config file and warns that run history stays under the old name; renaming onto another existing dataset is blocked (previously it silently overwrote that dataset’s config).
The pre-run check validates a per-dataset
snapshot_db override rather than always checking the global
path.
Unparseable run timestamps display verbatim instead of as “NA”;
an empty preview file no longer produces a max()
warning.
The wizard’s type-inference preview honours
type_inference_threshold (dataset override, then global
default) instead of a hard-coded 0.90.
Sidebar status badges and the dataset panel’s “Recent runs” table
now resolve a relative snapshot_db path (e.g. the
data/snapshots.sqlite written by the first-run scaffold)
against the project root instead of the installed app directory, where
it never existed. Both views also now honour a per-dataset
snapshot_db override, matching the History panel.
Values interpolated into raw HTML in the History and dataset-panel tables (delivered file names, dataset names, report URLs) are now HTML-escaped. File names come from externally supplied deliveries, so a hostile file name could previously inject markup into the analyst’s browser.
Saving the Global Config no longer discards hand-added keys:
unknown top-level keys and default_rules entries with no
GUI widget (e.g. max_row_count,
max_file_size_mb, iqr_fence_multiplier) are
preserved, matching the round-trip behaviour dataset configs already
had.
Stepping through wizard step 6 without changing anything no
longer writes a spurious min_row_count override into the
dataset config (an integer-vs-double comparison artefact).
Folder-scan previews in the wizard no longer consider subdirectories when picking the most recent file, and the folder file count excludes them.
run_app() gains a config_dir argument to
point the app at a specific project folder regardless of the R session’s
working directory. Passing this explicitly is recommended when launching
from a script on ‘Windows’ or from a ‘OneDrive’-synced path, where
getwd() may not match the script location. The argument
sets DQCHECKR_CONFIG_DIR for the session and restores the
previous value on exit.dqcheckr.yml is found, the app
now shows a dialog offering to scaffold config/,
data/, and reports/ and write a default global
config. Accepting opens Global Config for review before any dataset is
added. Declining allows manual setup. This replaces the previous silent
redirect to Global Config.deployment_root) as their first entry, followed by the
user home directory and system volumes, so the correct location is
reachable without navigating from an unrelated working directory.source() runtime errors (e.g. missing package, top-level
stop()) from a missing custom_checks function,
and shows the specific error message.https://mickmioduszewski.github.io/dqcheckrGUI/, deployed
automatically via ‘GitHub Actions’ on every push to
main.folder and current_file paths in
the pre-run check are now resolved against the deployment root before
the existence check, so they no longer show a false “Folder not found”
warning when the path is valid relative to the project.dqcheckr.yml (e.g. max_mean_shift_pct = 20
instead of max_numeric_mean_shift_pct = 0.20). The written
config now matches the canonical schema used by
read_global_config() and Global Config.uiOutput("step8_save_status") removed from wizard
step 8; save feedback is provided by notification and modal, not this
slot.config_dir argument usage,
DQCHECKR_CONFIG_DIR env var option, ‘Windows’/‘OneDrive’
launcher pattern, and first-run modal description.?dqcheckrGUI package help page now resolves (dropped
@noRd); includes Getting started and Related packages
sections with cross-references to ‘dqcheckr’ vignettes.?run_app gains @seealso links to the
vignette and dqcheckr::run_dq_check.skip_on_cran() added to all ‘shinytest2’ test blocks;
the suite requires a browser and runs ~108 s, which exceeds CRAN’s time
limit.library() calls from test files;
all packages are accessed via :: (exception:
library(shiny) retained in test-history.R to
attach tags to the search path for
status_badge()).PayeeName/Amount): a raw-header probe
(name_repair = "minimal") recovers the names and
suggest_col_names() proposes valid, unique, editable fixes.
On save a renamed header is written as col_names plus
csv_skip: 1, so ‘dqcheckr’ (>= 0.2.2) skips the original
header row instead of reading it as data; clean files write neither
key.snapshot_db / report_output_dir
paths in the config are resolved against the deployment root (the parent
of the config directory), and background ‘callr’ runs execute with
wd set there, so the GUI reads and writes the same snapshot
database the ‘dqcheckr’ CLI does. Absolute paths continue to work
unchanged.