Skip to content

Part 1 (GeoJSON) TypeScript interfaces omit all @link association properties #108

@Sam-Bolling

Description

@Sam-Bolling

Task

Add optional @link-derived fields and a shared CSAPIResourceRef type to the Part 1 GeoJSON interfaces (System, Deployment, SamplingFeature) in model.ts so consumers have typed access to structural associations defined by OGC 23-001 §16.

Finding Reference: Gap 1 from CS API @link Property Gap Analysis
Severity: Moderate
Category: Design gap
Ownership: Ours


Problem Statement

The OGC CS API JSON encoding (OGC 23-001 §16) defines inline @link properties on Part 1 GeoJSON resources to encode structural associations between resources:

System ──systemKind@link──→ Procedure
Deployment ──platform@link──→ System (platform)
Deployment ──deployedSystems@link──→ [System, System, ...]
SamplingFeature ──sampledFeature@link──→ Feature

The four Part 1 GeoJSON resource interfaces in model.ts do not include any @link fields. After extractCSAPIFeature() parses server JSON, all @link data is silently discarded because:

  1. The TypeScript interfaces have no @link fields to define the shape
  2. The parser uses an allowlist extraction pattern — only named interface properties survive

Evidence:

The SamplingFeature JSDoc (model.ts L412) explicitly states:

"The sampledFeature@link link relation is also required."

…but the interface below it omits the field entirely.

Server JSON that gets lost:

{
  "id": "of45kp7s5ims",
  "type": "Feature",
  "properties": {
    "featureType": "http://www.w3.org/ns/sosa/Platform",
    "uid": "urn:osh:sensor:odas:buoy:46042",
    "name": "ODAS Station 46042 — Monterey",
    "systemKind@link": {
      "href": "http://45.55.99.236:8080/sensorhub/api/procedures/of45l6iqgims",
      "uid": "urn:osh:sensor:odas:procedure:buoy-platform",
      "rt": "http://www.w3.org/ns/sosa/Procedure",
      "title": "ODAS Standard Buoy Platform"
    }
  }
}

After parsing, systemKind@link is gone. The parsed System object provides no path to the procedure it implements.

Impact: Consumers cannot type-safely read @link fields from parsed resources. The ogc-csapi-explorer demo app had to implement a tryLinkFallback() workaround (commit ad06b52) that bypasses the library's typed models and reads @link fields from raw JSON.

Findings Report

📋 Issue #108 Findings Report — Part 1 (GeoJSON) TypeScript Interfaces Omit All @link Association Properties

Files to Create or Modify

File Action Est. Lines Purpose
src/ogc-api/csapi/model.ts Modify ~+12 Add CSAPIResourceRef interface + optional @link-derived fields to 3 interfaces
src/index.ts Modify ~+1 Export CSAPIResourceRef type

Proposed Fix

Add a shared CSAPIResourceRef type and optional @link-derived fields to 3 Part 1 interfaces:

New Type

/** Parsed form of a CS API `@link` inline property. */
export interface CSAPIResourceRef {
  /** URL of the referenced resource. */
  href: string;
  /** Globally unique identifier of the referenced resource. */
  uid?: string;
  /** Human-readable title. */
  title?: string;
  /** Resource type URI. */
  rt?: string;
}

Interface Changes

Interface New Field Type Spec Reference
System systemKindLink? CSAPIResourceRef OGC 23-001 §8.3 Table 8
Deployment platformLink? CSAPIResourceRef OGC 23-001 §8.5 Table 10
Deployment deployedSystemsLink? CSAPIResourceRef[] OGC 23-001 §8.5 Table 10
SamplingFeature sampledFeatureLink? CSAPIResourceRef OGC 23-001 §8.9 Table 14

Design notes:

  • All fields are optional (?) — servers aren't required to include @link properties in every response context
  • camelCase naming without @ sigil (e.g., systemKindLink not systemKind@link) for TypeScript ergonomics
  • deployedSystemsLink is CSAPIResourceRef[] (array) because deployments can have multiple systems
  • Procedure has no spec-defined @link properties — no change needed
  • Parser changes to populate these fields are tracked separately in Part 1 extractCSAPIFeature() silently drops all @link properties during parsing #109

Scope — What NOT to Touch

Acceptance Criteria

  • CSAPIResourceRef interface exists in model.ts with href, uid?, title?, rt? fields
  • System.properties includes optional systemKindLink?: CSAPIResourceRef
  • Deployment.properties includes optional platformLink?: CSAPIResourceRef and deployedSystemsLink?: CSAPIResourceRef[]
  • SamplingFeature.properties includes optional sampledFeatureLink?: CSAPIResourceRef
  • CSAPIResourceRef is exported from src/index.ts
  • All new fields have JSDoc documentation with @see links to OGC spec sections
  • Existing tests still pass (npm test)
  • No TypeScript errors
  • No lint errors

Dependencies

Blocked by: Nothing
Blocks: #109 — Part 1 extractCSAPIFeature() parser must extract @link properties (needs interface fields first)


Operational Constraints

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

Key constraints:

  • Precedence: OGC specifications → AI Collaboration Agreement → This issue description → Existing code → Conversational context
  • No scope expansion: Add the interface fields, nothing more
  • Minimal diffs: Prefer the smallest change that satisfies the acceptance criteria
  • No refactoring: Do not rename, restructure, or "improve" code outside this issue's scope

References

# Document What It Provides
1 Issue #108 Findings Report Full source code review, risk assessment, and recommendation
2 CS API @link Property Gap Analysis Full audit of all @link gaps across the library
3 AI Operational Constraints Mandatory operational behavior for AI collaboration
4 Issue #103 — Part 2 cross-reference fields Precedent: Part 2 @id fields (same pattern, already resolved)
5 ogc-csapi-explorer tryLinkFallback() (ad06b52) Real-world workaround demonstrating the gap
6 src/ogc-api/csapi/model.ts Source file to modify
7 src/index.ts Public exports file

Specification References

# Document Use
1 OGC 23-001 §8.3 (Table 8) System resource model — procedure association (Conditional)
2 OGC 23-001 §8.5 (Table 10) Deployment resource model — platform (Optional), deployedSystems (Required)
3 OGC 23-001 §8.9 (Table 14) SamplingFeature resource model — sampledFeature (Required)
4 OGC 23-001 §16 JSON encoding for Part 1 GeoJSON resources — @link inline property convention

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions