Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

TEDY.07 — Spaces

State: Built — list + TxResourceBar detail with Summary · Metadata (Core + GitHub edit) · linked Code Systems / Value Sets / Map Sets (add-as-link + unlink) · Comparison (diff) · Repository (git). Create page + list Add. Simplified scope (below) confirmed with the product owner.

Template: tool-feature. Prefix: TEDY.

Feature grouping

Root spec for the Spaces family (a “Management” section resource). References TEDY.08 Servers (bound servers + the cross-server comparison).

Overview

A Space is an authoring workspace that groups terminology resources (CS / VS / MS), optionally bound to terminology servers and a git repository (GitHub, with Azure DevOps as a feature-flagged sibling) for round-tripping FHIR content. Served off /spaces (NOT /ts/*); numeric id.

Design decisions:

  • TEDY renders the space detail through the shared TxResourceBar (same tabbed shell as CS/VS/MS/Servers), NOT the reference editor’s matrix-param “context” shell (;s=;p=;v=). Comparison and Repository are tabs on that bar.
  • Simplified scope (deliberately narrower than the reference): no package-manager UI, no SSG generator, no ACL editor, no wiki/GitHub import. mdBook (replacing the SSG) is a future concern and is not implemented.
  • Resources map directly to the Space. The UI shows the space’s linked resources as one flat set per type; “Add” links an existing resource. Because the backend only persists links through Package → PackageVersion → PackageResource, this is backed by an auto-managed, hidden default package (one package, one version) — the package/version layer is never surfaced in the UI.
  • Metadata = Core + GitHub only.

Data model

Space (libs/tedy/src/lib/types/space.ts)

id:number, code, names:LocalizedName, active, shared, globalSearch, terminologyServers:string[], integration:{ github?:{repo,dirs}, msDevops?:{repo,dirs} }.

Package / PackageVersion / PackageResource (libs/tedy/src/lib/types/spacePackage.ts) — internal

The hidden layer backing “map resources directly to the space”:

  • Package { id?, code?, status?, spaceId? } (status draft/active).
  • PackageVersion { id?, version?, description?, packageId?, resources?: PackageResource[] }.
  • PackageResource { id?, resourceType: 'code-system'|'value-set'|'map-set', resourceId, resourceVersion?, terminologyServer?, versionId? } — a reference to an existing CS/VS/MS, not an owned copy.
  • PackageTransactionRequest { pack: Package, version?: PackageVersion } (one transactional save; the backend retains the full resource list — resources not in the payload are soft-cancelled).
  • SpaceDiff { items?: SpaceDiffItem[], error? }, SpaceDiffItem { id?, resourceId?, resourceType?, resourceServer?, upToDate? }.
  • Git: SpaceGitStatus { sha?, files?: Record<path,'M'|'U'|'D'|'A'|'K'> }, SpaceGitDiff { left?, right? }.

REST API (base /spaces)

  • Space: GET/POST /spaces, GET /spaces/{id}, GET /spaces?{params}. Save = saveSpace (POST create / PUT-style upsert).
  • Packages (hidden): GET/POST /spaces/{spaceId}/packages, GET …/{id}/versions. Save body = PackageTransactionRequest.
  • Add-as-link resolves the default package + latest version (loadSpaceDefaultVersion), appends/removes a PackageResource, and re-saves the whole version (linkResourceToSpace / unlinkResourceFromSpace, libs/tedy/src/lib/client/spacePackageLink.ts). Dedup by resourceType + resourceId; creates the default package ({code: space.code||'default', status:'draft'} + version 1.0.0) if absent.
  • Diff: GET /spaces/{id}/diffLorque 202 {id}; poll GET /lorque-processes/{id} until finished/failed; result is base64 JSON. runSpaceDiff (spaceDiffClient.ts) drives start→poll→decode and rejects with the decoded error on failed.
  • Git (github|msdevops, spaceGitClient.ts): GET /spaces/{p}/providers, POST /spaces/{id}/{p}/authenticate {returnUrl}{isAuthenticated,redirectUrl}, GET /spaces/{id}/{p}/status, GET /spaces/{id}/{p}/diff?file=, POST /spaces/{id}/{p}/push {message,files}, POST /spaces/{id}/{p}/pull {files}.
  • Resource lists are linked-resource reads: the CS/VS/MS search endpoints resolve spaceId by JOINing through package_version_resource → package_version → package → space, so searchCodeSystems({spaceId}) returns exactly the linked set.

Metadata — attributes (Core + GitHub)

SectionFieldsNotes
Corecode (required), name (AppLocalizedName), active, globalSearch, servers (multiselect of terminology-server codes)view ⇄ edit via useDataController
GitHubenable + repo (addonBefore=https://github.com/) + per-provider directory inputs (GET /spaces/github/providers)object-defaulting before binding; save nulls disabled integrations
Azure DevOpssame block, feature-flagged (VITE_TX_MSDEVOPS_ENABLED)hidden unless the flag is on

ACL, SSG (metadata + generator), packages sub-list and import-from-GitHub are intentionally out of scope.

Screens / tabs (via TxResourceBar)

  • List — Code · Name · Active · GitHub; search + Add (gated *.Space.writespaces/new).
  • Create (SpaceCreate.tsx, spaces/new) — Core-only; saveSpace → navigate to the new space’s Summary.
  • Summary — space info card.
  • Metadata (SpaceMetadata.tsx) — read-only view + inline edit (Core + GitHub / MS DevOps).
  • Code Systems / Value Sets / Map Sets (SpaceResourceListTab.tsx) — list the space’s linked resources; Add = link an existing resource (searchable picker of existing CS/VS/MS, excluding the space’s full linked set → linkResourceToSpace); per-row Unlink (AppPopconfirmunlinkResourceFromSpace).
  • Comparison (SpaceDiffTab.tsx, mode diff) — Run comparison → start the Lorque diff job → poll → table of per-resource/server up-to-date state; idle/loading/error/empty states.
  • Repository (SpaceGitTab.tsx, mode github) — authenticate → Connect (OAuth redirect) when not authenticated, else working-tree status (changed files); Push (commit-message modal, neutral default "update space") + Pull (confirm) + per-file diff modal. Provider-parametrized so MS DevOps reuses the same component under the feature flag.

Routes & nav

/spaces (list), /spaces/new (create). Nav: Management → Spaces. Children under spaces/:id: summary, details, code-systems, value-sets, map-sets, diff, github. TxResourceMode includes diff/github; tabsFor('space') and SpaceResourceLayout.MODES list all seven.

Privileges

*.Space.read (view/list), *.Space.write (add), {id}.Space.write (edit / link / git). Gate with usePrivileged().

Config

VITE_TX_MSDEVOPS_ENABLED (config/tx.tsMSDEVOPS_ENABLED) toggles the Azure DevOps integration UI. Real repo/server URLs stay in the gitignored .env.

Naming

The reference’s default commit message is a brand string — TEDY uses a neutral default ("update space"). Never commit the reference product names. (Backend runtime errors surfaced in the Comparison tab may echo server-side class names; that text is server data, not TEDY source.)

Reference ↔ TEDY comparison

Re-verified against the reference editor’s space module (sys/space/containers/{space,server,package}) and the terminology-server release/feature docs. The reference drives the space detail through a matrix-param context shell (;s=;p=;v=) with a package/version drawer; TEDY replaces that with the shared TxResourceBar (point 2) — same navigation model as CS/VS/MS/Servers, no matrix params.

View / tab mapping (points 1, 4)

Reference viewTEDY tab (TxResourceBar)Status
Space dashboard (linked resources per type)Code Systems / Value Sets / Map Sets tabsBuilt — linked-resource lists + add-as-link + unlink + bulk actions
space-edit (metadata + packages + SSG + ACL)Metadata tab (view ⇄ edit)Built (Core + GitHub); packages/SSG/ACL descoped
space-diff (single-resource 3-pane)Comparison tabBuilt — whole-space diff table (Lorque)
space-diff-matrix (resource × server grid)Comparison tabBuilt — diff items + State filter + row selection + bulk change-server + per-row sync (local/external)
space-githubRepository tabBuilt — auth / status / push / pull / per-file diff
space-ms-dev-opsAzure DevOps tabBuilt — dedicated msdevops tab/route (flagged), reuses the provider-parametrized SpaceGitTab
Summary tabBuilt (space info card; TEDY addition)

Metadata attribute comparison (point 3)

Reference field(s)SectionTEDY status
code, names, active, globalSearch, terminologyServersCoreBuilt (view + edit)
integration.github (repo + per-provider dirs)GitHubBuilt
integration.msDevops (repo + dirs)Azure DevOpsBuilt, feature-flagged (VITE_TX_MSDEVOPS_ENABLED)
packages sub-list (open / add / delete)PackagesDescoped — replaced by the hidden auto-default package (resources map directly to the space)
description, languages, defaultLanguage, siteUrlSSG metadataPlanned (mdBook) — additive/nullable when mdBook lands
ssgSkin, ssgThemeAccent, ssgThemeSwitcher, ssgFooterMessage, ssgFooterCopyright, ssgTxServer, ssgSearch, ssgLogoSSG generatorDescoped — mdBook replaces the SSG generator
acl (owners/editors/viewers), sharedACLDescoped — access enforced via *.Space.* privileges
import-from-GitHub (POST /wiki-import/github)ImportDescoped — wiki import out of scope

Remaining gaps & implementation plan (point 5)

Everything the approved simplified scope calls for is built (points 2, 4, 6). Items 1–3 below (the reference deltas) are now also built; item 4 waits on the mdBook decision.

  1. Comparison matrix (space-diff-matrix) — Built. The Comparison tab lists diff items with a State filter (up-to-date / differs), row selection, a bulk change comparable server (POST /package-resources/change-server {resourceIds, terminologyServer}, options from the space’s terminologyServers), and a per-row Sync menu — into space (local) / to server (external) — via POST /package-resources/{id}/sync (packageResourceClient.ts).
  2. Per-resource Comparison shortcutBuilt. Each linked CS/VS/MS row has a Compare action opening the Comparison tab.
  3. Dedicated MS DevOps tabBuilt. msdevops added to TxResourceMode + tabsFor('space') (shown only when MSDEVOPS_ENABLED) + SpaceResourceLayout.MODES + a spaces/:id/msdevops route rendering SpaceGitTab provider="msdevops" (provider-aware label/icon/empty-state).
  4. mdBook metadata (future) — when the mdBook direction lands, add an mdBook section to Metadata for description/languages/defaultLanguage/siteUrl (additive, nullable). Not the old SSG generator.

Backend note: the space diff needs a comparable-server-configured space; on the dev backend it returns TC105: Terminology server for current installation is not defined, so the populated matrix (and per-row sync) are verified only against a configured deployment — the error/empty paths are verified in dev.

See open questions in TEDY-new-modules-open-questions.md.