Repository navigation
0.1.0
·
226 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
Added
FERROTERM_BASE_URL: the URL clients reach the server at, stated per version asCapabilityStatement.implementation.urland in the terminology capabilities. A server behind a reverse proxy answers on an address it never sees, so the endpoint is configured rather than guessed from a socket or a forgeable header; a deployment that names none states no URL.compose.yamlgains aproxiedprofile: Caddy terminates TLS in front and the server publishes no host port.GET /metrics: the Prometheus exposition of the requests answered (a counter and a duration histogram per method, matched route, and status) and the code system versions loaded (one gauge each). The route is off the FHIR base path, so a scrape is never a terminology request, and the labels name the matched route rather than the URI, so the series count stays bounded whatever codes clients ask about.X-Request-Idon every response: the client's own value when it sent a usable one, a fresh UUID otherwise, and the same id in the request's log line. An id that is empty, over 128 characters, or not printable ASCII is replaced rather than echoed.$batch-validate-codeonValueSetandCodeSystem, on every served version: onePOSTcarries the shared inputs once, avalidationparameter per validation, each aParametersof that validation's own inputs, and the answer repeatsvalidationin the same order with that validation's$validate-codeoutputs. A validation states its own value for an input the request also states, and a validation the server cannot run answers anOperationOutcomein its own slot while the others still answer. NoOperationDefinitiondeclares the operation anywhere, so the contract is the terminology ecosystem suite's cases, whosebatch/batch-validatenow passes on/r4b,/r4and/r5.- The fuzz targets under
fuzz/: every parser an untrusted input reaches (ECL, the FHIR JSON and XML bodies, the SNOMED CT implicit?fhir_vs=and?fhir_cm=forms, and the RF2 file names, effective times, and identifiers) is fed arbitrary bytes bycargo-fuzz, weekly in CI and by hand for longer runs. The seeds are committed; a crash uploads the input that reproduces it.
Fixed
- The terminology capabilities no longer claim SNOMED CT post-coordination.
CodeSystem.compositionalis "The code system defines a compositional (post-coordination) grammar" andTerminologyCapabilities.codeSystem.version.compositionalis "If the compositional grammar defined by the code system is supported", two different statements that one flag answered, so a client was told it could send expressions and then got "no such concept" for every one. A provider now declares the grammar and this server's support for it separately: SNOMED CT defines the grammar and this server evaluates none, UCUM, BCP 13, BCP 47, and the ICD-11 linearizations parse the grammars they declare, and aCodeSystemresource that declares a grammar is served without one. A post-coordinated code is refused as a grammar this server does not evaluate (not-supported) rather than as a concept the edition lacks. - A code system the deployment loaded reads at its own id and is found by a search.
GET CodeSystem/{id}on the id the server prints at startup was a404andGET CodeSystem?url=…answeredtotal0, while the capability statement declaredreadandsearch-typeand the configuration page documented the id, so a documented instance path addressed nothing. Every loaded version now answers both, under every version prefix: a system held behind an index answers its definition withcontent = not-present, and one loaded as aCodeSystemresource answers with thecontentit declared. A supplement stays applied to the system it supplements and is not served as an instance. CodeSystem/{id}/$lookupanswers under/r5and/r6, whoseOperationDefinitiondeclares the operation at the instance level. The engine refused the instance level on every version; the level is now the served version's own declaration, so/r4and/r4b, which declare the type level only, still offer no such route.- A SNOMED CT implicit value set or concept map based on a non-default edition answers when several editions are loaded. The FHIR SNOMED CT page lets any edition version stand as the base URL, and the edition in the base decides the membership, but the server only asked the default version of the system, so every
?fhir_vsform and?fhir_cm=on another loaded edition was refused as a malformed URI. The registry now asks every loaded version, default first, so the barehttp://snomed.info/sctbase still answers from the default edition. A base naming an edition version no loaded version serves is anot-foundon that version rather thanvs-invalid. $translateover a SNOMED CT map reference set returns a targetCodingcarrying both asystemand acode. R4B needsConceptMap.group.target, the "absolute URI that identifies the target system that the concepts will be mapped to", unless the target value set names a single system or every target equivalence isunmatched, and an implicit map states neither. RF2 records the scheme nowhere on a member row, so the reference set names it: the ICD-10 extended map (447562003), the ICD-9-CM equivalence map (447563008), the ICD-O map (446608001), the CTV3 map (900000000000497000), and the US Edition's ICD-10-CM map (6011000124106) each state the URI FHIR publishes for their scheme, on the servedConceptMapand on every match. A map reference set outside that table answersnot-supportedinstead of a code with no system. An association reference set names SNOMED CT on both sides, whichever reference set it is.- The LOINC and RxNorm builds name a property key they never registered instead of reporting "too many concepts": a defect in the build no longer surfaces as a capacity error. The RxNorm relationship-type lookup is split the same way, and
TooManykeeps its own meaning. - An expression constraint of deeply nested brackets no longer takes the server down. The ECL parser descends with the grammar, so an unbounded nesting exhausted the stack and aborted the process, which no
OperationOutcomesurvives; the parser now refuses pastsct_ecl::NESTING_LIMIT(64) and the server answers the refusal as anOperationOutcome. Found by theecl_parsefuzz target.
Changed
- A flat
$expandanswers in the order the compose selected: the includes in order, each include's named concepts as it named them, each filter's concepts in the code system's own order, and the first occurrence winning where includes overlap.countandoffsetpage over that order. No FHIR version fixes the order of an expansion, andValueSet.compose.include.conceptsays an expansion typically follows the compose; a compose of one filter still pages off the selection bitmap without reading a concept. The ICD-11 postcoordination axis now answers in the WHO's own scale order, which the terminology ecosystem suite'sicd-11/expand-pcs-countandicd-11/expand-pcs-offsetcases assert together.