All notebook entries

A confusing age field broke the warehouse

A misunderstood estimated-age input produced future birth dates and negative ages. Fixing the resulting warehouse failures took clearer inputs, server validation, and careful repair of existing records.

Published

The failure showed up in the data warehouse: facility syncs kept retrying because insert batches contained negative ages. The destination used an unsigned integer for age, which could not store those values.

Following the data back into ZanLIS exposed a problem much earlier in the workflow. Some client records had birth dates in the future. The age calculation was exposing invalid source data.

An age input looked like a date input

The registration interface let staff enter an estimated age using Years, Months, and Days. Those fields could be mistaken for the components of a birth date. Entering a birth year where an age was expected produced a bad derived date, and the server lacked the birth-date validation needed to reject it.

By the time the warehouse complained, the value had already become part of a saved client record. It could display as a negative age in the laboratory system and block a batch of otherwise usable reporting data.

Changing the warehouse column to accept negative numbers would have allowed the insert without making the record meaningful. I needed to address both continued ingestion and the source of the error.

Make the interpretation visible before saving

The interface changes explained that the inputs expected an age, added sensible bounds, and showed an estimated birth-date preview while the user typed. That preview made the system's interpretation visible before submission.

Server-side checks enforced the same intent. A future birth date could no longer pass simply because a browser-side check was skipped. Later date-validation work also covered the sample-creation path, where normal field validators were being bypassed.

That distinction mattered. Improving the form helped staff enter the intended value. Enforcing the rule at the write boundary protected the stored record across submission paths.

Existing records needed a different kind of fix

Rejecting new invalid dates did not correct the dates already stored.

For a recognizable class of entry mistakes, historical entry dates and audit information gave me enough evidence to reconstruct a plausible intended value. The repair recorded its corrections, could be run repeatedly without reapplying them, and left implausible cases for manual review. It also marked corrected records as modified so downstream sync could discover the change.

The production repair ran on 16 July 2026. Further review of historical dates continued separately: an August scan identified client birth dates that required confirmation from the laboratories before correction.

That separation was deliberate. A value falling outside the accepted range established that something needed attention; it did not always tell me what the replacement should be. Automated repair was appropriate only where the error pattern and historical evidence supported it.

Recovery had to reach the reporting layer too

The warehouse received an interim normalization measure to keep these values from repeatedly crashing ingestion. That restored progress, but a successful sync was not proof that every age was now accurate.

After source correction, affected data still needed to be picked up or re-synced and checked in reporting. A repaired laboratory record and an updated warehouse row are separate steps.

This incident crossed a boundary I could easily have treated as someone else's layer: a reporting failure began with the meaning of a form field. The durable fix connected the user's interpretation, server-side validation, evidence-based repair, and downstream recovery.

Share this entry

Back to the notebook