Skip to content

Classify import exceptions into named buckets (grouped summary + detail), instead of one flat fail file #299

Description

@bosd

The idea

Today a failed import produces one flat fail file. In practice the failures are not one thing — they are several distinct populations, each needing a different decision by a different person. Sorting them into named buckets is what actually moves a migration forward.

This is not speculative. On a live migration project the buckets emerged by hand as ~22 CSVs in a review/ directory, built one at a time as each problem surfaced. That accidental taxonomy is the requirement; this issue is about making Fluvo produce it deliberately.

The taxonomy that actually emerged

Generalised from real migration work (part/product data, ~40k affected rows):

Excel mangling — source data damaged before Fluvo ever saw it

  • Scientific notation: a 12-digit part number arrives as 1,1253E+11
  • Trailing-zero loss: 0100100
  • Normalisation collisions: two distinct codes become identical once cleaned
  • Case-only duplicates

Duplicates

  • Duplicate internal references within the source
  • References colliding with records already loaded in the target — a different decision from an intra-source duplicate, because one side is already live

Needs a client decision — nothing is technically wrong; someone has to choose

  • Dormant records: archive, restore, or keep
  • Records missing a business prerequisite (e.g. no supplier) — migrate anyway or exclude

Blocked on missing reference data

  • Unresolved vendor/partner references
  • Records referencing a category or code that does not exist
  • Reference records that exist but carry no name

Company-dependent conflicts

The organising principle: bucket by who decides, not by what is wrong

This is the part that makes it more than a categorised error log, and it should drive the design:

Owner Examples What the tool does
Fluvo can fix scientific notation, trailing zeros, case normalisation Propose the correction, show it, apply on confirmation
The client must decide dormant records, records without a supplier, which duplicate wins Present the choice; do not guess
Blocked on missing data unresolved vendors, missing categories Ask for the missing input

A client should only ever be shown the middle row. Mixing the three is why a raw fail file is unusable as a client-facing artifact.

Volume forces aggregation, not just filtering

Real numbers from that project: the duplicate-reference detail file is 40,340 rows; the trailing-zero file is 454 KB. Neither can go in front of a human.

But the grouped view of the same data is 222 groups — and that is reviewable.

So a bucket is two artifacts, not one:

  • a grouped summary (one row per decision, human-sized), and
  • the detail rows behind each group (machine-sized, for the fix pass).

This is the same constraint already recorded for the staging portal — heavy lifting in Polars, only what needs a human goes to the review layer.

Scope

v1 — core, free:

Out of scope here: the visual review layer (staging portal / Flowfile — PLAN phase 5, #288) and the client-facing summary report, which is a premium artifact and is tracked privately.

Why this belongs in core

It is part of doing an import well — Fluvo already writes fail files, and this is those fail files made useful. It is also the substrate the premium reporting sits on, so it needs to exist and be good regardless of what gets sold on top.

Acceptance

  • Re-running a migration reproduces the same bucket ids for the same underlying problems.
  • A bucket with tens of thousands of detail rows still yields a grouped summary a person can read in one screen.
  • Every existing detector routes into the bucket system; none keeps a private output format.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions