Skip to content

Add a tested data-quality workflow - #2

Merged
DataTideHH merged 14 commits into
mainfrom
feat/data-quality-workflow
Jul 28, 2026
Merged

Add a tested data-quality workflow#2
DataTideHH merged 14 commits into
mainfrom
feat/data-quality-workflow

Conversation

@DataTideHH

Copy link
Copy Markdown
Owner

Summary

Adds a small, auditable Data/BI preparation workflow that turns an intentionally imperfect synthetic CSV into cleaned records, rejected rows with explicit reason codes, module-level KPIs and a machine-readable quality report.

Workflow

  • reads raw CSV fields as text before controlled conversion
  • validates required columns
  • detects missing values, invalid dates and invalid numeric values
  • enforces score, maximum and pass-threshold ranges
  • normalises identifiers, module whitespace and dates
  • removes later copies of exact duplicates
  • rejects all variants of conflicting duplicate result IDs
  • derives score percentage and pass/fail outcome
  • aggregates deterministic module KPIs
  • exports cleaned data, rejected rows, KPIs and JSON quality metrics

Test coverage

  • verified sample control totals
  • expected output files
  • deterministic KPI values
  • required-column failure
  • conflicting duplicate rejection
  • identifier and whitespace normalisation
  • stable empty-KPI schema

CI integration

The Ubuntu 24.04 and Windows 2025 matrix now compiles and lints the new package, runs the full pytest suite, executes the data-quality CLI, validates the expected 15/8/7 control totals and uploads short-lived generated outputs.

Safety and scope

  • input data is synthetic
  • invalid rows remain auditable instead of being silently discarded
  • generated local and CI outputs stay outside version control
  • this is a learning-grade data-quality workflow, not a production ETL or regulatory-validation claim

Validation status

The PR will be merged only after the complete Ubuntu and Windows matrix succeeds on the final head.

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:3e79eba114

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +83 to +85
for column in REQUIRED_COLUMNS:
missing_mask = working[column].astype("string").str.strip().eq("")
_append_reason(reasons, missing_mask, f"missing_{column}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject null values in required fields

When callers pass a DataFrame containing pd.NA, None, or NaN, this expression produces an indeterminate Boolean rather than True, so _append_reason skips the missing value. The later numeric and date checks similarly fail to add a reason, allowing records with missing identifiers, modules, dates, or scores into cleaned and potentially omitting them from KPIs. Include working[column].isna() in the required-field mask.

Useful? React with 👍 / 👎.

Comment on lines +87 to +90
for column in NUMERIC_COLUMNS:
working[column] = pd.to_numeric(working[column], errors="coerce")
invalid_numeric = working[column].isna() & raw[column].astype("string").str.strip().ne("")
_append_reason(reasons, invalid_numeric, f"invalid_{column}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject non-finite numeric values

For CSV values such as inf or -inf, pd.to_numeric returns an infinity rather than NaN, so this validation does not classify them as invalid. In particular, a row whose score and maximum are both inf passes all range checks, is accepted, and derives a NaN score percentage that contaminates the cleaned output and module KPI. Explicitly require each converted numeric value to be finite.

Useful? React with 👍 / 👎.

if not input_path.is_file():
raise DataQualityError(f"Input file does not exist: {input_path}")

frame = pd.read_csv(input_path, dtype="string", keep_default_na=False)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve blank CSV rows for validation

When an input CSV contains a physically blank line, read_csv skips it by default, so the record is silently absent from both cleaned and rejected output. This also makes input_rows undercount the source and causes every subsequent source_row value to point to the wrong physical CSV line, undermining the workflow's audit trail. Disable blank-line skipping or otherwise retain the original physical line numbers.

Useful? React with 👍 / 👎.

@DataTideHH
DataTideHH merged commit 11eb3b6 into mainJul 28, 2026
2 checks passed
@DataTideHH
DataTideHH deleted the feat/data-quality-workflow branch July 28, 2026 17:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@DataTideHH