Introduction
Our Enterprise Architecture Metamodel provides a structured overview of the core component types and their relationships within our model.
We are utilising a single shared instance of Ardoq to model the health and care architecture across NHS Wales.
Our metamodel is derived from the Ardoq Use Case Solutions and customised the fit the context of NHS Wales. Any deviations from the Ardoq recommended metamodel are capture as metamodel decisions.
Decisions
Warning
If a new decision/change is made to the metamodel ensure the metamodel diagram here is updated alongside the Gremlin query and associated report in Ardoq
The following decisions have been made regarding the metamodel:
Metamodel Diagram
This is a high-level diagram of the metamodel to aid comprehension, it is a non-exhaustive view and therefore doesn't capture every aspect of the model.
graph TD
accTitle: Enterprise Architecture Metamodel.
accDescr: A diagram showing a high level relationships between components in the enterprise architecture metamodel.
Business_Capability -->|Is Realized By| Application
Technical_Capability -->|Is Realized By| Application
Person -->|Belongs To| Organization
Person -->|Assigned To| Roles
Person -->|Owns, Is Expert In| Application
Organisation -->|Own, Supports, Supplies, Consumes| Application
External_Organisation -->|Supplies| Application
Application -->|Is Supported By| Database
Application -->|Accesses / Connects To| Logical_Information
Application -->|Connects To / Is Supported By / Depends On| Technology_Service
Infrastructure -->|Is Supported By| Database
Database -->|Is Located At| Locations
Technology_Services -->|Is Supported By| Infrastructure
Tip
See Mermaid Docs for more information on creating/editing these diagrams and the Mermaid Live Editor.
Metamodel Compliance Query
A Gremlin query is maintained within Ardoq to produce a "Metamodel Compliance" report. It will identify any relationships between components that do not match the agreed metamodel (i.e. non-compliant 'source -> reference -> target' relationships).
The source for this query is maintained within the ea-metamodel-compliance.groovy
file of this repository, allowing for version control. The contents of the
latest version of this query can be seen below:
def validReferences = [
['Business Capability', 'Is Realized By', 'Application'],
['Business Capability', 'ardoq_parent', 'Business Capability'],
['Technical Capability', 'Is Realized By', 'Application'],
['Technical Capability', 'ardoq_parent', 'Technical Capability'],
//
['Person', 'Is Expert In', 'Application'],
['Person', 'Is Expert In', 'Business Capability'],
['Person', 'Owns', 'Application'],
//
['Organizational Unit', 'Consumes', 'Application'],
['Organizational Unit', 'Consumes', 'Application Module'],
['Organizational Unit', 'Supplies', 'Application'],
['Organizational Unit', 'Supports', 'Application'],
['Organizational Unit', 'Owns', 'Application'],
['Organizational Unit', 'ardoq_parent', 'Organization'],
['Organizational Unit', 'ardoq_parent', 'Organizational Unit'],
['Organizational Unit', 'Partners With', 'Organizational Unit'],
//
['Application Module', 'ardoq_parent', 'Application'],
['Application', 'ardoq_parent', 'Application'],
['Application', 'ardoq_parent', 'Application Group'],
['Application', 'Has Successor', 'Application'],
['Application', 'Connects To', 'Application'],
['Application', 'Depends On', 'Application'],
['Interface', 'ardoq_parent', 'Application'],
['Interface', 'Connects To', 'Application']
]
def isLegalReference = {
project('sourceType', 'type', 'targetType').
by(outV().label()).
by(label()).
by(inV().label()).
filter{
validReferences.any{ validReference ->
validReference[0] == it.get()['sourceType'] &&
validReference[1] == it.get()['type'] &&
validReference[2] == it.get()['targetType']
}
}
}
g.V().
hasLabel('Application', 'Business Capability', 'Person', 'Organizational Unit').
bothE().
dedup().
not(isLegalReference()).
project('source', 'source type', 'reference', 'target', 'targetType type').
by(outV().values('name')).
by(outV().label()).
by(label()).
by(inV().values('name')).
by(inV().label())