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:
Validate type === 'DataRecord'
Validate fields is a non-empty array
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
Preserve field ordering (the spec says "sequence of data components" — order matters)
Parse the shared AbstractSweIdentifiable properties (id, label, description)
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
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
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
src/ogc-api/csapi/formats/swecommon/data-record.tssrc/ogc-api/csapi/formats/swecommon/data-record.spec.tsBlueprint Reference
Follow the EDR pattern in
src/ogc-api/edr/model.ts(126 lines) for file structure andsrc/ogc-api/edr/model.spec.ts(42 lines) for test patterns.Scope — What to Implement
DataRecord Parser
parseDataRecord(json: unknown): DataRecordParse 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
nameand contains any SWE Common DataComponent — including other DataRecords (recursive nesting).Properties to parse:
type: 'DataRecord'— discriminator (required, must be'DataRecord')id?: string— optional referenceable identifierlabel?: string— human-readable label (from AbstractSweIdentifiable)description?: string— human-readable description (from AbstractSweIdentifiable)definition?: string— URI semantic link defining what this record representsupdatable?: 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 requiredname) 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_\-]*$AnyComponentunion — simple types, DataRecord, DataArray, Vector, Matrix, DataChoice, GeometryData)href,role,arcrole,title)Parsing responsibilities:
type === 'DataRecord'fieldsis a non-empty arraynamepropertyparseDataRecordfor nested records)AbstractSweIdentifiableproperties (id,label,description)AbstractDataComponentproperties (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
typeortype !== 'DataRecord'→ errorfieldsarray → error (spec requiresminItems: 1)name→ errornamenot matching pattern^[A-Za-z][A-Za-z0-9_\-]*$→ warning or errorJSDoc Requirements
parseDataRecordwith@param,@returns, and usage example showing nested records@seelink to OGC SWE Common 3.0 (24-014) DataRecord sectionsrc/ogc-api/edr/model.tsTesting Requirements
src/ogc-api/csapi/formats/swecommon/data-record.spec.ts(~100-150 lines)src/ogc-api/edr/model.spec.tsScope — What NOT to Touch
types.ts— that belongs to Issue Phase 3.4: SWE Common Types #17 (SWE Common Types)components.ts— that belongs to Issue Phase 3, Task 11: SWE Common Simple Components Parser #24 (SWE Common Simple Components Parser)data-array.ts— that belongs to Issue Phase 3, Task 13: SWE Common DataArray Parser #26 (SWE Common DataArray Parser)parser.ts— that belongs to Issue Phase 3, Task 14: SWE Common Main Parser #27 (SWE Common Main Parser)index.ts— that belongs to Issue Phase 3, Task 15: SWE Common Index #28 (SWE Common Index)Acceptance Criteria
data-record.tsexists withparseDataRecord()functionfieldsarray withnameextraction and component delegationfieldsproperty (non-empty array)namepresence@seespec referencesdata-record.spec.tsexists with tests for flat records, nested records, field ordering, and error handlingnpm test)Dependencies
Blocked by: Issue #17 — SWE Common Types (must have
DataRecord,DataField,SWEDataComponentinterfaces), Issue #24 — SWE Common Simple Components Parser (must have simple component parsers for field value delegation)Blocks: Issue #27 — SWE Common Main Parser (imports
parseDataRecordfor component type discrimination)Operational Constraints
Key constraints for this task:
References
Read these documents before starting implementation. They are ordered by priority.
Primary References (must read)
docs/planning/csapi-implementation-guide.mddocs/planning/csapi-implementation-guide.mddata-record.ts(~150-200 lines)docs/planning/csapi-implementation-guide.mdDataRecordandDataFieldinterface definitions,SWEDataComponentunion typesrc/ogc-api/edr/model.tssrc/ogc-api/edr/model.spec.tsUpstream Type/Import References (files this task imports from)
src/ogc-api/csapi/formats/swecommon/types.tsDataRecord,DataField,SWEDataComponentand all component interfacessrc/ogc-api/csapi/formats/swecommon/components.tsparseSimpleComponentfor delegating field value parsing of simple typesResearch References (context, not required reading)
docs/research/requirements/csapi-datatype-schema-requirements.mddocs/research/testing/findings/04-implementation-guide-testing-requirements.mdSpecification References (for
@seelinks and field accuracy)docs/research/standards/ogcapi-connectedsystems-2.bundled.oas31.yamlDataRecord(L7593), field structure (L531-L544 showingfieldsarray,namepattern,SoftNamedProperty),AnyComponent(L7608)Convention Quick Reference
.jsextension for relative importsimport { X } from './file.js'import typefor interfaces/typesimport type { Y } from './model.js'export interface Z { ... }as constarrays for enum-like valuesexport const XTypes = [...] as constglobalThis.fetch = jest.fn()