Summary
Almost everything you create in Linkr is an entity: a project, a schema, an ETL pipeline, a plugin… Ten kinds, but a single shape — a file tree with the same identity record at its root. Exporting, versioning and publishing then work the same way across all ten, and what gives every entity an identity that survives the journey from one instance to another.
Ten kinds, one shape
A project and a plugin have nothing in common in substance. Yet from a sharing point of view they raise the same questions: who made it, under what licence, in which version, and how do I recognise it if someone sends it back to me changed?
Linkr answers those questions once and for all: the ten kinds of entity share the same structure. Two containers carry everything they hold. Seven warehouse resources, filed under the workspace’s Data Warehouse, are shared across projects — these are the ones that gain most from circulating: an OMOP schema or a set of quality rules is worth the same to everyone. Then comes the tooling, which extends Linkr itself.
A workspace holds all the rest
10 entity typesThe containers
Workspace
The shared container, exported whole.
workspaceProject
A study: cohorts, analyses, dashboards, code.
projectThe warehouse resources
Schema
How to read a source.
schema-presetDatabase
A declared source, with its schema and cohorts.
databaseConcept mapping
Local codes → standard vocabulary.
mapping-projectScript collection
SQL queries in folders.
sql-collectionQuality rules
Checks to run on a database.
dq-rule-setData catalog
A database's content, as aggregate counts.
data-catalogETL pipeline
A source converted to OMOP.
etl-pipelineThe tooling
Plugin
A packaged analysis that becomes a widget.
user-pluginEach one exports as a file tree: JSON configuration files, your content, your documentation. What you see on screen, what the ZIP archive holds and what goes into a git repository are one and the same thing. See Workspaces and projects.
The identity record
At the root of every entity sits a file named entity.json. It is its identity record: it says what kind of entity this is, what it is called, who produced it and on what terms it can be reused.
{
"type": "project",
"name": { "en": "ICU — mortality", "fr": "Réanimation — mortalité" },
"description": { "en": "Monitoring mortality in intensive care" },
// … the content specific to the kind: here cohorts, dashboards …
"createdBy": "Ada Lovelace",
"createdByDetails": { "orcid": "0000-0000-0000-0001" },
"organization": { "name": { "en": "Rennes University Hospital" }, "type": "hospital" },
"lineageId": "a3f1c2…",
"parentLineageId": null,
"version": "1.2.0",
"license": { "id": "MIT", "name": "MIT License" }
}
Four blocks always follow in this order: what it is, the content specific to the kind, who produced it, then how it is published.
Two practical consequences. First, identity comes before content: opening the file shows you what you are dealing with, not a wall of data. Second, Linkr can read an entity without knowing in advance what it is — it reads the type field and works out the rest. That is what makes importing universal: you drop in an archive, and Linkr recognises what is inside.
The identity that survives the journey
This is the least visible part, and the most useful. Picture it: you publish a set of quality rules, a colleague installs them, improves them, sends them back. When you re-import, what should Linkr do?
With no stable identity it would create a duplicate — two rule sets under the same name, and it is on you to untangle them. So every entity carries a lineage identifier that follows it everywhere: re-importing the same entity updates it in place.
Lineage identity
What makes an entity stay itself across instances. It travels with the export.
Local identifier
The internal key of your instance. It never leaves the machine: each instance assigns its own.
An entity derived from another also keeps a trace of its parent. Picture it: you publish your project, analysis code included. Another centre picks it up, applies it to their own patients, fixes a bias you had not spotted, adds an adjustment variable. Their project knows which project it descends from — and yours stays yours.
That is what lets you follow a lineage without confusing the original with its variants: anyone can trace where an analysis came from, and compare two versions of the same method applied to two populations.
The author, the institution and the licence
An entity shared without an author or a licence is hard to reuse: no one knows who to credit or what they may do with it. So every entity carries three complementary pieces of information.
- The author — the person, with their ORCID identifier if they have one, which makes the work citable.
- The organization — the publishing institution. It sits next to the author rather than next to the version, because this is co-authorship, not packaging.
- The licence — on what terms a third party may build on the work.
Every entity can also carry its README and illustrating images. That is what shows up when someone discovers it in the catalog.
Three ways to move an entity around
These foundations serve three ways of moving one around, each covered on its own page.
The archive
A ZIP file to download and re-import elsewhere. The simplest route, available even in the browser.
The git repository
Link an entity to a remote repository to follow its history and work together over time.
The catalog
Publish for the community, or install what others have published, in one click.
Data does not travel by default
Exporting an entity does not carry the data files it holds: they are excluded by default, and you explicitly mark the ones that should travel. This is a deliberate safeguard — sharing a dashboard must never leak patient data by accident. See Import and export.
Going further
- Workspaces and projects — the two levels these entities live in.
- Versioning and collaboration — why Linkr builds on git rather than a proprietary format.
- Publishing content — preparing an entity so others can reuse it.