Skip to content

Phase 3, Task 12: SWE Common DataRecord Parser #25

@Sam-Bolling

Description

@Sam-Bolling

Task

Create the SWE Common DataRecord parser (data-record.ts) that parses DataRecord structures with named fields containing any SWE Common DataComponent, supporting flat records, nested records, and field ordering preservation.

ROADMAP Reference: Phase 3, Task 12 — SWE Common DataRecord Parser (~2-3 hours, Medium-High complexity)


Files to Create or Modify

File Action Est. Lines Purpose
src/ogc-api/csapi/formats/swecommon/data-record.ts Create ~150-200 DataRecord parser with field parsing and nested record support
src/ogc-api/csapi/formats/swecommon/data-record.spec.ts Create ~100-150 DataRecord parser tests — flat, nested, field ordering, error handling

Blueprint Reference

Follow the EDR pattern in src/ogc-api/edr/model.ts (126 lines) for file structure and src/ogc-api/edr/model.spec.ts (42 lines) for test patterns.

Scope — What to Implement

DataRecord Parser

parseDataRecord(json: unknown): DataRecord

Parse a SWE Common 3.0 DataRecord structure. A DataRecord is an implementation of the ISO-11404 Record datatype that groups a sequence of named data components (fields). Each field has a required name and contains any SWE Common DataComponent — including other DataRecords (recursive nesting).

Properties to parse:

  • type: 'DataRecord' — discriminator (required, must be 'DataRecord')
  • id?: string — optional referenceable identifier
  • label?: string — human-readable label (from AbstractSweIdentifiable)
  • description?: string — human-readable description (from AbstractSweIdentifiable)
  • definition?: string — URI semantic link defining what this record represents
  • updatable?: boolean — whether value can be updated externally (default: false)
  • optional?: boolean — whether data can be omitted in datastream (default: false)
  • fields: DataField[] — required array of named fields (minItems: 1)

DataField structure (per OGC spec):

Each field item is a SoftNamedProperty (with required name) combined with either an inline DataComponent or a link reference:

  • name: string — required field name, must match pattern ^[A-Za-z][A-Za-z0-9_\-]*$
  • The field value is one of:
    • An inline SWE DataComponent (any type from the AnyComponent union — simple types, DataRecord, DataArray, Vector, Matrix, DataChoice, GeometryData)
    • A link reference (href, role, arcrole, title)

Parsing responsibilities:

  1. Validate type === 'DataRecord'
  2. Validate fields is a non-empty array
  3. For each field:
    • Extract the name property
    • Determine if the field value is an inline component or a link
    • For inline components: delegate to the appropriate component parser (simple components from Issue Phase 3, Task 11: SWE Common Simple Components Parser #24, or recursively call parseDataRecord for nested records)
    • For links: preserve the link reference structure
  4. Preserve field ordering (the spec says "sequence of data components" — order matters)
  5. Parse the shared AbstractSweIdentifiable properties (id, label, description)
  6. Parse the AbstractDataComponent properties (definition, updatable, optional)

Recursive Nesting

DataRecords can be nested — a field's component can itself be a DataRecord. The parser must handle this recursively. Example:

{
  "type": "DataRecord",
  "fields": [
    {
      "name": "location",
      "type": "DataRecord",
      "fields": [
        { "name": "lat", "type": "Quantity", "uom": {"code": "deg"}, "value": 45.0 },
        { "name": "lon", "type": "Quantity", "uom": {"code": "deg"}, "value": -73.0 }
      ]
    },
    { "name": "temperature", "type": "Quantity", "uom": {"code": "Cel"}, "value": 23.5 }
  ]
}

The parser should handle reasonable nesting depth (at least 3 levels per testing requirements).

Error Handling

  • Missing type or type !== 'DataRecord' → error
  • Missing or empty fields array → error (spec requires minItems: 1)
  • Field missing name → error
  • Field name not matching pattern ^[A-Za-z][A-Za-z0-9_\-]*$ → warning or error
  • Unknown component type in field → error with field name context
  • Provide meaningful error messages indicating which field caused the issue

JSDoc Requirements

  • Document parseDataRecord with @param, @returns, and usage example showing nested records
  • Add @see link to OGC SWE Common 3.0 (24-014) DataRecord section
  • Document the recursive nesting behavior
  • Follow the JSDoc style in src/ogc-api/edr/model.ts

Testing Requirements

  • Create src/ogc-api/csapi/formats/swecommon/data-record.spec.ts (~100-150 lines)
  • Flat record tests:
    • Record with simple scalar fields (Quantity, Text, Boolean)
    • Record with mixed field types
    • Field ordering preserved in output
  • Nested record tests:
    • Record with nested DataRecord field
    • 2-3 levels deep nesting
    • Record with nested DataArray field (if DataArray parser available)
  • Field validation tests:
    • Missing field name → error
    • Empty fields array → error
    • Field with link reference → handled correctly
  • Error handling tests:
    • Invalid type → error
    • Null/undefined input → error
    • Non-object input → error
  • Follow test patterns from src/ogc-api/edr/model.spec.ts

Scope — What NOT to Touch

Acceptance Criteria

  • data-record.ts exists with parseDataRecord() function
  • Parses fields array with name extraction and component delegation
  • Handles recursive nesting (DataRecord fields containing DataRecords)
  • Preserves field ordering
  • Handles link references in fields (not just inline components)
  • Validates required fields property (non-empty array)
  • Validates field name presence
  • All new code has complete JSDoc documentation with @see spec references
  • data-record.spec.ts exists with tests for flat records, nested records, field ordering, and error handling
  • Existing tests still pass (npm test)
  • No lint errors

Dependencies

Blocked by: Issue #17 — SWE Common Types (must have DataRecord, DataField, SWEDataComponent interfaces), Issue #24 — SWE Common Simple Components Parser (must have simple component parsers for field value delegation)
Blocks: Issue #27 — SWE Common Main Parser (imports parseDataRecord for component type discrimination)


Operational Constraints

⚠️ MANDATORY: Before starting work on this issue, review docs/governance/AI_OPERATIONAL_CONSTRAINTS.md.

Key constraints for this task:

  • Precedence: OGC specifications → AI Collaboration Agreement → This issue description → Existing code → Conversational context
  • No scope expansion: Do not infer unstated requirements or add unrequested features
  • No refactoring: Do not rename, restructure, or "improve" code outside this issue's scope
  • Minimal diffs: Prefer the smallest change that satisfies the acceptance criteria
  • Ask when unclear: If intent is ambiguous, stop and ask for clarification

References

Read these documents before starting implementation. They are ordered by priority.

Primary References (must read)

# Document Section/Lines What It Provides
1 docs/planning/csapi-implementation-guide.md Lines 3043-3130 (SWE Common Handler) Full specification of SWE Common data components including DataRecord description
2 docs/planning/csapi-implementation-guide.md Lines 2098-2120 (File Structure) File organization showing data-record.ts (~150-200 lines)
3 docs/planning/csapi-implementation-guide.md Lines 2823-2838 (SWE Common Types) DataRecord and DataField interface definitions, SWEDataComponent union type
4 src/ogc-api/edr/model.ts Full file (126 lines) Blueprint — file structure, JSDoc style, export conventions
5 src/ogc-api/edr/model.spec.ts Full file (42 lines) Blueprint — test structure and patterns

Upstream Type/Import References (files this task imports from)

# Document What to Import
1 src/ogc-api/csapi/formats/swecommon/types.ts DataRecord, DataField, SWEDataComponent and all component interfaces
2 src/ogc-api/csapi/formats/swecommon/components.ts parseSimpleComponent for delegating field value parsing of simple types

Research References (context, not required reading)

# Document What It Provides
1 docs/research/requirements/csapi-datatype-schema-requirements.md Complete analysis of SWE Common data types including DataRecord
2 docs/research/testing/findings/04-implementation-guide-testing-requirements.md Testing requirements and fixture definitions

Specification References (for @see links and field accuracy)

# Document Use
1 OGC SWE Common 3.0 (24-014) Normative specification for DataRecord structure, field definitions, ISO-11404 Record datatype
2 OGC API - Connected Systems Part 2 (23-002) DataRecord usage in DataStream result schemas
3 docs/research/standards/ogcapi-connectedsystems-2.bundled.oas31.yaml OpenAPI schema — DataRecord (L7593), field structure (L531-L544 showing fields array, name pattern, SoftNamedProperty), AnyComponent (L7608)

Convention Quick Reference

Rule Example
Use .js extension for relative imports import { X } from './file.js'
Use import type for interfaces/types import type { Y } from './model.js'
Three-tier hierarchy: import from lower tiers only shared → ogc-api → csapi
Named exports for types and utilities export interface Z { ... }
as const arrays for enum-like values export const XTypes = [...] as const
HTTP mocking: globalThis.fetch = jest.fn() Never use nock, msw, or other libraries
Meaningful tests only Verify behavior, not that code runs without throwing

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions