Anomaly Upload Validator · Specification artifact
Product Requirements Document
What the tool had to do and the constraints it worked inside.
This page is rendered from that DOCX. Same document, same words.
Anomaly Upload Validator — Product Requirements Document
Platform A · Internal Tool · v3.1.4 · September 2026
Document Information
| Property | Detail |
|---|---|
| Product Name | Anomaly Upload Validator |
| Version | v3.1.4 (current; working file v9.1.4) |
| Document Status | Current — reflects delivered functionality through v3.1.4 |
| Author | Engineering |
| Last Updated | September 2026 |
| Distribution | data coordinators and engineering staff |
Executive Summary
The Anomaly Upload Validator is a browser-based internal tool that automates the pre-upload preparation of inspection datasets for Platform A. It accepts raw Input Source exports in CSV or XLSX format, validates them against the Platform A upload specification, converts field values across three nomenclature systems (Input Source → Platform A → Platform B), enables human-in-the-loop resolution of unmatched values, and produces a formatted multi-tab XLSX working document ready for upload.
The tool is distributed as a single self-contained HTML file requiring no installation, no server, and no authentication. All data processing runs client-side — no inspection data is transmitted externally.
Problem Statement
Background
Platform B wind farm asset owners engage both Platform A and third-party inspector Input Source for blade inspections. When third-party-sourced data needs to be ingested into Platform A and submitted to Platform B, it must pass through two conversion layers and conform to the Platform A upload specification.
Problems Identified
- Manual pre-upload checking was performed in spreadsheets with no standardized process, leading to inconsistent results and occasional failed uploads.
- Field value conversion across three nomenclature systems was performed manually using a reference spreadsheet, requiring significant coordinator time per dataset.
- Unrecognized field values had no structured resolution workflow — they were either missed or required escalation to Engineering via email.
- Multiple Input Source export formats exist across different client datasets, causing conversion failures when the wrong template was applied.
Impact: Each failed upload or conversion error requires manual rework estimated at 30–90 minutes per dataset.
Goals & Success Metrics
| Goal | Success Metric | Priority |
|---|---|---|
| Eliminate manual pre-upload field checking | 100% of required fields validated automatically | Must Have |
| Automate field value conversion | Zero manual conversion steps for known field values | Must Have |
| Structured resolution for unknown values | All unmatched values surfaced with dropdown resolution | Must Have |
| Support multiple source dataset formats | Handles all known Input Source export structures | Must Have |
| Zero installation / zero IT dependency | Runs in any modern browser from a shared Drive link | Must Have |
| Keep data internal | No inspection data transmitted outside local machine | Must Have |
| Engineering can extend conversion mappings | New rows in Conversions tab update formulas automatically | Should Have |
| Operational visibility | Compliance score, anomaly count, turbine count, site breakdown per run | Should Have |
Users & Personas
Data Coordinator (Primary User)
Receives raw Input Source exports from clients and prepares them for upload to Platform A. Non-technical. Needs clear pass/fail feedback without reading code or formulas.
Engineering / Data Lead (Secondary User)
Owns the conversion mapping tables and is responsible for extending them when new damage types or component combinations appear. Comfortable with spreadsheets. Needs to update the Conversions tab without breaking the output.
Operations Manager (Stakeholder)
Needs confidence that data being uploaded to Platform A and onward to Platform B is accurate and complete. Reviews compliance scores and flags for escalation.
Scope
In Scope — v3.1.4
- File ingestion: CSV and XLSX from Input Source
- Column-level validation: presence and naming of all required and conditional fields
- Row-level validation: field format rules (date, severity, Yes/No, blade side, numerics, coordinate pairs)
- Four-tier status system: Error, Manual Review, Check Internally, Warning
- Conversion engine: Input Source → Platform A → Platform B
- Three converted field groups: Element/Component, Anomaly Type, Blade Side
- Human-in-the-loop Manual Review resolution with dropdown selectors
- Dataset summary: anomaly count, unique turbines, site breakdown
- Export: Validation Report CSV + Converted XLSX (Damages Report + Conversions tabs)
- Multi-format support: Format A (Component + Material) and Format B (Component + Element) structures
Added since v2.1:
- Content-based column matching: a header-alias pass plus data-shape fingerprinting, so renamed or reordered columns resolve by what their values look like (v2.3)
- Automatic header-row detection beneath up to 25 rows of metadata preamble (v2.3)
- Bulk resolution of Manual Review flags across rows sharing a value (v2.2)
- Pass-through of Propagation Type, OpSeverity, Monitoring Recommendation and Tasks (v2.4)
- Revised output schema:
Assetcarries the blade letter, with turbine and asset serial numbers as separate fields (v2.5) - Clickable image hyperlinks in the exported report, with source URLs preserved exactly (v2.6, v2.7)
Out of Scope — v3.1.4
- Cross-field conditional validation (e.g. BladeChamber required when Damage Location = Internal)
- Duplicate anomaly ID detection
- Direct upload to either platform from the tool
- User authentication or access control
- Audit logging of validation runs (deferred — requires Apps Script or API access)
- Persistent storage of resolved manual review mappings across sessions
- Automated extension of VLOOKUP ranges when Engineering adds rows to Conversions tab
- Warning at ingest when image links are close to or past expiry (deferred; see v2.7 known issues)
- Severity-aware conversion, where severity forms part of the lookup key alongside size thresholds. One client's model requires it, and the flat three-column lookup cannot represent it.
Functional Requirements
FR-01 File Ingestion
| # | Requirement | Priority |
|---|---|---|
| FR-01.1 | Accept CSV (UTF-8) and XLSX / XLS file formats | Must Have |
| FR-01.2 | Files may be submitted via drag-and-drop or file browser dialog | Must Have |
| FR-01.3 | First sheet of any XLSX file shall be used as the data source | Must Have |
| FR-01.4 | Filename and row count shall be displayed on successful load | Must Have |
| FR-01.5 | Error message shall be displayed if file is empty or unparseable | Must Have |
| FR-01.6 | No file data shall be transmitted to any external server | Must Have |
| FR-01.7 | A date shall be ingested from its underlying value rather than from the parser's display formatting, so that the calendar date is identical in every timezone (v3.0) | Must Have |
| FR-01.8 | An ingested date shall be normalised to YYYY-MM-DD, retaining a time of day only where the source cell carries one (v3.0) | Must Have |
FR-02 Column Normalisation
| # | Requirement | Priority |
|---|---|---|
| FR-02.1 | Apply a column alias map to normalize variant column names before validation | Must Have |
| FR-02.2 | Aliases shall include: Date→Inspection Date, Blade Chamber→BladeChamber, Chord (%)→Chord(%), Turbine Serial Number→Serial Number, Links→Source Images | Must Have |
| FR-02.3 | Unrecognized column names shall be passed through unchanged | Must Have |
| FR-02.4 | Columns shall be matched by content as well as by name. The alias map is a fallback, not the primary mechanism (v2.3) | Must Have |
| FR-02.5 | Matching shall run two passes: header alias first, in priority order, then a data-shape fingerprint for any field still unmatched | Must Have |
| FR-02.6 | A field shall bind by data shape when at least 70% of sampled values in a candidate column match that field's expected shape | Must Have |
| FR-02.7 | Where one alias matches several columns, the candidate whose values best fit the field shall win; where shape cannot separate them, the column with more distinct values shall win | Must Have |
| FR-02.8 | The header row shall be detected automatically within the first 25 rows, so a file carrying a metadata preamble above its header is ingested without manual editing | Must Have |
| FR-02.9 | A confirmation panel shall show which input column bound to each canonical field, and whether it bound by name or by shape | Should Have |
FR-03 Column-Level Validation
| # | Requirement | Priority |
|---|---|---|
| FR-03.1 | Verify all 18 required field column headers are present (case-sensitive) | Must Have |
| FR-03.2 | Missing required columns shall be flagged with field name and description | Must Have |
| FR-03.3 | Missing conditional columns shall be reported as informational (non-blocking) | Must Have |
FR-04 Row-Level Validation
| # | Requirement | Priority |
|---|---|---|
| FR-04.1 | Every data row shall be validated against all required field rules | Must Have |
| FR-04.2 | Severity: integer value 1–5 only | Must Have |
| FR-04.3 | Critical: 'Yes' or 'No' (case-insensitive) | Must Have |
| FR-04.4 | Inspection Date: YYYY-MM-DD format strictly enforced | Must Have |
| FR-04.5 | Damage Location: 'Internal' or 'External' (case-insensitive) | Must Have |
| FR-04.6 | Blade Side: Code 1 / Value 1 / Code 2 / Value 2 / Code 3 / Value 3 / Code 4 / Value 4 | Must Have |
| FR-04.7 | Distance (m), Length (m), Width (m): numeric values | Must Have |
| FR-04.8 | Coordinates: must contain at least three [x,y] bracketed pairs | Must Have |
| FR-04.9 | Asset and Coordinates: when empty, flag as Check Internally rather than Error | Must Have |
| FR-04.10 | Serial Number: when empty or absent, raise no flag of any kind | Must Have |
FR-05 Conversion Engine
| # | Requirement | Priority |
|---|---|---|
| FR-05.1 | Detect Component+Material vs Component+Element column structure and apply appropriate concatenation | Must Have |
| FR-05.2 | Detect Type+Subtype vs AnomalyType+Subtype column structure and apply appropriate concatenation | Must Have |
| FR-05.3 | Concatenation shall use LEN()=0 guard (not ISBLANK) to handle empty string cells correctly | Must Have |
| FR-05.4 | Element conversion: Input Source Component → Platform A Element + Platform B Element via lookup | Must Have |
| FR-05.5 | Anomaly Type conversion: Input Source Damage Type → Platform A Anomaly Type + Platform B Anomaly Type via lookup | Must Have |
| FR-05.6 | Blade Side conversion: Blade Side → Platform A Blade Side + Platform B Blade Side via lookup | Must Have |
| FR-05.7 | Floating-point noise in numeric fields shall be cleaned to 4 decimal places on import | Should Have |
| FR-05.8 | Blade letter shall be extracted from Asset field when Blade column is empty or contains full label | Should Have |
| FR-05.9 | Derived column headers shall render both company names as those companies write them (v2.7.1) | Must Have |
FR-06 Status System
| # | Requirement | Priority |
|---|---|---|
| FR-06.1 | Each row issue shall be assigned one of four statuses: Error, Manual Review, Check Internally, Warning | Must Have |
| FR-06.2 | Error: required field absent or format invalid | Must Have |
| FR-06.3 | Manual Review: concatenated value not found in conversion lookup table | Must Have |
| FR-06.4 | Check Internally: Asset or Coordinates empty — value may exist in internal records | Must Have |
| FR-06.5 | Warning: conditional field populated but format invalid | Must Have |
| FR-06.6 | Check Internally rows shall be excluded from compliance score denominator | Must Have |
FR-07 Manual Review Resolution
| # | Requirement | Priority |
|---|---|---|
| FR-07.1 | Each Manual Review row shall display the original unmatched value | Must Have |
| FR-07.2 | A dropdown shall present all valid target-platform values for the affected field | Must Have |
| FR-07.3 | On selection, row status updates to Resolved and correct value written to converted dataset | Must Have |
| FR-07.4 | A progress counter shall show resolved / total Manual Review count | Must Have |
| FR-07.5 | Export Converted XLSX shall remain disabled until all Manual Reviews are resolved | Must Have |
FR-08 Results Dashboard
| # | Requirement | Priority |
|---|---|---|
| FR-08.1 | Summary cards: Total Rows, Clean, Errors, Manual Review, Check Internally, Warnings | Must Have |
| FR-08.2 | Compliance score as percentage with green/amber/red threshold coloring | Must Have |
| FR-08.3 | Auto-conversion count and Manual Review count as secondary cards | Must Have |
| FR-08.4 | Dataset summary: total anomalies, unique turbine count, site count, per-site breakdown | Must Have |
| FR-08.5 | Issues table filter tabs: All / Errors / Manual Review / Check Internally / Warnings | Must Have |
FR-09 Exports
| # | Requirement | Priority |
|---|---|---|
| FR-09.1 | Validation Report: dated CSV with columns Row, Anomaly ID, Field, Status, Detail | Must Have |
| FR-09.2 | Converted XLSX: two-tab workbook — Damages Report + Conversions | Must Have |
| FR-09.3 | Damages Report tab shall match column order of the amended Format A file exactly | Must Have |
| FR-09.4 | Derived columns shall use live VLOOKUP formulas referencing the Conversions tab | Must Have |
| FR-09.5 | Conversions tab structured in three editable sections: Element/Component, Anomaly Type, Blade Side | Must Have |
| FR-09.6 | Exported XLSX filename shall incorporate source filename and export date | Should Have |
| FR-09.7 | Every column carrying a value on input shall carry it on output. A column whose output header differs from its canonical field name shall still resolve (v3.1) | Must Have |
| FR-09.8 | The column-width list shall hold exactly one entry per output column, and shall be revised whenever a column is added, removed or inserted (v3.1.1) | Must Have |
| FR-09.9 | Column widths shall seat the widest value each column can hold, computed from the conversion tables where those define it (v3.1.3, v3.1.4) | Should Have |
Non-Functional Requirements
| ID | Category | Requirement |
|---|---|---|
| NFR-01 | Deployment | Single self-contained HTML file. No server, no installation, no authentication. |
| NFR-02 | Compatibility | Chrome, Edge, Firefox, Safari — any version released in the last 3 years. |
| NFR-03 | Data Privacy | All processing client-side. No data transmitted to any external endpoint. |
| NFR-04 | Performance | Must handle up to 10,000 rows without browser freezing. |
| NFR-05 | Dependencies | SheetJS is the only runtime dependency. Loaded from CDN; cacheable for offline use. |
| NFR-06 | Portability | Distributable via shared Drive folder with no configuration required by recipients. |
| NFR-07 | Maintainability | Conversion tables, field definitions, and aliases defined as named constants at top of script. |
| NFR-08 | Output fidelity | Exported XLSX formulas must use LEN()=0 guards rather than ISBLANK() for empty-string cells. |
Conversion Mapping Summary
Element / Component
Source: Component + Material column (falls back to Component + Element if Material absent)
Derivation: IF(LEN(Material)>0, Component & " - " & Material, IF(LEN(Element)>0, Component & " - " & Element, Component))
Output: Input Source Component → Platform A Element → Platform B Element
[Conversion table removed. The mapping across vendor, platform and client schemas is proprietary and is not distributed with this document.]
Anomaly Type
Source: Type + Subtype column (falls back to Anomaly Type + Subtype if Type absent)
Derivation: IF(LEN(Subtype)>0, Type & " - " & Subtype, Type)
Output: Input Source Damage Type → Platform A Anomaly Type → Platform B Anomaly Type
[Conversion table removed. The mapping across vendor, platform and client schemas is proprietary and is not distributed with this document.]
Blade Side
Source: Blade Side column (direct lookup — no concatenation)
Output: Blade Side → Platform A Blade Side → Platform B Blade Side
[Conversion table removed. The mapping across vendor, platform and client schemas is proprietary and is not distributed with this document.]
Supported Dataset Formats
| Format | Known Source | Element Columns | Anomaly Type Columns | Blade Column |
|---|---|---|---|---|
| Format A | Format A (Input Source) | Component + Material | Type + Subtype | Empty — extracted from Asset |
| Format B | Format B (Input Source) | Component + Element | Anomaly Type + Subtype | "Blade A" — letter extracted |
Assumptions & Constraints
Assumptions
- All source files are Input Source exports. Tool is not designed for other inspection platform formats.
- The first sheet of any XLSX file contains the inspection data.
- Column names are consistent within a given client's export format.
- Engineering is responsible for maintaining and extending the Conversions tab.
- Platform A upload specification does not change between tool versions without a corresponding tool update.
Constraints
- No server infrastructure available — tool must run entirely client-side.
- Google Apps Script deployment is restricted by company IT policy for user-facing web apps. Distribution via shared Google Drive is the approved method.
- SheetJS is the only permitted third-party dependency.
- VLOOKUP row ranges in exported XLSX are calculated at export time. Engineering adding rows beyond the current range requires manual formula updates.
Future Considerations
| Feature | Description | Priority |
|---|---|---|
| Persistent manual review mappings | Save resolved mappings to localStorage for reuse on future runs | High |
| Cross-field conditional validation | BladeChamber required when Damage Location = Internal | High |
| Duplicate anomaly ID detection | Flag rows where ID appears more than once | Medium |
| Dynamic VLOOKUP range expansion | Auto-extend formula ranges when Engineering adds rows | Medium |
| Audit logging | Write run summary to a shared Sheet — pending IT approval for API access | Medium |
| Direct platform upload | Submit directly to Platform A upload endpoint | Low |
| Additional source platform support | Extend alias map and format detection beyond Input Source | Low |
Sign-off
| Role | Name | Date | Status |
|---|---|---|---|
| Product Owner | May 2026 | Pending | |
| Engineering Lead | May 2026 | Pending | |
| Data Operations | May 2026 | Pending |
Sign-off above covers the v2.1 scope. Versions v2.2 to v3.1.4 have not been through a separate sign-off.
Anomaly Upload Validator · Platform A · Internal Use Only · v3.1.4 · September 2026