← Anomaly Upload Validator

Anomaly Upload Validator · Specification artifact

Data Dictionary

Every field, its source schema, and how it maps across vendor, platform, and client.

This page is rendered from that DOCX. Same document, same words.

Anomaly Upload Validator , Data Dictionary

Internal Tool · v3.1.4 · September 2026

About this revision

Updated 2026-09-17 from v2.1 to v2.7, then extended 2026-09-18 to v3.1.4. Three kinds of change in the first pass:

1. Output schema. The D/E/F columns were split (v2.5). Asset now carries the blade letter; turbine and asset serial numbers are separate fields.

2. Sanitization. Generic labels were inconsistent across the previous revision (four competing forms, some producing ungrammatical sentences). The whole document now uses one scheme, defined below.

3. Verification flags. Items marked [verify] could not be confirmed from the change log alone and need checking against a current export before this document is treated as authoritative. They are listed together in "Open verification items" at the end.

The tool's own version header and its working file advance together: v2.x / v8.x through v2.7.1, v3.x / v9.x since. This document describes v3.1.4 (working file v9.1.4).

The second pass, on 2026-09-18, carried the document from v2.7 to v3.1.4. That range is four defect fixes: the header misrenderings below (v2.7.1); a date fault that shifted CSV dates back a day west of UTC and made every dated row fail its own YYYY-MM-DD check in every timezone (v3.0); two output columns that wrote an empty cell under a correct header because the export looked them up by header text rather than canonical name (v3.1); and the export's column-width list, one entry short since the v2.5 split and so shifting every width from column E onward onto its right-hand neighbour (v3.1.1 through v3.1.4).

Generic labels used in this document

This is an internal tool operating between three commercial systems. Their names, and the contents of the conversion tables between them, are withheld. The structure is not.

Generic labels used in this document
LabelMeans
Input SourceThe inspection platform the raw dataset is exported from. Column A of the Conversions tab.
Platform AThe platform the dataset is being loaded into. Column B of the Conversions tab.
Platform BThe manufacturer's system the report is ultimately delivered in. Column C of the Conversions tab.

Conversion runs Input Source, then Platform A, then Platform B. All three classify the same physical damage differently, which is the problem this tool exists to solve.

Overview

This data dictionary defines every field the Anomaly Upload Validator processes, from the raw Input Source export columns through to the derived conversion columns in the exported XLSX. It covers field names, source column mappings, data types, classification, validation rules, and conversion output targets.

Field Classification Key

Field Classification Key
ClassificationMeaning
RequiredMust be present and non-empty in every data row. Missing or invalid values raise an Error.
ConditionalOptional. No flag raised if absent or empty. Format validated only when populated.
Check InternallyRequired in principle but may exist in internal records. Empty gives a Check Internally flag, not an Error, and is excluded from the compliance score.
RawSource columns used only as inputs to derivation formulas. Not directly validated.
DerivedComputed by the tool from raw source columns. Written to the output XLSX as lookup formulas.

Column Alias Map

The tool normalizes the following column name variants before validation. Applied silently at ingestion.

Column Alias Map
Raw Column NameNormalized ToNotes
DateInspection DateInput Source uses 'Date'; Platform A requires 'Inspection Date'
Blade ChamberBladeChamberSpace removed to match the Platform A column spec
Chord (%)Chord(%)Parenthetical formatting normalized
Turbine Serial NumberSerial NumberInput Source full label mapped to the Platform A short label. [verify] This alias predates the v2.5 D/E/F split and may now be ambiguous, since two serial-number fields exist.
LinksSource ImagesInput Source uses 'Links'; Platform A expects 'Source Images'

Since v2.3 the alias map is a fallback rather than the primary mechanism. Columns are matched by content as well as by name: see "Column matching" below.

Column matching

Added v2.3. Input files vary in column order, column names, and sheet structure, so a fixed-layout assumption failed on any file that did not match the canonical structure exactly.

The matcher runs two passes. First a header-alias match, priority-ordered so that a more specific alias wins over a general one. Second a data-shape fingerprint, comparing each candidate column's values against the expected shape of the field. Where alias matches are ambiguous, the closer shape match wins. Where shape scores tie, the column with more distinct values wins, which resolves the case of two identically named columns holding different things at different levels of the record.

The header row is detected automatically and is not assumed to be row 1: up to 25 rows of metadata preamble above the header are scanned and skipped. A collapsible confirmation panel shows which input column was bound to each canonical field.

Field Reference

All fields listed in the order they appear in the Damages Report output tab.

Output column letters confirmed 2026-09-17 against a current export header row. All previously flagged letters are resolved. The layout below is the real one, and it differs from the v2.1 document in more than position: four fields moved, two were removed, and one is new.

Field Reference
Field NameColSource Column(s)TypeClassificationFormat / Validation Rule
IDAIDStringRequiredAny non-empty value
SiteBSiteStringRequiredAny non-empty value
TurbineCTurbineStringRequiredAny non-empty value
AssetDBlade / Asset (extracted)StringRequiredSingle letter A to C. Changed at v2.5: carries the BLADE LETTER, not a turbine identifier. Extracted from a dedicated Blade column, a Blade Position column, a full label, or a bare letter.
Turbine Serial NumberEAsset (input column)StringConditionalNew at v2.5. Carries the value previously written to the output Asset column.
Asset Serial NumberFSerial Number (input column)StringConditionalNew at v2.5. Carries the value previously written to the output Serial Number column.
SeverityGSeverityIntegerRequiredMust be exactly 1, 2, 3, 4, or 5
CriticalHCriticalStringRequired. See D-5, open."Yes" or "No", case-insensitive
Propagation TypeIPropagation TypeStringConditionalPreserved unchanged
DateJDate / Inspection Date (alias)DateRequiredMust match YYYY-MM-DD exactly. The output header is Date, not Inspection Date.
OpSeverityKOpSeverityStringConditionalPreserved unchanged
Monitoring RecommendationLMonitoring RecommendationStringConditionalPreserved unchanged
Damage LocationMDamage LocationStringRequired. See D-5, open."Internal" or "External", case-insensitive
ComponentNComponentStringRawBase of the component concatenation
MaterialOMaterial / ElementStringRawCarries the effective suffix for both formats: Material for Format A, Element for Format B. The header stays Material either way.
Input Source ComponentPDerivedStringDerivedConcatenation of N and O. Lookup key for Q and R.
Platform A ElementQDerivedStringDerivedLookup on P, column 2
Platform B ElementRDerivedStringDerivedLookup on P, column 3
TypeSType / Anomaly TypeStringRawCarries the damage base for both formats: Type for Format A, Anomaly Type for Format B. The header stays Type either way.
SubtypeTSubtypeStringRawOptional. Appended to the base if non-empty.
Input Source Damage TypeUDerivedStringDerivedConcatenation of S and T. Lookup key for V and W.
Platform A Anomaly TypeVDerivedStringDerivedLookup on U, column 2
Platform B Anomaly TypeWDerivedStringDerivedLookup on U, column 3
Blade SideXBlade SideStringRequiredCode 1 / Value 1 / Code 2 / Value 2 / Code 3 / Value 3 / Code 4 / Value 4
Platform A Blade SideYDerivedStringDerivedDirect lookup on X, column 2
Platform B Blade SideZDerivedStringDerivedDirect lookup on X, column 3
Blade ChamberAABlade ChamberStringConditionalAny value, no format rule. The output header is Blade Chamber with a space, not BladeChamber.
Distance (m)ABDistance (m)DecimalRequiredNumeric, float noise cleaned to 4dp
Length (m)ACLength (m)DecimalRequiredNumeric, float noise cleaned to 4dp
Width (m)ADWidth (m)DecimalRequiredNumeric, float noise cleaned to 4dp
Chord (%)AEChord (%)DecimalConditionalNumeric if present, float noise cleaned to 4dp
ActionAFActionStringConditionalPreserved unchanged
RuleAGRuleStringConditionalPreserved unchanged
CoordinatesAHCoordinatesStringCheck InternallyAt least 3 [x,y] pairs. Empty gives a Check Internally flag.
Source Image ReferenceAISource Image ReferenceStringRequiredIdentifier, not a URL. No hyperlink attached.
LinksAJLinksStringRequiredURL value. Hyperlink attached since v2.6.
Source ImagesAKSource ImagesStringRequiredURL value. Hyperlink attached since v2.6.
Source Image Expiration DateALDerived or passed through. [verify]Date[verify]Not documented anywhere. Present in the current export, absent from the v2.1 dictionary and from the change log. See open items.
TasksAMTasksStringConditionalPreserved unchanged

Output header names were misrendered in four of eight derived columns. FIXED in v2.7.1.

Corrected in v2.7.1 (working file v8.9.1) on 2026-09-17, verified against a live export, and carried forward unchanged since. All four headers now render both company names correctly. Retained as a record of the defect and of what it showed about the "preserved intentionally" note, not as a description of current behaviour.

The defect as it stood through v2.7: two separate name errors, neither applied consistently.

Field Reference
ColHeader through v2.7Error
PSource-system name, lower-cased mid-wordCasing
QPlatform A name, two letters transposedTransposition
RPlatform B nameCorrect
USource-system name, lower-cased mid-wordCasing
VPlatform A nameCorrect
WPlatform B nameCorrect
YPlatform A name, two letters transposedTransposition
ZPlatform B nameCorrect

Four of the eight derived columns carried a wrong rendering of a company name. Two different companies, two different kinds of error, and the same name appeared correct in one column and wrong in another.

This settled how the typo item should be read. The v2.1 limitation log records the misspelling as preserved intentionally, which implied a downstream consumer matching on that exact string. A deliberately preserved convention would have been consistent. Four of eight, with one name spelled both ways in the same sheet, was accumulated copy error rather than convention.

Consequences worth stating plainly:

LIM-07: CLOSED, 2026-09-18. Closed by the v2.7.1 correction, verified against the header row of a live export read from the raw file rather than from a summary.

It is closed as copy error, not convention. The v2.1 log recorded the misspelling as preserved intentionally, which implied a downstream consumer matching on that exact string. Nothing did. Before the correction the tool was searched for all four misrendered strings: every occurrence was on the output side, and the input-side column matcher — both its alias map and its field signatures — contained neither spelling. No ingestion path depended on a misrendered form, so none was made tolerant of one, and files exported before the change ingest exactly as they did before. The question this document put to Engineering, "what matched on those strings when they were preserved, and does it still", is answered: nothing did, and nothing does.

The casing error takes no entry of its own. It was found and fixed within the same change, so it was never an open item.

Scope note: the v2.1 limitation log that holds the LIM-07 entry is not part of this sanitized document set. This records the closure; if that log is maintained separately it still shows LIM-07 open and needs the same update.

Sanitized note: these headers appear in this document under generic labels, so neither error surfaces here. Both are recorded because they describe every export produced up to v2.7.1, which anyone opening an older file will still see.

What changed against the v2.1 document, beyond position

Note on the pass-through fields. Propagation Type, OpSeverity, Monitoring Recommendation and Tasks were defined in this document at v2.1 and were correct. What was wrong was the tool: the matcher held no field signatures for them, so it never bound the input column and the export wrote a header with nothing beneath it. Signatures were added at v2.4. The definitions did not change.

Derived Fields

Computed by the tool from raw source columns. Written as lookup formulas in the output XLSX.

Column references confirmed 2026-09-17. The change log's references to a Material slot at N and a Type slot at R, and this document's previous references to O, T and W, were all pre-v2.5 values. The v2.5 insertion shifted every one of them by exactly one position, which is why the two sets never reconciled. The values below are post-v2.5 and match the current export.

Field Reference
FieldColFormula
Input Source ComponentPIF(LEN(O2)>0, N2&" - "&O2, N2)
Platform A ElementQIFERROR(VLOOKUP(P2, Conversions!A:C, 2, FALSE), "MANUAL REVIEW: "&P2)
Platform B ElementRIFERROR(VLOOKUP(P2, Conversions!A:C, 3, FALSE), "MANUAL REVIEW: "&P2)
Input Source Damage TypeUIF(LEN(T2)>0, S2&" - "&T2, S2)
Platform A Anomaly TypeVIFERROR(VLOOKUP(U2, Conversions!A:C, 2, FALSE), "MANUAL REVIEW: "&U2)
Platform B Anomaly TypeWIFERROR(VLOOKUP(U2, Conversions!A:C, 3, FALSE), "MANUAL REVIEW: "&U2)
Platform A Blade SideYIFERROR(VLOOKUP(X2, Conversions!A:C, 2, FALSE), "MANUAL REVIEW: "&X2)
Platform B Blade SideZIFERROR(VLOOKUP(X2, Conversions!A:C, 3, FALSE), "MANUAL REVIEW: "&X2)

Row 2 shown as the example row. LEN() is used rather than ISBLANK() because ISBLANK() returns FALSE for an empty-string cell, which produced a trailing separator on the derived value. Fixed at v2.1.

Derivation rule, added v2.4. Any raw input value the export needs is read from the untouched input row, never from the working row. The row object is mutated during derivation, so reading a value back from it after processing returns the already-transformed value and concatenates it a second time.

Format handling, added v2.4. The formulas reference the output slots rather than the raw input columns, so one formula path serves both input formats. The output Material slot carries the effective suffix, Material for Format A and Element for Format B. The output Type slot carries the damage base, Type for Format A and Anomaly Type for Format B.

Dataset Format Variations

Two distinct Input Source export formats are handled. Format is detected automatically.

Dataset Format Variations
FieldFormat AFormat BDetection Logic
Element sourceComponent + MaterialComponent + ElementCheck whether a Material column exists
Element formulaComponent & " - " & MaterialComponent & " - " & ElementLEN(Material)>0 uses Material, else Element
Damage Type sourceType + SubtypeAnomaly Type + SubtypeCheck whether a Type column exists
Damage Type formulaType & " - " & SubtypeAnomaly Type & " - " & SubtypeLEN(Type)>0 uses Type, else Anomaly Type
Blade fieldEmpty, extracted from Asset"Blade A", letter extractedAccepts a full label, a bare letter, a Blade column, or a Blade Position column

Provenance note. Format B support was built against illustrative reconstructed examples and was first confirmed against a genuine Input Source export later. Treat any Format B behavior not exercised by a real file as unverified.

Conversion Lookup Tables

The three lookup tables live in the Conversions tab of the exported XLSX. Columns are A (Input Source) then B (Platform A) then C (Platform B).

What is published here and what is not. The structure of the conversion problem is described below. The tables themselves are not, because the category names, code values and the mappings between them are the commercial property of the platforms and the manufacturers involved. The redaction is deliberate and is marked where it applies rather than left as a silent gap.

Structure, which is publishable:

Illustrative shape only, with invented values:

[input category A] -> [platform A category 2] -> [platform B code X]

[input category B] -> [platform A category 2] -> [platform B code X]

[input category C] -> (no clean target) -> held for manual review

Element / Component Conversions

Lookup key: Input Source Component.

[Table withheld. See the redaction note above.]

Anomaly Type Conversions

Lookup key: Input Source Damage Type.

[Table withheld. See the redaction note above.]

Blade Side Conversions

Lookup key: Blade Side, a direct lookup with no concatenation.

[Table withheld. See the redaction note above.]

Table currency

The tool currently uses the original key set. A reconciled union table built from the conversion tables of genuine delivered files is staged but not wired in, pending confirmation of four conflicting mappings where the same source value resolves to different targets in files of different dates.

Reconciliation rule. The tables reconcile by union, not intersection. A key absent from one client's table is a key that client's data has never needed. Absent does not mean retired, and pruning on that basis would silently drop valid mappings.

Validation Status Reference

Validation Status Reference
StatusTriggerCompliance ScoreExport Gate
ErrorRequired field missing or format invalidCounts against scoreDoes not block export
Manual ReviewConcatenated value not found in the conversion tableCounts against scoreBlocks export until resolved
Check InternallyField empty where the value may exist in internal recordsExcluded from scoreDoes not block export
WarningConditional field format invalidCounts against scoreDoes not block export

Manual Review flags can be resolved in bulk from within the tool rather than row by row (added v2.2). The export button stays disabled until every Manual Review flag is cleared.

Compliance Score Formula

Score = ROUND( cleanRows / (totalRows - checkInternallyRows) * 100, 0 )

cleanRows counts rows with no issues of any kind. Check Internally rows are excluded from the denominator.

Known Limitations

Open verification items

Resolved 2026-09-17 by a current export header row: all output column letters, every derived-field formula reference, the classification of Asset and the two serial-number fields, and whether Blade survives as its own column. It does not.

Three items remain.

1. Source Image Expiration Date, column AL. Present in the current export, absent from the v2.1 dictionary and absent from the change log across all six versions. Either it predates v2.1 and was never documented, or it shipped without a change-log entry. Needs classification, a source, and a format rule. The change log lists an expiry warning at ingest as a deferred idea, so a column already emitting the expiry date is worth reconciling against that.

2. The Turbine Serial Number to Serial Number alias. Predates the v2.5 split and now sits against two serial-number fields. Confirm which it feeds.

3. Classification of Critical and Damage Location. Open as D-5. Both currently Required, both empty in some client files and absent as columns in others, both therefore penalising the compliance score for data the client never supplies. Reclassification to Check Internally is under consideration.

Anomaly Upload Validator · Internal Use Only · v3.1.4 · September 2026

← Back to the Anomaly Upload Validator case study