Resolvable vocabulary: build + local content-negotiation deploy
Resolvable vocabulary: build, browsable site, and code-list/data fixes
Builds the second deployment from the architecture doc — the dereferenceable vocabulary served at vocabulary.uncefact.org — and fixes several data/UX
issues found while previewing it locally. 7 commits.
Build & local preview
-
build-vocab-site.pyloads allontology/**/*.ttlinto one graph and emitsdist/— every class, property, code list, code value, collection and domain asindex.html+index.ttl+index.jsonld(10,703 resources), plus a landing page,/classesand/code-listsindexes, and whole-graph dumps. Each TTL/JSON-LD is the graph from that point down (a class + its properties, a scheme + its concepts, a concept + its narrower subtree, the root + everything). HTML reuses the existing vocabulary.uncefact.org look & feel, extended for the richer SKOS. -
serve-vocab.pyservesdist/withAccept-header content negotiation (Turtle / JSON-LD / HTML default) — emulating the production CloudFront function. -
methodology/deployment-architecture.mddocuments the two deployments, negotiation strategy, URL↔ file mapping, case-sensitivity handling, and the local → S3 test → prod pipeline.
Code-list navigation UX
- Structured code lists (hierarchy or
skos:Collection) now land on their top-level categories with child counts instead of dumping the whole tree; each has a Browse all N codes flat A–Z view. Collections (party-role/collection/*,unit-of-measure/kind/*) are first-class navigable pages. Concept pages give up/down navigation: full ancestor breadcrumb, broader up link, Narrower (down) children, and grouping membership.
Fixes surfaced in preview
-
Landing diagram links re-pointed from the docs-site paths (
/ontology/<domain>/) to this site — class boxes → their class page, domain regions →/module/<domain>; all links resolve. -
"This resource" links were relative (
index.ttl) and resolved to the whole vocabulary; made absolute so they return the sub-graph only. Added page edge margins. -
Case-collision data loss: URIs are case-sensitive but macOS/Windows filesystems are not, so a class (
/Product) and same-name property (/product) collided and one silently overwrote the other at build time. Colliding resources now get a distinct on-disk directory recorded indist/_manifest.json; the server routes through it. S3 keys stay case-sensitive, so production is unaffected.
Vocabulary/data quality
-
Renamed 7 terms that collided with a class name by case only (URIs not yet published, so no aliases):
address→postalAddress,characteristics→productCharacteristics,measure→measuredValue,party→actingParty,product→suppliedProduct,sensorData→recordedSensorData, and the QUDTdimensionannotation →dimensionVector(kept, not removed). -
Deduped
language-code-list: the BSP source carried every language twice (uppercaseAA+ lowercaseaa, 185 pairs). Kept the lowercase ISO-639-1 form as canonical and retired the 185 uppercase as deprecated stubs (owl:deprecated+dcterms:isReplacedBy, out of the active scheme but still resolvable). The rule lives in the generator so it's reproducible.
Housekeeping
- Added a repo README (purpose + how to run the browsable ontology locally). Validator (6 gates) and fidelity check pass throughout; the code-list generator reproduces every other list byte-identically.