Chapter 4

Chapter 4: Avionics and the WIA Data Format

Chapter overview: This chapter first surveys the avionics that navigate, communicate and keep an aircraft separated from traffic, and shows why each avionics box is a serialised line-replaceable unit with its own hardware and software configuration. It then opens PHASE 1 of WIA-SPACE-016, the data format, walks through every field of the AircraftComponent record, and ends by writing and testing a JSON Schema 2020-12 definition for it. The avionics LRU is the running example because it stresses the data model in ways a structural part does not.

4.1 Avionics Overview

"Avionics" covers the electronic systems an aircraft carries: navigation, communication, surveillance, flight management, displays, autoflight, and the monitoring equipment that ties them together. On a transport aircraft most of them live in racks of boxes in an electronics bay, wired to antennas, sensors and cockpit displays. The engineering question is what each system does and how accurate or redundant it must be. The records question, the subject of this book, is which physical unit, running which software, was installed where, and on what approval basis.

Navigation: GNSS, SBAS, inertial reference and the FMS

Satellite navigation (GNSS) derives position from constellations such as GPS, GLONASS, Galileo and BeiDou. Aviation receivers continuously check the integrity of the solution, and many use a satellite-based augmentation system (SBAS) that broadcasts corrections and integrity data from geostationary satellites. Examples are WAAS in North America, EGNOS in Europe, MSAS in Japan, GAGAN in India and KASS in Korea. SBAS is what allows approaches with vertical guidance without ground-based landing aids at every runway. The accuracy figures in the PHASE-2 source depend on receiver class and geometry. Treat them as indicative, not as requirements the data format checks.

An inertial reference system (IRS) integrates accelerations and rotation rates, usually measured by ring-laser or fibre-optic gyros in airliners. It needs no external signal, so it survives GNSS outages and jamming, but its position error grows with time. Navigation-grade systems are usually described as "about 1 nautical mile per hour class" free-inertial performance, and they must align while the aircraft is stationary, taking longer at high latitudes. The flight management system (FMS) sits above both sensors. It holds a navigation database revised on the ICAO 28-day AIRAC cycle and an aircraft-specific performance database, and it computes lateral (LNAV) and vertical (VNAV) guidance. The FMS shows why avionics records are not just "one part number": the same hardware can carry different software releases and a database that changes every four weeks.

Communication: VHF, HF, SATCOM and data link

Air-traffic voice communication uses VHF amplitude-modulated radios in the band from about 118 to 137 MHz. Congestion in Europe led to 8.33 kHz channel spacing, which splits each historical 25 kHz channel into three. The 19 MHz band therefore holds about 760 channels at 25 kHz but roughly 2,280 at 8.33 kHz. Under 8.33 kHz spacing, the six-digit "channel name" a pilot selects is not always equal to the carrier frequency, so a record that stores "the frequency" should say which one it means. VHF propagation is essentially line-of-sight, so range grows with altitude:

Worked example: VHF radio horizon (approximation)
d [NM] ≈ 1.23 × √h [ft]      (standard-atmosphere radio horizon)

Aircraft at h = 35,000 ft, ground station at sea level:
  √35,000 ≈ 187.1   →   d ≈ 1.23 × 187.1 ≈ 230 NM

Two aircraft, both at 35,000 ft:
  d ≈ 230 + 230 ≈ 460 NM (terrain, power and receiver sensitivity permitting)

That geometry is why the PHASE-2 source describes VHF coverage as a few hundred nautical miles at cruise. Beyond line of sight, aircraft use HF radios with single-sideband voice and HF data link, relying on ionospheric propagation that varies with time of day, season and solar activity. SATCOM provides voice and data through geostationary systems such as Inmarsat and low-earth-orbit systems such as Iridium, the latter also covering the polar regions. Data rates differ widely by generation and service, so a record should store the terminal's part number and configuration rather than a data-rate figure. ACARS messaging and controller–pilot data link communications (CPDLC) run over these bearers.

Surveillance: TCAS II and ADS-B

TCAS II, the equipment implementing ICAO's ACAS II, interrogates nearby transponders on 1030 MHz and receives replies on 1090 MHz. From range, range rate and altitude it estimates time to closest approach, then issues a traffic advisory (TA) and, if needed, a resolution advisory (RA), a vertical manoeuvre coordinated with the other aircraft's TCAS. The warning times are not fixed. The thresholds grow with altitude through a set of sensitivity levels, spanning roughly 20–48 seconds for a TA and 15–35 seconds for an RA, so the single figures in the PHASE-2 source are one point in that range. The logic version (currently 7.1) is itself a configuration item a records system should show.

ADS-B turns the idea around: the aircraft broadcasts its own GNSS-derived position, velocity and identity, most commonly on 1090 MHz Extended Squitter (1090ES). ADS-B Out is mandated in several jurisdictions, including the United States and Europe, but rules, dates and airspace differ, and the United States also accepts 978 MHz UAT equipment in some airspace. A component record should capture what the unit is capable of and approved for, and leave "is this aircraft compliant here?" to the operator's configuration management.

The avionics box as a serialised LRU

Most avionics functions are packaged as line-replaceable units (LRUs): sealed boxes a line mechanic can swap at the gate, with the failed unit sent to a shop. Form-factor standards such as ARINC 600 standardise racks, connectors and cooling, and data buses such as ARINC 429 and ARINC 664 Part 7 (AFDX) connect the boxes. Four identities matter for each unit:

FunctionTypical equipmentConfiguration facts beyond P/N and S/N
NavigationGNSS receiver, IRS, FMS computerSoftware P/N, navigation database cycle, SBAS capability, installed position
CommunicationVHF, HF and SATCOM transceivers, data link unitSoftware P/N, 8.33 kHz capability, enabled data link applications, modification status
SurveillanceTCAS II computer, Mode S transponder with ADS-B OutCollision-avoidance logic version, ADS-B output version; the 24-bit aircraft address belongs to the airframe
All LRUs—Approval basis (e.g., TSO), DO-160G categories, DAL of hosted software, release certificate reference

The transponder's 24-bit ICAO address is set at installation for the airframe registration; it does not belong to the box. That distinction between the unit and its installation recurs throughout this chapter. The WIA record describes the unit. The installation is a relationship over time, recorded by the traceability operation group (Chapter 5) and the maintenance-event flow (Chapter 6).

4.2 The Purpose of PHASE 1

The PHASE-1 document states its scope in one sentence: it defines "the canonical data structures for aircraft component identification, structural envelopes, material certification records, and traceability metadata," expressed in JSON Schema 2020-12 and stable for the lifetime of the phase. Each phrase corresponds to a group of fields in the reference types:

PHASE-1 concernWhat it answersFields in the reference types
Component identificationWhich design, and which individual unit?id, type, partNumber, serialNumber, manufacturer, manufacturingDate
Structural envelopeHow big and heavy, and what loads was it shown to carry?dimensions, structuralAnalysis
Material certificationWhat is it made of, with which properties?material
Traceability metadataWhat approvals, inspections and history attach to it?status, certification, inspectionHistory, metadata

Why a canonical format, and why JSON Schema 2020-12

Component data moves between organisations in many shapes: a supplier's ERP export, a PDF release certificate, an MRO shop's work-order system, an airline's technical records database. Each describes the same serial number in its own vocabulary, and every hand-off is a place where a digit is transposed or a modification status is lost. A canonical format does not replace those systems. It gives them one representation to exchange, which a receiver can validate mechanically before a person looks at it. That is why PHASE 1 precedes the API (PHASE 2) and the protocol (PHASE 3): an interface is only as precise as the data it carries.

JSON Schema 2020-12 is the draft that OpenAPI 3.1 aligns with, which matters because PHASE 2 describes its interface in OpenAPI. One schema can then validate stored records, API request bodies and inter-organisation messages. The draft also introduced $defs for reusable sub-schemas and moved format checking into an optional vocabulary, a detail that matters in Section 4.6.

What the specification file does and does not contain

After its short introduction, the PHASE-1 file consists of engineering reference material (fuselage, wing and tail construction; aluminium, titanium and composite properties), which Chapter 2 covered. It contains no machine-readable schema. The concrete shape of the record is defined by the TypeScript reference types in the SDK package @wia/aircraft-component (api/typescript/src/types.ts). This chapter treats those types as the normative shape and derives a JSON Schema from them. Where the types leave a question open, the answer given here is marked as a proposal. The file's reference list also cites a hardware-component identification standard that could not be verified, so this book does not rely on it. The quality-system references it names, AS9100D and AS9145, are real and return in Chapter 7.

4.3 Anatomy of AircraftComponent

AircraftComponent is the root object: one record per physical, serialised component. The table lists every field of the reference type, its unit or format, whether it is mandatory, and the real-world document that normally supplies the value. The last column matters most in practice, because a field without a clear source gets filled inconsistently.

FieldTypeUnit / formatRequiredTypical source document
idstringopaque (UUID recommended)yesAssigned by the creating system
typeComponentType9 enum valuesyesEngineering classification
statusComponentStatus6 enum valuesyesLifecycle state (see below)
partNumberstringas markedyesNameplate, drawing, parts catalogue
serialNumberstringas markedyesNameplate, release certificate
manufacturerstringlegal nameyesProduction approval holder, CoC
manufacturingDatestringISO 8601 dateyesProduction record
dimensionsDimensionsmm, kgyesOutline and installation drawing
materialMaterialSpecificationMPa, kg/m³yesMaterial certificate, drawing notes
structuralAnalysisStructuralAnalysiskN, MPa, cyclesnoStress report
certificationCertificationISO 8601 datesnoApproval document
inspectionHistoryInspection[]array, may be emptyyesInspection reports, work orders
metadataobjectfree-formnoAnything not modelled above

Identity and classification

The id is the record's key inside a system. It should be opaque, such as a UUID, and never built from part and serial number: part numbers change when a unit is modified and re-identified, and records are merged when systems are reconciled, and an identifier that encodes business data breaks in both cases. The business identity of a unit is manufacturer + part number + serial number (Section 4.5).

type takes one of nine values: fuselage, wing, tail, landing-gear, flight-control, hydraulic-system, fuel-system, avionics, engine-mount. This coarse taxonomy supports search (ComponentSearchQuery.type, Chapter 5) and tells a reader which other fields are meaningful. It does not replace the industry's ATA iSpec 2200 chapter numbering, in which communications is chapter 23, navigation 34 and auto flight 22. For avionics, record the ATA chapter in metadata as well.

The status field and its two meanings

status takes design, testing, certified, production, maintenance and retired, and the list mixes two lifecycles. The first three describe a design, and they are the same for every serial number of that part number. The last three describe an individual unit: produced, in the maintenance loop, retired. For serialised records this book uses the unit reading. A newly released unit is production, a unit removed to a shop is maintenance, a scrapped or life-expired unit is retired. The earlier states are reserved for prototypes and test articles, such as a qualification unit that went through DO-160 testing and will never fly. Chapter 6 formalises the transitions. An implementation should declare its interpretation, ideally in its profile manifest (Chapter 8).

A complete record for an avionics LRU

The example describes a fictional VHF transceiver, and every name, number and dimension in it is illustrative. The material block reuses the PHASE-1 values for 2024-T3 only to show the units. A real chassis alloy comes from the manufacturer's drawing. Facts the reference types cannot hold have gone into metadata (Section 4.5).

Example (illustrative): AircraftComponent record for a VHF transceiver LRU
{
  "id": "3f2b8c1e-6a4d-4e0b-9c57-1d2e8a7b5f10",
  "type": "avionics",
  "status": "production",
  "partNumber": "EXV-2100-01",
  "serialNumber": "VX21-004517",
  "manufacturer": "Example Avionics Co.",
  "manufacturingDate": "2024-03-15",
  "dimensions": { "length": 320, "width": 60, "height": 194, "weight": 3.2 },
  "material": {
    "type": "aluminum-2024",
    "grade": "2024-T3 (chassis sheet)",
    "strength": 470,
    "fatigueLimit": 140,
    "density": 2780,
    "corrosionResistance": "medium"
  },
  "inspectionHistory": [
    {
      "id": "insp-2024-000871",
      "inspectionDate": "2024-03-18",
      "inspector": "QA-017",
      "method": "visual",
      "result": "pass",
      "findings": "Receiving inspection: nameplate, connector pins, seals and labels conform."
    }
  ],
  "metadata": {
    "wiaSchemaVersion": "1.0.0",
    "manufacturerCode": { "scheme": "CAGE", "value": "EX001" },
    "ataChapter": "23",
    "hardwareModStatus": "B",
    "softwareParts": [ { "role": "radio application", "partNumber": "EXV-SW-2100-0304" } ],
    "approvalBasis": [ { "authority": "FAA", "basis": "TSO-C169a" } ],
    "environmentalQualification": "RTCA DO-160G, categories per the unit's declaration",
    "capabilities": { "channelSpacingKHz": [25, 8.33] },
    "releaseCertificate": { "form": "FAA Form 8130-3", "trackingNumber": "EX-000123" },
    "usage": { "hoursSinceNew": 0, "cyclesSinceNew": 0, "asOf": "2024-03-18" }
  }
}

Three things are absent on purpose. There is no structuralAnalysis, because an LRU's mechanical qualification is its DO-160 vibration and shock testing, and inventing an applied load to fill the field would make the record less truthful. There is no certification, for a reason explained in Section 4.4. And there is no installed position or registration, because those belong to the installation.

4.4 The Sub-objects

Dimensions

Dimensions holds length, width and height in millimetres and weight in kilograms. The "weight" is a mass, not a force, and a system converting it to newtons or pounds-force must know that. The three lengths are a bounding envelope for handling, packaging and storage, not a geometric model: for a wing panel the "height" is a few millimetres over a span of metres. Where the drawing allows a weight tolerance, record the measured weight of the unit, since that is what the aircraft's weight-and-balance records ultimately depend on.

MaterialSpecification

MaterialSpecification carries type (aluminum-2024, aluminum-7075, titanium-ti6al4v, carbon-fiber, fiberglass, aramid, composite), a free-text grade, strength and fatigueLimit in MPa, density in kg/m³, and a three-level corrosionResistance. Chapter 2 covered the materials themselves. Four conventions are needed to write them down consistently:

StructuralAnalysis

StructuralAnalysis summarises a stress analysis: appliedLoad (kN), calculatedStress (MPa), a dimensionless safetyFactor, fatigueLife (cycles), analysisDate and analyst. It is a summary, never the analysis. The stress report, with its load cases, finite-element model and margins at each critical location, stays in the design organisation's controlled documents, and the record should cite it by number and revision in metadata.

The field name safetyFactor is ambiguous. The ratio of allowable to applied stress is a reserve factor, and the margin of safety is that ratio minus one (MS = allowable/applied − 1, Chapter 1). The factor of safety of 1.5 in CS/FAR 25.303 is something else: it converts limit loads to ultimate loads before any comparison. Following Chapter 1, this book stores the ratio of the allowable to the ultimate-level design stress (special factors included) at the critical location for the governing load case, with the load case named in metadata. Under that convention the pass criterion is 1.0, so the SDK helper ComponentAnalyzer.isSafe, whose default threshold is 1.5, must be called with an explicit minimum of 1.0; its default only makes sense for a stress computed at limit load (Chapter 5). fatigueLife must come from the fatigue and damage-tolerance analysis (Chapter 7), never from the SDK's estimateFatigueLife, whose formula returns 10⁸ cycles when applied stress equals ultimate strength. Chapter 5 examines it as an anti-example.

Certification

Certification has six mandatory fields: standard, authority, certificateNumber, issueDate, expiryDate and a boolean compliance. The reference types' comment suggests "WIA-SPACE-016" as a standard, while PHASE 2's certification-package group speaks of evidence for aviation authorities, so the object is generic. Records should use precise values, such as "TSO-C169a" with "FAA", rather than a vague "FAA certified".

The difficulty is expiryDate. A TSO authorisation, a type certificate, an FAA Form 8130-3 or an EASA Form 1 has no calendar expiry. It stays valid until surrendered, suspended or superseded, or until the part's condition changes. Filling a required expiry field with an invented far-future date would falsify the record. That is why the LRU example omits the optional certification object and records its approval basis in metadata.approvalBasis. Things that genuinely expire, such as a sealant batch's shelf life or a test set's calibration, are better modelled as their own records.

Inspection

Each Inspection has id, inspectionDate, inspector, method, result, and optional findings and nextInspectionDate. The five methods (visual, ultrasonic, radiographic, magnetic-particle, eddy-current) are NDI techniques, described in Chapter 7. Two gaps are immediate. Liquid penetrant inspection, one of the most common methods, is missing. So is any functional or bench test, which is how a shop actually checks an avionics unit against its acceptance test procedure. Until the enum grows, such tests belong in metadata or a maintenance event (Chapter 6), and visual should record only what was genuinely visual.

The result values are pass, fail and conditional. "Conditional" means within limits but to be watched, and without findings and nextInspectionDate it is not actionable. The schema in Section 4.6 enforces that pairing. inspector should be an identifier the quality system can resolve to a qualified person, not a name typed by hand. Many inspections are scheduled in hours or cycles, which a calendar nextInspectionDate cannot express. That is one more reason usage counters are needed.

4.5 Identifier Design

Part number, serial number and manufacturer

A serial number is unique only within a manufacturer's part number, and sometimes only within a manufacturer. Two suppliers can both ship serial number 1001. The business key of a WIA record should therefore be the triple (manufacturer, partNumber, serialNumber), and a registry should reject a duplicate triple. Because manufacturer is free text, and "Example Avionics Co." and "Example Avionics Company" would compare as different, store a coded identifier in metadata too. In much of the aerospace supply chain that is the CAGE code, a five-character code assigned in the United States by the Defense Logistics Agency, with NCAGE codes for organisations in other participating nations. The example records it as {"scheme": "CAGE", "value": "EX001"} so that other schemes can be named explicitly.

Part and serial numbers must be stored exactly as marked, including dashes and leading zeros. Normalising them eases matching inside one database but destroys the match with the physical nameplate, which is what an inspector or an investigator of suspected unapproved parts will check. If a normalised form is needed for search, keep it as a derived value.

Dates, times and units

All dates are strings. This book requires ISO 8601 calendar dates in YYYY-MM-DD form (the RFC 3339 full-date) for manufacturingDate, inspectionDate, nextInspectionDate, issueDate, expiryDate and analysisDate. Events that need a time of day use a full RFC 3339 timestamp with an explicit UTC offset, since aircraft and shops span time zones. Units are fixed by the field definitions (mm, kg, kN, MPa, kg/m³, cycles) and are never written as strings with suffixes. A system that ingests inches or pounds converts at the boundary and may keep the original in metadata for audit.

What the reference types cannot express

The avionics example exposes facts a real records system needs and the reference types do not model. The proposed extensions are this book's suggestions for a future minor version of PHASE 1, not part of the current standard.

GapWhy it mattersInterim locationProposed extension
Software part numbersAn LRU's function depends on loaded DO-178C softwaremetadata.softwareParts[]Optional softwareParts array
Modification statusSB incorporation changes the unit without a new P/Nmetadata.hardwareModStatusOptional modStatus
Hours and cyclesLife limits and repeat inspections are counted in hours and cyclesmetadata.usageOptional usage object with an as-of date
Coded manufacturerFree-text names do not compare reliablymetadata.manufacturerCodeOptional manufacturerCode {scheme, value}
Approval without expiryexpiryDate is required but many approvals do not expiremetadata.approvalBasis[]New optional field beside Certification
Penetrant, functional testCommon inspections cannot be recordedfindings + metadataAdditional method values

For usage counters, spell field names out. The records abbreviations TSN, CSN and TSO (time since new, cycles since new, time since overhaul) collide: "TSO" is also the technical standard order. Every counter needs the date it was valid on, since a cycle count without an as-of date goes stale the day after it is written.

How the schema evolution rules apply

Annex E of the PHASE documents says additive changes (new optional fields, new error codes) are non-breaking, while renaming or removing a field "MUST trigger a minor version bump." Annex H adopts Semantic Versioning 2.0.0, in which a backwards-incompatible change is a major version. The two disagree on renames and removals. This book follows Annex H, the dedicated versioning policy, and treats them as major.

Under those rules most of the proposals above are minor-version changes: they add optional fields that old producers never send and old consumers can ignore. Two need care. New enum values are formally additive but break consumers that validate strictly against the old list, so they should ship with an announcement, and a tolerant consumer should flag an unknown value for review rather than reject the record. Making the existing expiryDate optional would break consumers that assume it exists, which is why the table proposes a separate field. Until anything is standardised, the metadata keys used here form an implementation profile to be declared in the profile manifest (Chapter 8), and each record carries the schema version it was written against (metadata.wiaSchemaVersion).

4.6 Validating with JSON Schema

The SDK package declares a dependency on the zod library, but its client code never calls it, and the CLI's validate and check commands currently print success without inspecting their input (Chapter 8). A deployment must supply its own validator. The schema below is derived from the reference types plus the constraints argued for in this chapter. It is this book's construction, offered as a starting point, not a schema published by the standard.

Schema excerpt

JSON Schema 2020-12 for AircraftComponent (excerpt; $id is a placeholder)
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:example:wia-space-016:aircraft-component:1.0.0",
  "title": "AircraftComponent",
  "type": "object",
  "required": ["id", "type", "status", "partNumber", "serialNumber",
               "manufacturer", "manufacturingDate", "dimensions",
               "material", "inspectionHistory"],
  "additionalProperties": false,
  "properties": {
    "id":                { "type": "string", "minLength": 1 },
    "type": { "enum": ["fuselage", "wing", "tail", "landing-gear",
                       "flight-control", "hydraulic-system", "fuel-system",
                       "avionics", "engine-mount"] },
    "status": { "enum": ["design", "testing", "certified",
                         "production", "maintenance", "retired"] },
    "partNumber":        { "type": "string", "pattern": "^\\S(.*\\S)?$" },
    "serialNumber":      { "type": "string", "pattern": "^\\S(.*\\S)?$" },
    "manufacturer":      { "type": "string", "minLength": 1 },
    "manufacturingDate": { "type": "string", "format": "date" },
    "dimensions":        { "$ref": "#/$defs/Dimensions" },
    "material":          { "$ref": "#/$defs/MaterialSpecification" },
    "structuralAnalysis":{ "$ref": "#/$defs/StructuralAnalysis" },
    "certification":     { "$ref": "#/$defs/Certification" },
    "inspectionHistory": { "type": "array", "items": { "$ref": "#/$defs/Inspection" } },
    "metadata":          { "type": "object" }
  },
  "$defs": {
    "Dimensions": {
      "type": "object",
      "required": ["length", "width", "height", "weight"],
      "additionalProperties": false,
      "properties": {
        "length": { "type": "number", "exclusiveMinimum": 0 },
        "width":  { "type": "number", "exclusiveMinimum": 0 },
        "height": { "type": "number", "exclusiveMinimum": 0 },
        "weight": { "type": "number", "exclusiveMinimum": 0 }
      }
    },
    "MaterialSpecification": {
      "type": "object",
      "required": ["type", "grade", "strength", "fatigueLimit",
                   "density", "corrosionResistance"],
      "additionalProperties": false,
      "properties": {
        "type": { "enum": ["aluminum-2024", "aluminum-7075", "titanium-ti6al4v",
                           "carbon-fiber", "fiberglass", "aramid", "composite"] },
        "grade":        { "type": "string", "minLength": 1 },
        "strength":     { "type": "number", "exclusiveMinimum": 0 },
        "fatigueLimit": { "type": "number", "minimum": 0 },
        "density": { "type": "number", "minimum": 500, "maximum": 20000,
                     "$comment": "kg/m3; bounds catch g/cm3 entries" },
        "corrosionResistance": { "enum": ["low", "medium", "high"] }
      }
    },
    "Inspection": {
      "type": "object",
      "required": ["id", "inspectionDate", "inspector", "method", "result"],
      "additionalProperties": false,
      "properties": {
        "id":             { "type": "string", "minLength": 1 },
        "inspectionDate": { "type": "string", "format": "date" },
        "inspector":      { "type": "string", "minLength": 1 },
        "method": { "enum": ["visual", "ultrasonic", "radiographic",
                             "magnetic-particle", "eddy-current"] },
        "result": { "enum": ["pass", "fail", "conditional"] },
        "findings":           { "type": "string" },
        "nextInspectionDate": { "type": "string", "format": "date" }
      },
      "if":   { "properties": { "result": { "const": "conditional" } } },
      "then": { "required": ["findings", "nextInspectionDate"] }
    }
  }
}

StructuralAnalysis and Certification follow the same pattern and are omitted for space. All their fields are required, and compliance is a boolean. Three design decisions deserve comment:

Running the schema: the format trap

In 2020-12, format is by default an annotation, not an assertion, so a validator may accept "15/03/2024" as a date unless format validation is switched on. With the Ajv library that means using its 2020-12 build and registering the formats package:

TypeScript: validating a record with Ajv (2020-12 build) and ajv-formats
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
import schema from "./aircraft-component.schema.json";

const ajv = new Ajv2020({ allErrors: true, strict: true });
addFormats(ajv);                 // without this, "format": "date" is not checked
const validate = ajv.compile(schema);

export function checkRecord(record: unknown): string[] {
  if (validate(record)) return [];
  return (validate.errors ?? []).map(
    (e) => `${e.instancePath || "/"} ${e.message ?? "invalid"}`
  );
}

A zod mirror for TypeScript code

Inside a TypeScript service it is convenient to validate with zod and derive static types from the same definition. The mirror below covers Inspection with the same conditional rule. Its date regular expression checks shape only, so a production mirror should also reject impossible dates such as 2024-02-30. Keeping the zod mirror and the JSON Schema in agreement is a testing task: run both against the same positive and negative examples in CI, as Chapter 8 describes for test vectors.

TypeScript (zod): Inspection mirror
import { z } from "zod";

const isoDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD");

export const Inspection = z.object({
  id: z.string().min(1),
  inspectionDate: isoDate,
  inspector: z.string().min(1),
  method: z.enum(["visual", "ultrasonic", "radiographic",
                  "magnetic-particle", "eddy-current"]),
  result: z.enum(["pass", "fail", "conditional"]),
  findings: z.string().optional(),
  nextInspectionDate: isoDate.optional(),
}).strict().superRefine((v, ctx) => {
  if (v.result === "conditional" && (!v.findings || !v.nextInspectionDate)) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: "conditional result needs findings and nextInspectionDate",
    });
  }
});

export type Inspection = z.infer<typeof Inspection>;

Negative examples

A schema is only as good as the wrong inputs it has been shown to reject. Each case below is a small mutation of the valid record in Section 4.3 and must fail. A test that checks the reported keyword, not merely "invalid", catches records that fail for the wrong reason.

Mutation of the valid recordExpected failing keywordReal-world cause
serialNumber removedrequiredSerial not captured at receiving
serialNo instead of serialNumberadditionalProperties, requiredField-name drift between systems
"type": "avionic"enumHand-typed or legacy classification
"manufacturingDate": "15/03/2024"format (only with format assertion)Locale-formatted spreadsheet dates
"density": 2.78minimumg/cm³ entered as kg/m³
"weight": -3.2exclusiveMinimumSign error in a conversion script
Inspection "method": "penetrant"enumCorrect failure under 1.0 that signals the missing enum value
"result": "conditional" without nextInspectionDaterequired (in then)Open finding with no follow-up
"partNumber": "EXV-2100-01 "patternTrailing space from an export

What validation does not prove

A record that passes this schema is well-formed. That does not make it true, and it does not make the component airworthy. The schema cannot know whether serial VX21-004517 was really produced under the approval claimed, whether its release certificate exists, or whether the listed software is what is loaded in the box. Those questions belong to the traceability and certification operations of the API (Chapter 5), the release and maintenance flows between supplier, MRO, operator and authority (Chapter 6), and the signed evidence packages of the quality system (Chapter 7). PHASE 1 makes those processes possible by ensuring every party talks about the same unit, in the same units, with the same field names. A schema is the cheapest place to enforce that agreement and the first test a new implementation should pass.