Skip to content

Phase 3, Task 11: SWE Common Simple Components Parser #24

@Sam-Bolling

Description

@Sam-Bolling

Task

Create parsers for all SWE Common 3.0 simple component types in components.ts, covering the 6 scalar components (Quantity, Count, Text, Boolean, Time, Category) and the 4 range components (QuantityRange, CountRange, TimeRange, CategoryRange), with UOM parsing, constraint handling, NilValues support, and quality indicators.

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


Files to Create or Modify

File Action Est. Lines Purpose
src/ogc-api/csapi/formats/swecommon/components.ts Create ~300-400 Parsers for all 10 simple component types (6 scalar + 4 range)
src/ogc-api/csapi/formats/swecommon/components.spec.ts Create ~200-300 Component parser tests — each type, constraints, UOM, NilValues

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

Scalar Component Parsers

Each parser takes a raw JSON object and returns a typed interface value. All scalar components extend AbstractSimpleComponent which provides shared optional properties: id, label, description, definition (URI), nilValues, quality.

parseQuantity(json: unknown): Quantity

  • Parse: type: 'Quantity', uom (UnitOfMeasure — code and/or href), value (number), constraint (AllowedValues), quality (Quality[]), nilValues (NilValues[])
  • Validate: uom should be present (UCUM code like "Cel", "m/s", "%")
  • OGC spec description: "Scalar component with decimal representation and a unit of measure used to store value of a continuous quantity"

parseCount(json: unknown): Count

  • Parse: type: 'Count', value (integer), constraint (AllowedValues), quality, nilValues
  • No uom — counts are dimensionless integers
  • OGC spec description: "Scalar component with integer representation used for a discrete counting value"

parseBoolean(json: unknown): Boolean

  • Parse: type: 'Boolean', value (boolean)
  • Simplest scalar component — no constraints, no UOM
  • OGC spec description: "Scalar component used to express truth: True or False, 0 or 1"

parseText(json: unknown): Text

  • Parse: type: 'Text', value (string), constraint (AllowedTokens — enumeration list or regex pattern)
  • OGC spec description: "Free text component used to store comments or any other type of textual statement"

parseTime(json: unknown): Time

  • Parse: type: 'Time', value (ISO 8601 string or number), uom (UnitOfMeasure), constraint (AllowedTimes — time range or enumerated times), referenceFrame (temporal CRS URI), referenceTime (ISO 8601 epoch)
  • OGC spec description: "Scalar component used to represent a time quantity either as ISO 8601 (e.g., 2004-04-18T12:03:04.6Z) or as a duration relative to a time of reference"

parseCategory(json: unknown): Category

  • Parse: type: 'Category', value (string token), constraint (AllowedTokens), codeSpace (URI to controlled vocabulary)
  • OGC spec description: "Scalar component used to represent a categorical value as a simple token identifying a term in a code space"

Range Component Parsers

Range components represent pairs of values (min/max). Each extends the corresponding scalar type's constraint structure.

parseQuantityRange(json: unknown): QuantityRange

  • Parse: type: 'QuantityRange', uom (UnitOfMeasure), value ([number, number] pair), constraint (AllowedValues)
  • OGC spec description: "Decimal pair for specifying a quantity range with a unit of measure"

parseCountRange(json: unknown): CountRange

  • Parse: type: 'CountRange', value ([integer, integer] pair), constraint (AllowedValues)
  • OGC spec description: "Integer pair used for specifying a count range"

parseTimeRange(json: unknown): TimeRange

  • Parse: type: 'TimeRange', value ([string, string] ISO 8601 pair), uom, constraint (AllowedTimes), referenceFrame, referenceTime
  • OGC spec description: "Time value pair for specifying a time range (can be a decimal or ISO 8601)"

parseCategoryRange(json: unknown): CategoryRange

  • Parse: type: 'CategoryRange', value ([string, string] token pair), constraint (AllowedTokens), codeSpace
  • OGC spec description: "Pair of categorical values used to specify a range in an ordinal reference system (specified by the code space)"

Shared Helpers

parseUnitOfMeasure(json: unknown): UnitOfMeasure

  • Parse code (UCUM code string) and/or href (URI to unit definition)
  • Used by Quantity, QuantityRange, Time, TimeRange

parseAllowedValues(json: unknown): AllowedValues

  • Parse enumerated values list and/or intervals (inclusive ranges)
  • Used by Quantity, Count, QuantityRange, CountRange

parseAllowedTokens(json: unknown): AllowedTokens

  • Parse enumerated values list or pattern (regex)
  • Used by Text, Category, CategoryRange

parseAllowedTimes(json: unknown): AllowedTimes

  • Parse time ranges or enumerated time values
  • Used by Time, TimeRange

parseNilValues(json: unknown): NilValues[]

  • Parse missing/invalid data representation with reason codes
  • Used by all scalar and range components

parseQuality(json: unknown): Quality[]

  • Parse quality indicators (accuracy, precision, confidence)
  • Used by all scalar and range components

Discriminator Function

parseSimpleComponent(json: unknown): AnySimpleComponent

  • Read the type field and dispatch to the correct parser
  • This is called by the main SWE Common parser (Issue Phase 3, Task 14: SWE Common Main Parser #27) for component type discrimination
  • Return type is the AnySimpleComponent union of all 10 simple types

JSDoc Requirements

  • Document each parser function with @param, @returns, and a usage example
  • Add @see links to OGC SWE Common 3.0 (24-014) for each component type
  • Document UOM as UCUM codes with reference to UCUM
  • Follow the JSDoc style in src/ogc-api/edr/model.ts

Testing Requirements

  • Create src/ogc-api/csapi/formats/swecommon/components.spec.ts (~200-300 lines)
  • Scalar component tests (one describe block per type):
    • Quantity: parse with UOM, value, constraints, NilValues
    • Count: parse integer value with constraints
    • Boolean: parse true/false values
    • Text: parse string value with AllowedTokens constraint
    • Time: parse ISO 8601 value with referenceFrame
    • Category: parse token value with codeSpace
  • Range component tests:
    • QuantityRange: parse value pair with UOM
    • CountRange: parse integer pair
    • TimeRange: parse ISO 8601 pair
    • CategoryRange: parse token pair with codeSpace
  • Constraint tests:
    • AllowedValues with enumerated list
    • AllowedValues with intervals
    • AllowedTokens with pattern
    • AllowedTimes with time range
  • UOM handling tests:
    • UCUM code parsing ("Cel", "m/s", "%")
    • href URI parsing
    • Missing UOM on Quantity → error or default handling
  • NilValues tests:
    • NilValues with reason code
    • Multiple NilValues entries
  • Error handling:
    • Unknown component type → error
    • Missing required fields → meaningful error
  • Follow test patterns from src/ogc-api/edr/model.spec.ts

Scope — What NOT to Touch

Acceptance Criteria

  • components.ts exists with individual parse functions for all 6 scalar types (Quantity, Count, Boolean, Text, Time, Category)
  • components.ts includes individual parse functions for all 4 range types (QuantityRange, CountRange, TimeRange, CategoryRange)
  • parseSimpleComponent discriminator function dispatches by type field to the correct parser
  • UOM parsing handles both code (UCUM) and href (URI) formats
  • Constraint parsing covers AllowedValues, AllowedTokens, and AllowedTimes
  • NilValues and Quality indicator parsing implemented
  • All new code has complete JSDoc documentation with @see spec references
  • components.spec.ts exists with tests for each component type, constraints, UOM, and error handling
  • Existing tests still pass (npm test)
  • No lint errors

Dependencies

Blocked by: Issue #17 — SWE Common Types (must have interfaces to return)
Blocks: Issue #27 — SWE Common Main Parser (imports parseSimpleComponent for 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 components, encodings, constraints, NilValues, quality
2 docs/planning/csapi-implementation-guide.md Lines 2098-2120 (File Structure) File organization showing components.ts (~300-400 lines)
3 docs/planning/csapi-implementation-guide.md Lines 2790-2900 (SWE Common Types) Type definitions template — SWEDataComponent union, Quantity interface, UnitOfMeasure, AllowedValues, encodings
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 Quantity, Count, Boolean, Text, Time, Category, QuantityRange, CountRange, TimeRange, CategoryRange, AnySimpleComponent, UnitOfMeasure, AllowedValues, AllowedTokens, AllowedTimes, NilValues, Quality

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
2 docs/research/testing/findings/04-implementation-guide-testing-requirements.md Testing coverage requirements for SWE Common parsers

Specification References (for @see links and field accuracy)

# Document Use
1 OGC SWE Common 3.0 (24-014) Normative specification for all component types, constraints, NilValues, quality
2 OGC API - Connected Systems Part 2 (23-002) Requirements for SWE Common in DataStreams/Observations
3 docs/research/standards/ogcapi-connectedsystems-2.bundled.oas31.yaml OpenAPI schema — Quantity (L7530), Count (L7516), Boolean (L7500), Text (L7564), Time (L7546), Category (L7559), QuantityRange (L7576), CountRange (L7571), TimeRange (L7581), CategoryRange (L7586), AnySimpleComponent (L7591), AllowedValues (L7510), AllowedTokens (L7555), AllowedTimes (L7543)
4 UCUM Codes Unit of measure code system for UOM validation

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions