Flint (tx-fhir) — FHIR terminology engine library 🔥🦎
Flint is the shared FHIR terminology engine of the org.helex.tx.* suite — the FHIR façade + terminology
$operations that replaces Kefhir. It ships as a published library org.helex.tx:tx-fhir (module
modules/tx-fhir, package org.helex.tx.fhir) that consumers — TEDY and Teagle — embed and back with
their own storage. It also runs standalone (in-memory) as the conformance target.
Conformance: general-mode tx-ecosystem = 1194/1194 (see [MEMORY run-fhir-tx-ecosystem-tests] for the harness).
What’s in the library
| Piece | Package | Role |
|---|---|---|
| Engine ops | engine/{ValidateCodeOp,LookupOp,ExpandOp,TranslateOp,EngineContextFactory,RegexFilterRewrite,OpResult} | $validate-code / $lookup / $expand / $translate over the HL7 core R5 terminology kernel (org.hl7.fhir.r5 6.10.1, pinned to the tx-ecosystem validator release). RegexFilterRewrite uses linear-time re2j for compose regex filters. |
| Storage SPI | store/{ResourceStore,InMemoryResourceStore,MutableResourceStore} | The seam a consumer implements. Flint ships only the SPI + the in-memory store (and its mutable variant for editable servers) — no DB dependency. |
| Provider SPI | route/{ExternalTerminologyProvider,TerminologyRouter} + providers/… | Per-system providers consulted before the local kernel: UCUM (native, org.fhir:ucum — validate/lookup/expand + convert/canonicalise/analyse), static CodeSystems (ISO-3166 countries, …), SNOMED (version-URI→Snowstorm-branch), and the upstream-FHIR forward (FhirUpstreamDelegate). |
| HTTP surface | FhirResourceController, FhirOperationController | /fhir/{Type}/{id} + ?url= reads, /fhir/metadata (+?mode=terminology), $versions, and the $operation endpoints (GET + POST). |
| Capability | {CodeSystem,ValueSet,ConceptMap}Capability | commons-fhir FhirResourceCapability beans → aggregated /fhir/metadata. |
| Standalone app | FhirEngineApplication | Runs the engine on the in-memory store (./gradlew runFhirEngine, default :18630). |
Embedding Flint in a consumer
A consumer (TEDY, Teagle) depends on the published jar and supplies three things:
implementation("org.helex.tx:tx-fhir:0.1.0-SNAPSHOT") // + the OOM-safe HAPI/kernel set travels transitively (api)
- A
ResourceStoreimpl selected byflint.store— e.g. TEDY’sorg.helex.tx.tedy.fhir.TedyDbResourceStore(flint.store=tedydb, mapstedy.*→ FHIR on read), Teagle’s registry stores, or the bundledInMemoryResourceStore(flint.store=memory). - Config under
flint.*—flint.store,flint.authoritative-hosts(defaulthelex.org),flint.delegate.snomed-target/.default-target(upstream targets — real URLs in the gitignored.env). - A Spring Security chain (Flint stays auth-free) — e.g. TEDY’s
FhirAuthorizationInterceptorgating/fhir/**on{CodeSystem,ValueSet,ConceptMap}.read. TEDY composes Flint viaorg.helex.tx.tedy.config.FhirEngineComposition(@ComponentScanof the Flint package, excludingFhirEngineApplication).
Dependencies / the OOM caveat
Flint re-exports the runtime kernel as api: commons-fhir + hapi-fhir-structures-r5 + hapi-fhir-validation
(together) + hapi-fhir-caching-caffeine (runtimeOnly) + org.hl7.fhir.r5/utilities 6.10.1 (with the
resolution pin) + re2j + commons-collections4 (the kernel’s TerminologyCache needs it; HAPI marks it
optional). Never add hapi-fhir-validation-resources-r5 — its default-profile value sets inflate ~200 MB and
OOM a small heap. The runFhirEngine task pins maxHeapSize=512m as the regression guard.
Run standalone
./scripts/run_backend.sh flint # in-memory engine on :18630
Or point the tx-ecosystem harness at it (see the run-fhir-tx-ecosystem-tests memory).
Adapters vs the reference server
Providers in depth: see
flint-providers.mdfor the UCUM (native) and LOINC (upstream-delegate) providers — their operations, the local-first routing, and the config keys.
Flint’s SNOMED provider follows the reference server’s Snowstorm-delegation model but adds version-URI→branch
resolution (so versioned editions / the xsct test sub-ontology resolve, where a plain FHIR-forward could not).
UCUM is native in Flint (the reference is too) — it covers the conversion / canonicalise / analyse use-cases
that no generic FHIR delegate can. $subsumes and non-FHIR management endpoints (RF2 import, browse) are out of
Flint’s scope — Flint is the FHIR-serving engine, not a SNOMED editorial tool.