HAS_NAME Party Data
Description
Connects a :Party, :EventSeries or :Venue to a name.
Label
HAS_NAME
Valid nodes
| From | Relationship | To |
|---|---|---|
| Party A node with the :Party label | :HAS_NAME | Name A node with the :Name label |
| EventSeries A node with the :EventSeries label | :HAS_NAME | Name A node with the :Name label |
| EventInstance A node with the :EventInstance label | :HAS_NAME | Name A node with the :Name label |
| Venue A node with the :Venue label | :HAS_NAME | Name 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 is | The ACID transaction should be... |
|---|---|---|
Display | 1 | Reject if exact duplicate of current active display name Deactivate the current Display name effective todayReject 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 todayReplicate the newly created name into the :Party name property, overwriting what is there |
Alias | 0..n | Create new aliases as requested, but do not allow exact dupes of any existing alias name for this party |
Legal | 0..1 | Reject 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 type | Client | Buyer | Employee | Talent | Contact | Participant | Venue | EventSeries |
|---|---|---|---|---|---|---|---|---|
| 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.
// 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):
Use a query like this to summarize all the names for the party:
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 DESCThe 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.
| type | name | active | fromDate | thruDate | termReason |
|---|---|---|---|---|---|
| Alias | Adrienne Di Piazza 3 | true | "2023-01-28" | ||
| Alias | Adrienne Di Piazza 2 | true | "2023-01-28" | ||
| Alias | Adrienne Di Piazza | true | "2023-01-27" | ||
| Display | Adrienne Di Piazza 4 | true | "2023-01-28" | ||
| Display | Adrienne Di Piazza 3 | false | "2023-01-28" | "2023-01-28" | Testing business rules |
| Display | Adrienne Di Piazza 2 | false | "2023-01-27" | "2023-01-28" | Testing business rules |
| Display | Adrienne Di Piazza | false | "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... |
|---|---|
Display | Update name and modified properties |
Alias | Update name and modified properties |
Legal | Update 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... |
|---|---|
Display | Not allowed. The correct flow for deactivating a display name is described in CREATE above |
Alias | Deactiviate the current HAS_NAME relationship for this alias as of today with a required termReason |
Legal | Deactivate the current HAS_NAME relationship for this legal name as of today with a required termReason |