id: TEDY.03
template: tool-feature
module: tedy
state: Proposed
traces-from: []
source-refs:
reference-editor/app/src/app/resources/map-set
reference-editor/app/src/app/resources/_lib/map-set/model/map-set.ts
reference-editor/app/src/app/resources/_lib/map-set/model/map-set-version.ts # scope + statistics
reference-editor/app/src/app/resources/_lib/map-set/model/map-set-association.ts
reference-editor/app/src/app/resources/_lib/map-set/model/map-set-concept.ts
reference-editor/app/src/app/resources/_lib/map-set/services/map-set-lib.service.ts # GET /ts/map-sets*
reference-editor/app/src/app/resources/map-set/services/map-set-service.ts # write /ts/map-sets*
terminology-server (/ts/map-sets, /ts/map-set-versions, /file-importer/map-set)
author: TEDY bootstrap
created: 2026-08-08
updated: 2026-08-08
Common specification for Map Set management in TEDY — browse, view, and author FHIR ConceptMaps over terminology-server (/ts/map-sets). A Map Set relates concepts from a source to a target (each a code system or value set, its scope ) through associations (individual mappings with a relationship ). This root spec owns the shared vocabulary, data + scope/association model, FHIR mapping, privileges, the full REST surface, and navigation so the child (screen) specs don’t duplicate them.
terminology-server owns persistence + the ConceptMap model + automap engine; TEDY is the React client. Derived via spec-authoring.md ; the REST surface below was read from reference-editor’s map-set services and confirmed live on dev-tx.example (guest yupi).
Child specs:
Term (canonical) Meaning
Map Set A FHIR ConceptMap — a set of mappings from source concepts to target concepts.
Version A MapSetVersion with a publication status + release date; carries the scope + statistics .
Scope MapSetVersion.scope — the source and target: sourceType/targetType (code-system/value-set/external-canonical-uri) + the referenced systems/value sets.
Association MapSetAssociation — one mapping: source {code, codeSystem, display} → target {…}, a relationship, verified, noMap.
Relationship The map relationship (equivalent / source-is-narrower-than-target / source-is-broader-than-target / related-to / not-related-to).
No-map An association marking that a source has no target mapping (noMap: true).
Verified Whether an association has been human-verified (verified).
Statistics MapSetVersion.statistics — counts: sourceConcepts, equivalent, noMap, narrower, broader, unmapped, inactiveSources/Targets.
Automap A background job that proposes associations by matching code / designation (.../associations/automap).
Map Set concept MapSetConcept — a source concept + its associations (the source-centric view).
Property MapSetProperty — a defined property attached to associations.
flowchart LR
US["(TODO) US: manage map sets"] --> ROOT[TEDY.03]
ROOT --> LST[TEDY.03.1 List]
ROOT --> CRT[TEDY.03.2 Add]
ROOT --> VIEW[TEDY.03.3 View]
LST -->|Add map set| CRT
LST -->|row / ID| VIEW
CRT -->|save| VIEW
VIEW --> ASSOC[Associations grid]
ASSOC -->|automap / verify / unmap| ASSOC
Entity / Resource the reference platform API FHIR Notes
MapSet /ts/map-setsConceptMap list + detail; versions decorated
MapSetVersion /ts/map-sets/{id}/versionsConceptMap.version status ∈ draft/active/retired; carries scope + statistics
MapSetScope (embedded in version) ConceptMap.group.source/target source/target type + system/value-set refs
MapSetAssociation /ts/map-sets/{id}/associationsConceptMap.group.element.target source → target + relationship + verified + noMap
MapSetConcept .../versions/{v}/conceptsConceptMap.group.element source concept + its associations
MapSetStatistics version.statisticsn/a mapping counts
MapSetProperty (embedded in map set) ConceptMap.property defined properties on associations
Field Type Rule
idstring identity; renamed via change-id
uristring canonical URL
name / titlestring / LocalizedName
description / purposeLocalizedName
publisherstring publisher VS or free text
narrativestring HTML (FHIR text)
experimentalboolean
otherTitle / topic / useContext / sourceReference… as ValueSet
identifiersIdentifier[]
contactsContactDetail[]
copyright / settingsobjects settings.{reviewRequired,approvalRequired}
versionsMapSetVersion[] version + status + scope + statistics
propertiesMapSetProperty[]
id, version, status, mapSet, releaseDate/expirationDate (YYYY-MM-DD), preferredLanguage, description, algorithm, identifiers, scope (MapSetScope), statistics (MapSetStatistics).
MapSetVersion.scope # MapSetScope
├── sourceType # 'code-system' | 'value-set' | 'external-canonical-uri'
├── sourceValueSet | sourceCodeSystems[] # MapSetResourceReference {id, version, uri}
├── targetType
└── targetValueSet | targetCodeSystems[]
MapSetAssociation
├── source: {code, codeSystem, display} # MapSetAssociationEntity
├── target: {code, codeSystem, display}
├── relationship # concept-map-relationship code
├── verified # human-verified
├── noMap # source has no target
└── propertyValues[]
Field ValueSet Canonical URL
publisherpublisher https://tx.example/fhir/ValueSet/publisher
version status publication-status http://hl7.org/fhir/ValueSet/publication-status
supported/preferred language languages http://hl7.org/fhir/ValueSet/languages
association relationship concept-map-relationship http://hl7.org/fhir/ValueSet/concept-map-relationship
Internal FHIR R5 ConceptMap path
id/uri/name/title/publisherConceptMap.id/.url/.name/.title/.publisher
version scope.sourceCodeSystems/sourceValueSet ConceptMap.group.source / .sourceScope
version scope.targetCodeSystems/targetValueSet ConceptMap.group.target / .targetScope
association source group.element (code + display)
association target + relationship group.element.target (code + relationship)
association noMap group.element.noMap
Associations (the mappings) are the content; read them source-centric via .../versions/{v}/concepts (MapSetConcept + its associations) or flat via .../associations.
Version lifecycle mirrors the other resources: draft → active → retire (dedicated endpoints, empty body, 204); editing an active version is frozen server-side.
Batch association ops: associations-batch (bulk upsert), verify (verify/unverify sets), unmap (mark no-map), automap (background job → JobLogResponse).
Statistics are (re)computed server-side; reload-statistics-async refreshes them.
publisher / status / language / relationship selects use TxConceptSelect(url=…).
Action Privilege
View / browse authenticated (dev: guest via the reference platform yupi)
Create / edit / delete / versions / associations MapSet.write (the reference platform {id}.MapSet.write)
Base /ts/map-sets unless noted. All TEDY calls go through @helex/tedy’s txApi (/txapi → dev-tx.example /api).
Method Path Priv Description
GET /ts/map-setsread list — params below
GET /ts/map-sets/{id}?decorate={bool}read load one (decorate embeds versions + scope + statistics)
POST /ts/map-sets/transactionwrite create/update — MapSetTransactionRequest {mapSet, version?, properties?, associations?}
POST /ts/map-sets/{id}/change-idwrite rename id — {id: newId}
DELETE /ts/map-sets/{id}write delete map set
GET /ts/map-sets/{id}/provenances?version=read provenance
List params (MapSetSearchParams): id, ids, idContains, uri, uriContains, name, nameContains, description, descriptionContains, text, textContains, publisher, versionVersion, versionStatus, versionSource, versionsDecorated, lang, spaceId, packageId, packageVersionId, plus association filters (associationSourceCode, associationSourceSystem, associationTargetCode, associationTargetSystem, … + associationsDecorated), + limit/offset/sort.
Method Path Description
GET /ts/map-sets/{id}/versionsversion list
GET /ts/map-sets/{id}/versions/{version}load one version (scope + statistics)
GET /ts/map-set-versions/{id}load version by numeric id
POST /ts/map-sets/{id}/versionscreate version
PUT /ts/map-sets/{id}/versions/{version}update version
POST /ts/map-sets/{id}/versions/{version}/{draft|activate|retire}lifecycle (204)
POST /ts/map-sets/{id}/versions/{version}/duplicateduplicate
DELETE /ts/map-sets/{id}/versions/{version}delete version
POST /ts/map-sets/{id}/versions/{version}/reload-statistics-asyncrecompute statistics → JobLogResponse
Method Path Description
GET /ts/map-sets/{id}/associationsflat association search (MapSetAssociationSearchParams: mapSetVersion, relationships, verified, noMap)
GET /ts/map-sets/{id}/associations/{associationId}load one
GET /ts/map-sets/{id}/versions/{v}/conceptssource-centric (MapSetConcept + associations)
POST /ts/map-sets/{id}/versions/{v}/associationscreate association
PUT /ts/map-sets/{id}/versions/{v}/associations/{id}update association
POST /ts/map-sets/{id}/versions/{v}/associations-batchbulk upsert — {batch: [...]}
POST /ts/map-sets/{id}/versions/{v}/associations/verify{verifiedIds, unVerifiedIds}
POST /ts/map-sets/{id}/versions/{v}/associations/unmap{ids}
POST /ts/map-sets/{id}/versions/{v}/associations/automapMapSetAutomapRequest → JobLogResponse
POST /ts/map-sets/{id}/properties/{propertyId}/delete-usagesclear a property’s usages
Method Path Description
GET /file-importer/map-set/csv-templatedownload CSV template
POST /file-importer/map-set/processfile import (multipart) → JobLogResponse
/tedy/map-sets — list (TEDY.03.1)
/tedy/map-sets/new — create (TEDY.03.2)
/tedy/map-sets/{id} — view shell (TEDY.03.3): Summary · Metadata · Associations
/tedy/map-sets/{id}/versions/new · /versions/{version}/edit — version form
/tedy/map-sets/{id}/compare — version compare (placeholder, shared pattern)
Requirement Target
List load < 2s; server-side pagination (20/page); versionsDecorated only
Associations grid server-paged; filter by relationship / verified / no-map
Automap / reload-statistics async job; non-blocking (poll or fire-and-refresh)
Search debounce ~400ms
List / view / create operate over /ts/map-sets* with the shared envelope.
A version carries a scope (source→target) and statistics; associations are read via .../associations or .../versions/{v}/concepts.
Association authoring (create/edit/verify/unmap/automap) + version lifecycle require MapSet.write; read is open on the guest dev server.
Publisher/status/language/relationship render via their value sets.
traces-from: TODO user stories
children: TEDY.03.1, TEDY.03.2, TEDY.03.3
sibling families: TEDY.01 Code System , TEDY.02 Value Set (shared shell, version form, summary widgets, Tedy* UI)