Skip to content

HAS_NAME Party Data

Description

Connects a :Party, :EventSeries or :Venue to a name.

Label

HAS_NAME

Valid nodes

FromRelationshipTo
Party
A node with the :Party label
:HAS_NAMEName
A node with the :Name label
EventSeries
A node with the :EventSeries label
:HAS_NAMEName
A node with the :Name label
EventInstance
A node with the :EventInstance label
:HAS_NAMEName
A node with the :Name label
Venue
A node with the :Venue label
:HAS_NAMEName
A node with the :Name label

Properties

HAS_NAME uses the standard relationship properties,

CREATE

The overall goal is to keep one and only one active display name, and each active alias should be unique and distinct from the display name.

Names are case sensitive. No specific casing should be assumed. For example, a name can be ALL CAPS, "all lowercase", or any mixture of upper and lowercase.

Names can contain special characters like "$".

If creating a :Name of type...Cardinality isThe ACID transaction should be...
Display1Reject if exact duplicate of current active display name
Deactivate the current Display name effective today
Reject if there is an Alias of the exact same name
Create a new Alias with the old display name effective today
Create and set active a new :Name of type Display effective today
Replicate the newly created name into the :Party name property, overwriting what is there
Alias0..nCreate new aliases as requested, but do not allow exact dupes of any existing alias name for this party
Legal0..1Reject if exact duplicate of current active legal name
If there is a currently active legal name, deactivate the current Legal name effective today with termReason "Changed legal name"
Create and set active a new :Name of type Legal

We will enforce business rules for the kinds of names a party is allowed to have based on the existence of an active :Role, or whether it is a :Venue or EventSeries node. The checkmarks below indicate which names are allowed by role:

:Name typeClientBuyerEmployeeTalentContactParticipantVenueEventSeries
Display
Alias
Legal

TODO

Clarify allowed names for parties in multiple roles

Creating names in practice

The following Cypher query demonstrates the steps needed in a transaction needed to change the display name for a party.

cypher
// Deactivate the currently active display name effective today

MATCH    (p:Party { id: $id})
       -  [rel:HAS_NAME { active: true }]
       -> (oldName:Name { type: 'Display'})
SET    rel.thruDate = date(),
       rel.active = false,
       rel.termReason = 'Testing business rules'

// Create a new name node of type "alias", using the old name,
// and set the relationship as active, effective today

WITH  p, oldName
MERGE (p)-[aliasRel:HAS_NAME {
        active: true,
        private: false,
        fromDate: date(),
        thruDate: "",
        termReason: ""
      }]->(newAlias:Name {
        type: 'Alias',
        name: oldName.name,
        givenName: oldName.givenName,
        additionalName: oldName.additionalName,
        familyName: oldName.familyName,
        honorificPrefix: oldName.honorificPrefix,
        honorificSuffix: oldName.honorificSuffix,
        createdBy: 'Glenn Scott',
        createdDate: date(),
        modifiedBy: 'Glenn Scott',
        modifiedDate: date()
      })

// Create and attach a new display name node and set relationship active,
// effective today

WITH   p
MERGE  (p)-[newNameRel:HAS_NAME {
          active: true,
          private: false,
          fromDate: date(),
          thruDate: "",
          termReason: ""
        }]->(newName:Name {
          type: 'Display',
          name: 'Adrienne Di Piazza 4',
          givenName: 'Adrienne',
          additionalName: '',
          familyName: 'Di Piazza 4',
          honorificPrefix: '',
          honorificSuffix: '',
          createdBy: 'Glenn Scott',
          createdDate: date(),
          modifiedBy: 'Glenn Scott',
          modifiedDate: date()
        })

// Replicate the name into the `:Party` `name` property

WITH    p, newName
SET     p.name = newName.name,
        p.modifiedBy = 'Glenn Scott',
        p.modifiedDate = date()
RETURN  p{.*}

After several creates the name nodes will build up. For example, after running a query like the above three times, we end up with seven names (one active display name, three inactive display names, and three active aliases):

Party names graph excerpt

Use a query like this to summarize all the names for the party:

cypher
MATCH    (p:Party { id: $id})-[rel:HAS_NAME]->(names:Name)
RETURN   names.type as type,
         names.name as name,
         rel.active as active,
         rel.fromDate as fromDate,
         rel.thruDate as thruDate,
         rel.termReason as termReason
ORDER BY names.type, rel.active DESC, rel.thruDate DESC

The resulting table shows the most recent display name that is active, as well as the former display names that are properly marked inactive with termination dates for their relationships. The table also shows the three aliases created for each new display name.

typenameactivefromDatethruDatetermReason
AliasAdrienne Di Piazza 3true"2023-01-28"
AliasAdrienne Di Piazza 2true"2023-01-28"
AliasAdrienne Di Piazzatrue"2023-01-27"
DisplayAdrienne Di Piazza 4true"2023-01-28"
DisplayAdrienne Di Piazza 3false"2023-01-28""2023-01-28"Testing business rules
DisplayAdrienne Di Piazza 2false"2023-01-27""2023-01-28"Testing business rules
DisplayAdrienne Di Piazzafalse"2022-12-07""2023-01-27"Testing business rules

TIP

A query somewhat like this could be used as the underlying source for data used by an API endpoint (perhaps GET /parties/{id}/names) to provide a timeline of changes to a particular entity. This would be especially useful in data management tools used by governance and data management personnel.

TODO

Rules about overlapping relationships

UPDATE

Most updates to existing names should be rejected in favor of deactivation + create flows as described above, so as to preserve the history of the changes. However, there are some situations where we will need to change a name on an existing :Name node because of a typographic error, and where holding on to the misspelled name would not be appreopriate. In all cases below, the only property that may be changed is name and the API update operation should be limited to data management personnel.

If updating a :Name of type...The ACID transaction should be...
DisplayUpdate name and modified properties
AliasUpdate name and modified properties
LegalUpdate name and modified properties

DELETE

For names, the DELETE verb corresponds to deactivating the relationship between the party and the :Name node. The rules depend on the type of :Name:

If deactivating a :Name of type...The ACID transaction should be...
DisplayNot allowed. The correct flow for deactivating a display name is described in CREATE above
AliasDeactiviate the current HAS_NAME relationship for this alias as of today with a required termReason
LegalDeactivate the current HAS_NAME relationship for this legal name as of today with a required termReason

Examples

Confidential. For internal use only.