Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

You can also design your own model from scratch (see "Designing your own model" section below).  So, feel free to start by modifying relationship-types.xml, or creating your own model based on the relationship-types.dtd.

2. Import entity model into the database

In order to enable a defined entity model, it MUST be imported into the DSpace database This is achieved by using the "initialize-entities" script.  The example below will import the "out-of-the-box" entity models into your DSpace installation

Code Block
# The -f command requires a full path to an Entities model configuration file.
[dspace]/bin/dspace initialize-entities -f [dspace]/config/entities/relationship-types.xml

If an Entity (of same type name) already exists, it will be updated with any new relationships defined in relationship-types.xml

If an Entity (of same type name) doesn't exist, the new Entity type will be created along with its relationships defined in relationship-types.xml

Once imported into the Database, the overall structure is as follows:

  • All valid Entity Types are stored in the "entity_type" database table.
  • All Relationship type definitions are stored in the "relationship_type" database table
  • All Relationships between entities get stored in the "relationship" table.
  • Entities themselves are stored alongside Items in the 'item' table.  Every Entity must have a "dspace.entity.type" metadata field whose value is a valid Entity Type (from the "entity_type" table).

Keep in mind, your currently enabled Entity model is defined in your database, and NOT in the "relationship-types.xml".  Anytime you want to update your data model, you'd update/create a configuration (like relationship-types.xml) and re-run the "initialize-entities" command.

3. Configure Collections for each Entity type

Because all Entities are Items, they MUST belong to a Collection.  Therefore, the recommended way to create a different submission forms per Entity type (e.g. Person, Project, Journal, Publication, etc) is to ensure you create a Collection for each Entity Type (as each Collection can have a custom Submission Form).  

A simple XML configuration file is used to determine the relations. This configuration is read into the database (making modeling the data from the UI possible in future versions as well). A sample of how to define a relationship between Publication and Person is shown below:

Code Block
<!-- This relationship defines both the Publication and Person Entities, along with how they are related together. -->
<relationships>
    <type>
        <leftType>Publication</leftType>
        <rightType>Person</rightType>
        <leftLabel>isAuthorOfPublication</leftLabel>
        <rightLabel>isPublicationOfAuthor</rightLabel>
        <leftCardinality>
            <min>0</min>
            <!--<max></max> not specified, unlimited-->
        </leftCardinality>
        <rightCardinality>
            <min>0</min>
            <!--<max></max> not specified, unlimited-->
        </rightCardinality>
    </type>
</relationships>

2. Import entity model into the database

In order to enable a defined entity model, it MUST be imported into the DSpace database This is achieved by using the "initialize-entities" script.  The example below will import the "out-of-the-box" entity models into your DSpace installation

Code Block
# The -f command requires a full path to an Entities model configuration file.
[dspace]/bin/dspace initialize-entities -f [dspace]/config/entities/relationship-types.xml

If an Entity (of same type name) already exists, it will be updated with any new relationships defined in relationship-types.xml

If an Entity (of same type name) doesn't exist, the new Entity type will be created along with its relationships defined in relationship-types.xml

Once imported into the Database, the overall structure is as follows:

  • All valid Entity Types are stored in the "entity_type" database table.
  • All Relationship type definitions are stored in the "relationship_type" database table
  • All Relationships between entities get stored in the "relationship" table.
  • Entities themselves are stored alongside Items in the 'item' table.  Every Entity must have a "dspace.entity.type" metadata field whose value is a valid Entity Type (from the "entity_type" table).

Keep in mind, your currently enabled Entity model is defined in your database, and NOT in the "relationship-types.xml".  Anytime you want to update your data model, you'd update/create a configuration (like relationship-types.xml) and re-run the "initialize-entities" command.

3. Configure Collections for each Entity type

Because all Entities are Items, they MUST belong to a Collection.  Therefore, the recommended way to create a different submission forms per Entity type (e.g. Person, Project, Journal, Publication, etc) is to ensure you create a Collection for each Entity Type (as each Collection can have a custom Submission Form).  

  1. Create at least one Collection for each Entity Type needing a custom Submission form. For example, a Collection for "Person" entities, and a separate one for "Publication" entities.
  2. Edit the Collection. On the "Edit Metadata" page, use the "Entity Type" dropdown to select the Entity Type for this Collection.
    1. This "Entity Type" selection will ensure that every Item submitted to this collection is automatically assigned that Entity type.  So, it ties this Collection to that type of Entity (i.e. no other type of Entity can be submitted to this Collection). 
      1. NOTE: Entity Type is currently not modifiable after being set. This is because changing the Entity type may result in odd behavior (or errors) with in-progress submissions (as they will continue to use the old Entity Type).  If you really need to modify the Entity Type, you can do so by changing the "dspace.entity.type" metadata value on the Collection object. At this time, changing that metadata field would need to be done at the database level.
    2. NOTE: In 7.0, this "Entity Type" dropdown did not exist. In that release, you have to create a "Template Item" from that page. In the In the Template Item, add a single metadata field "dspace.entity.type".  Give it a value matching the Entity type (e.g. Publication, Person, Project, OrgUnit, Journal, JournalVolume, JournalIssue).  This value IS CASE SENSITIVE and it MUST match the Entity type name defined in relationship-types.xml
      1. As of 7.1 (or above) , if you previously created a Template Item in 7.0, the "dspace.entity.type" field value will be migrated to the "Entity Type" dropdown automatically (via a database migration)
  3. Create at least one Collection for each Entity Type needing a custom Submission form. For example, a Collection for "Person" entities, and a separate one for "Publication" entities.
  4. Edit the Collection. On the "Edit Metadata" page, use the "Entity Type" dropdown to select the Entity Type for this Collection.
    1. This "Entity Type" selection will ensure that every Item submitted to this collection is automatically assigned that Entity type.  So, it ties this Collection to that type of Entity (i.e. no other type of Entity can be submitted to this Collection). 
      1. NOTE: Entity Type is currently not modifiable after being set. This is because changing the Entity type may result in odd behavior (or errors) with in-progress submissions (as they will continue to use the old Entity Type).  If you really need to modify the Entity Type, you can do so by changing the "dspace.entity.type" metadata value on the Collection object. At this time, changing that metadata field would need to be done at the database level.
    2. NOTE: In 7.0, this "Entity Type" dropdown did not exist. In that release, you have to create a "Template Item" from that page. In the In the Template Item, add a single metadata field "dspace.entity.type".  Give it a value matching the Entity type (e.g. Publication, Person, Project, OrgUnit, Journal, JournalVolume, JournalIssue).  This value IS CASE SENSITIVE and it MUST match the Entity type name defined in relationship-types.xml
      1. As of 7.1 (or above) , if you previously created a Template Item in 7.0, the "dspace.entity.type" field value will be migrated to the "Entity Type" dropdown automatically (via a database migration).
  5. In the Edit Collection page, switch to the "Assign Roles" tab and create a "Submitters" group.  Add any people who should be allowed to submit/create this new Entity type.
    1. If you only want Administrators to create this Entity type, you can skip this step. Administrators can submit to any Collection.
  6. If you want to hide this Collection, you can choose to only make it visible to that same Submitters group (or Administrators). This does NOT hide the Entities from search or browse, but it will hide the Collection itself
      1. .
  7. In the Edit Collection page, switch to the "AuthorizationsAssign Roles" tab .Add a new Authorization of TYPE_CUSTOM, restricting "READ" to the Submitters group created above (or Administrators if there is no Submitters group).  You can also add multiple READ policies as needed. WARNING: The Submitters group MUST have READ privileges to be able and create a "Submitters" group.  Add any people who should be allowed to submit/create this new EntitiesEntity type.
    1. Remove the default READ policy giving Anonymous permissions.
    2. Assuming you want the Entities to still be publicly available, make sure the DEFAULT_ITEM_READ policy is set to "Anonymous"!

Each of these Collections must be contained in a Community.  The simplest thing to do would be to create a new top-level Community, place your entity Collections there, and (optionally) hide the Community in a fashion similar to "hide this Collection" above.

Obviously, how you organize your Entity Types into Collections is up to you.  You can create a single Collection for all Entities of that type (e.g. an "Author Profiles" collection could be where all "Person" Entities are submitted/stored).  Or, you could create many Collections for each Entity Type (e.g. each Department in your University may have it's own Community, and underneath have a "Staff Profiles" Collection where all "Person" Entities for that department are submitted/stored).  A few example structures are shown below.

Example Structure based on the departments:

  • Department of Architecture
    • Building Technology Program
    • Theses - Department of Architecture
  • Department of Biology
    • Theses - Biology
  • People
  • Projects

OR 

  • Department of Architecture
    • Building Technology Program
    • Theses - Department of Architecture
    • People in Department of Architecture
    • Projects in Department of Architecture
  • Department of Biology
    • Theses - Biology
    • People in Department of Biology
    • Projects in Department of Biology

Example Structure based on the publication type:

    1. If you only want Administrators to create this Entity type, you can skip this step. Administrators can submit to any Collection.
  1. If you want to hide this Collection, you can choose to only make it visible to that same Submitters group (or Administrators). This does NOT hide the Entities from search or browse, but it will hide the Collection itself.
    1. In the Edit Collection page, switch to the "Authorizations" tab.
    2. Add a new Authorization of TYPE_CUSTOM, restricting "READ" to the Submitters group created above (or Administrators if there is no Submitters group).  You can also add multiple READ policies as needed. WARNING: The Submitters group MUST have READ privileges to be able to submit/create new Entities.
    3. Remove the default READ policy giving Anonymous permissions.
    4. Assuming you want the Entities to still be publicly available, make sure the DEFAULT_ITEM_READ policy is set to "Anonymous"!

Each of these Collections must be contained in a Community.  The simplest thing to do would be to create a new top-level Community, place your entity Collections there, and (optionally) hide the Community in a fashion similar to "hide this Collection" above.

Obviously, how you organize your Entity Types into Collections is up to you.  You can create a single Collection for all Entities of that type (e.g. an "Author Profiles" collection could be where all "Person" Entities are submitted/stored).  Or, you could create many Collections for each Entity Type (e.g. each Department in your University may have it's own Community, and underneath have a "Staff Profiles" Collection where all "Person" Entities for that department are submitted/stored).  A few example structures are shown below.

Example Structure based on the departments:

  • Department of Architecture
    • Building Technology Program
    • Theses - Department of Architecture
  • Department of Biology
    • Theses - Biology
  • People
  • Projects

OR 

  • Department of Architecture
    • Building Technology Program
    • Theses - Department of Architecture
    • People in Department of Architecture
    • Projects in Department of Architecture
  • Department of Biology
    • Theses - Biology
    • People in Department of Biology
    • Projects in Department of Biology

Example Structure based on the publication type:

  • Books
  • Books
    • Book Chapter
    • Edited Volume
    • Monograph
  • Theses
    • Bachelor Thesis
    • Doctoral Thesis
    • Habilitation Thesis
    • Master Thesis
  • People
  • Projects

...

Virtual Metadata is configurable for all Entities and all relationships.  DSpace comes with default settings for its default Entity model, and those can be found in [dspace]/config/spring/api/virtual-metadata.xml. In that Spring Bean configuration file, you'll find a map of each relationship type to a metadata field & its value.  Here's a summary of how it works:

The "org.dspace.content.virtual.VirtualMetadataPopulator" bean maps every Relationship type (from relationship-types.xml) to a <util:map> definition (of a given ID) also in the virtual-metadata.xml

Code Block
<!-- For example, the isAuthorOfPublication relationship is linked to a map of ID "isAuthorOfPublicationMap" -->
<entry key="isAuthorOfPublication" value-ref="isAuthorOfPublicationMap"/>

, you'll find a map of each relationship type to a metadata field & its value.  Here's a summary of how it works:

  • The "org.dspace.content.virtual.VirtualMetadataPopulator" bean maps every Relationship type (from relationship-types.xml) to a <util:map> definition (of a given ID) also in the virtual-metadata.xml

    Code Block
    <!-- For example, the isAuthorOfPublication relationship is linked to a map of ID "isAuthorOfPublicationMap" -->
    <entry key="isAuthorOfPublication" value-ref="isAuthorOfPublicationMap"/>


  • That <util:map> defintion defines which DSpace metadata field will store the virtual metadata. It also links to the bean which will dynamically define the value of this metadata field.

    Code Block
    <!-- In this example, isAuthorOfPublication will be displayed in the "dc.contributor.author" field -->
    <!-- The *value* of that field will be defined by the "publicationAuthor_author" bean -->
    <util:map id="isAuthorOfPublicationMap">
        <entry key="dc.contributor.author" value-ref="publicationAuthor_author"/>
    </util:map>


  • A bean of that ID then defines the value of the field, based on the related Entity. In this example, these fields are pulled from the related Person entity and concatenated.  If the Person has "person.familyName=Jones" and "person.givenName=Jane", then the value of "dc.contributor.author" on the related Publication will be dynamically set to "Jones, Jane.

    Code Block
     <bean class="org.dspace.content.virtual.Concatenate" id="publicationAuthor_author">
        <property name="fields">
            <util:list>
                <value>person.familyName</value>
                <value>person.givenName</value>
                <value>organization.legalName</value>
            </util:list>
        </property>
        <property name="separator">
            <value>, </value>
        </property>
        <property name="useForPlace" value="true"/>
        <property name="populateWithNameVariant" value="true"/>
    </bean>


If the default Virtual Metadata looks good to you, no changes are needed.  If you make any changes, be sure to restart Tomcat to update the bean definitions.

Designing your own Entity model

When using a different entities model, the new model has to be configured an loaded into your repository

Thinking about the object model

First step: identify the entity types

  • Which types of objects would you want to create items for: e.g. Person, Publication, JournalVolume
  • Be careful not to confuse a type with a relationship. A Person is a type, an author is a relationship between the publication and the person

Second step: identify the relationship types

  • Which relationship types would you want to create between the entity items from the previous step: e.g. isAuthorOfPublication, isEditorOfPublication, isProjectOfPublication, isOrgUnitOfPerson, isJournalIssueOfPublication
  • Multiple relationships between the same 2 types can be created: isAuthorOfPublication, isEditorOfPublication
  • Relationships are automatically bidirectional, so no need to worry about whether you want to display the authors in a publication or the publications of an author

Third step: visualize your model

  • By creating a drawing of your model, you’ll be able to quickly verify whether anything is missing

View file
namemodel.pdf
height250

Configuring the object model

Configure the model in relationship-types.xml

  • Similar to the default relationship-types.xml, configure a relationship type per connection between two Entity Types
  • Include the two Entity Type names which are being connected.
  • Determine a clear an unambiguous name for the relation in both directions
  • Optionally: determine the cardinality (min/max occurrences) for the relationships
  • Optionally: determine default behavior for copying metadata if the relationship is deleted

Configuring the metadata fields

Determining the metadata fields to use

  • Dublin Core works for publications, but not for a Person, JournalVolume, …
  • There are many standards which can be easily configured: schema.org, eurocris, datacite, …
  • Pick a schema which suits your needs

Configure the submission forms

Configuring the item display pages

  • The metadata configuration is not specific to configurable entities.
  • Similar to other customizations to the item display pages, configure in Angular which metadata fields to display and their label. A template per entity type can be created
  • The relationship display is similar to the metadata configuration
  • Similar to the metadata configuration: configure in Angular which relationship to display and their label

Configuring virtual metadata

  • The isAuthorOfPublication relationship can be displayed for the Publication item as dc.contributor.author
  • The isOrgUnitOfPerson relationship can be displayed for the Person item as organization.legalName
  • This can be configured in virtual-metadata.xml

Configuring discovery

  • Configure the discovery facets, filters, sort options, …
    • The facets for a Person can be job title, organization, project, …
    • The filters for a Person can be person.familyName, person.givenName, …

Additional Technical Details

The original Entities design document is available in Google Docs at: https://docs.google.com/document/d/1wEmHirFzrY3qgGtRr2YBQwGOvH1IuTVGmxDIdnqvwxM/edit

We are working on pulling that information into this Wiki space as a final home, but currently some technical details exist only in that document.

A talk on Configurable Entities was also presented at DSpace 7 at OR2021

Database Storage

The actual type of entity is stored in the "dspace.entity.type" metadata field. 

Flyway will create tables to store the entity type and relationship configuration. The entity type table contains a unique ID and name for the entity type. This table typically only contains a few rows. It uses database indexes to easily and quickly find the entity types.

Code Block
titleTable "entity_type"
 Column |         Type          | Modifiers 
--------+-----------------------+-----------
 id     | integer               | not null
 label  | character varying(32) | not null

The relationship type table contains a unique ID, the 2 entity type IDs (foreign keys), the labels for the relation, and the cardinality details (min and max occurrences in each direction). This table typically only contains a few rows. It uses database indexes to easily and quickly find the relations types.

Code Block
titleTable "relationship_type"
        Column         |         Type          | Modifiers 
-----------------------+-----------------------+-----------
 id                    | integer               | not null
 left_type             | integer               | not null
 right_type            | integer               | not null
 left_label            | character varying(32) | not null
 right_label           | character varying(32) | not null
 left_min_cardinality  | integer               |
 left_max_cardinality  | integer               | 
 right_min_cardinality | integer               | 
 right_max_cardinality | integer               | 

The actual relations are stored in another new database table, containing a row per relation between two entities.

Code Block
titleTable "relationship"
   Column    |  Type   | Modifiers 
-------------+---------+-----------
 id          | integer | not null
 left_id     | uuid    | not null
 type_id     | integer | not null
 right_id    | uuid    | not null
 left_place  | integer | 
 right_place | integer | 

It contains a unique ID, the ID of the relationship type (a foreign key to the table above), and the left and right item (foreign keys to the actual items), and place values to keep track of the position of the entity for the given relationship type. It uses database indexes to easily and quickly find all relations from the current item.

Ordering of Relations (place column)

The “place” columns for relations are similar to the "place" column in the metadatavalue table, which also determines the order of the values. It gets updated automatically with the next number if a relation is created, similar to the current solution to populate the "place" column in the metadatavalue table.

The reason why there's a left and right place separately, is because we don't want the model to restrict which part of the relation has a "place".

Unidirectional example

Image Added

For a journal, there are relations to the journal volumes as visible in REST. The relevant section is:

https://demo.dspace.org/entities/journalvolume/f9b89a11-b44e-4a64-a3b4-ab24a33553c7

"leftId": "a23eae5a-7857-4ef9-8e52-989436ad2955",
"rightId": "f9b89a11-b44e-4a64-a3b4-ab24a33553c7",
"leftPlace": 1,
"rightPlace": 1,

https://demo.dspace.org/entities/journalvolume/343d3263-2733-4367-9dc4-216a01b4a461

"leftId": "a23eae5a-7857-4ef9-8e52-989436ad2955",
"rightId": "343d3263-2733-4367-9dc4-216a01b4a461",
"leftPlace": 2,
"rightPlace": 1,

For this particular relation, the leftPlace is relevant because the leftId contains the current item ID. First the item with leftPlace 1 is displayed. 
Hereafter the item with leftPlace 2 is displayed.

Bidirectional example

Image Added

For an article, there are relations to the OrgUnits visible in REST. The relevant section is:

https://demo.dspace.org/entities/orgunit/d30de96b-1e76-40ae-8ef9-ab426b6f9763

"leftId": "96715576-3748-4761-ad45-001646632963",
"rightId": "d30de96b-1e76-40ae-8ef9-ab426b6f9763",
"leftPlace": 1,
"rightPlace": 2,

https://demo.dspace.org/entities/orgunit/c216201f-ed10-4361-b0e0-5a065405bd3e

"leftId": "96715576-3748-4761-ad45-001646632963",
"rightId": "c216201f-ed10-4361-b0e0-5a065405bd3e",
"leftPlace": 2,
"rightPlace": 2,

For this particular relation, the leftPlace is relevant because the leftId contains the current item ID. First the item with leftPlace 1 is displayed. 
Hereafter the item with leftPlace 2 is displayed.

In the other direction, on the OrgUnit item page there are 6 publications visible in REST. The relevant section is:

https://demo.dspace.org/entities/publication/e98b0f27-5c19-49a0-960d-eb6ad5287067

"leftId": "e98b0f27-5c19-49a0-960d-eb6ad5287067",
"rightId": "d30de96b-1e76-40ae-8ef9-ab426b6f9763",
"leftPlace": 1,
"rightPlace": 1,

https://demo.dspace.org/entities/publication/96715576-3748-4761-ad45-001646632963

"leftId": "96715576-3748-4761-ad45-001646632963",
"rightId": "d30de96b-1e76-40ae-8ef9-ab426b6f9763",
"leftPlace": 1,
"rightPlace": 2,

https://demo.dspace.org/entities/publication/2f4ec582-109e-4952-a94a-b7d7615a8c69

"leftId": "2f4ec582-109e-4952-a94a-b7d7615a8c69",
"rightId": "d30de96b-1e76-40ae-8ef9-ab426b6f9763",
"leftPlace": 2,
"rightPlace": 3,

For this particular relation, the rightPlace is relevant because the rightId contains the current item ID. First the item with rightPlace 1 is displayed. Hereafter the item with rightPlace 2 is displayed, …

The relation with rightPlace 2 is the same relation as mentioned for the article above

The default DSpace database tables will not need to be modified as the entity type is part of the regular metadata.

That <util:map> defintion defines which DSpace metadata field will store the virtual metadata. It also links to the bean which will dynamically define the value of this metadata field.

Code Block
<!-- In this example, isAuthorOfPublication will be displayed in the "dc.contributor.author" field -->
<!-- The *value* of that field will be defined by the "publicationAuthor_author" bean -->
<util:map id="isAuthorOfPublicationMap">
    <entry key="dc.contributor.author" value-ref="publicationAuthor_author"/>
</util:map>

A bean of that ID then defines the value of the field, based on the related Entity. In this example, these fields are pulled from the related Person entity and concatenated.  If the Person has "person.familyName=Jones" and "person.givenName=Jane", then the value of "dc.contributor.author" on the related Publication will be dynamically set to "Jones, Jane.

Code Block
 <bean class="org.dspace.content.virtual.Concatenate" id="publicationAuthor_author">
    <property name="fields">
        <util:list>
            <value>person.familyName</value>
            <value>person.givenName</value>
            <value>organization.legalName</value>
        </util:list>
    </property>
    <property name="separator">
        <value>, </value>
    </property>
    <property name="useForPlace" value="true"/>
    <property name="populateWithNameVariant" value="true"/>
</bean>

If the default Virtual Metadata looks good to you, no changes are needed.  If you make any changes, be sure to restart Tomcat to update the bean definitions.

Designing your own Entity model

When using a different entities model, the new model has to be configured an loaded into your repository

Thinking about the object model

First step: identify the entity types

  • Which types of objects would you want to create items for: e.g. Person, Publication, JournalVolume
  • Be careful not to confuse a type with a relationship. A Person is a type, an author is a relationship between the publication and the person

Second step: identify the relationship types

  • Which relationship types would you want to create between the entity items from the previous step: e.g. isAuthorOfPublication, isEditorOfPublication, isProjectOfPublication, isOrgUnitOfPerson, isJournalIssueOfPublication
  • Multiple relationships between the same 2 types can be created: isAuthorOfPublication, isEditorOfPublication
  • Relationships are automatically bidirectional, so no need to worry about whether you want to display the authors in a publication or the publications of an author

Third step: visualize your model

  • By creating a drawing of your model, you’ll be able to quickly verify whether anything is missing

View file
namemodel.pdf
height250

Configuring the object model

Configure the model in relationship-types.xml

  • Similar to the default relationship-types.xml, configure a relationship type per connection between 2 entity types
  • Include the 2 entity type names which are being connected.
  • Determine a clear an unambiguous name for the relation in both directions
  • Optionally: determine the cardinality (min/max occurrences) for the relationships
  • Optionally: determine default behavior for copying metadata if the relationship is deleted

Configuring the metadata fields

Determining the metadata fields to use

  • Dublin Core works for publications, but not for a Person, JournalVolume, …
  • There are many standards which can be easily configured: schema.org, eurocris, datacite, …
  • Pick a schema which suits your needs

Configure the submission forms

Configuring the item display pages

  • The metadata configuration is not specific to configurable entities.
  • Similar to other customizations to the item display pages, configure in Angular which metadata fields to display and their label. A template per entity type can be created
  • The relationship display is similar to the metadata configuration
  • Similar to the metadata configuration: configure in Angular which relationship to display and their label

Configuring virtual metadata

  • The isAuthorOfPublication relationship can be displayed for the Publication item as dc.contributor.author
  • The isOrgUnitOfPerson relationship can be displayed for the Person item as organization.legalName
  • This can be configured in virtual-metadata.xml

Configuring discovery

  • Configure the discovery facets, filters, sort options, …
    • The facets for a Person can be job title, organization, project, …
    • The filters for a Person can be person.familyName, person.givenName, …

Additional Technical Details

The original Entities design document is available in Google Docs at: https://docs.google.com/document/d/1wEmHirFzrY3qgGtRr2YBQwGOvH1IuTVGmxDIdnqvwxM/edit

We are working on pulling that information into this Wiki space as a final home, but currently some technical details exist only in that document.

A talk on Configurable Entities was also presented at DSpace 7 at OR2021

Tilted relationships

The tilted relationships are a default DSpace 7 feature, developed in https://github.com/DSpace/DSpace/pull/3134

...