HAS_ROLE Party Category
Description
The HAS_ROLE relationship is used to track the current and past state of role relationships.
Label
:HAS_ROLE
Valid nodes
| From | Relationship | To | Cardinality |
|---|---|---|---|
| Party A party node | :HAS_ROLE | Role A node with the :Role label and a specific name property | 1..n |
Properties
HAS_ROLE uses the standard relationship properties, but makes use of the normally optional subType property.
The subtype property is used to indicate the specific role that a party has within a particular role type. For example, a party may have a role of Buyer with a subtype of Brand.
The valid values for the HAS_ROLE subtype relationship property:
| Role | Valid Subtypes | Notes |
|---|---|---|
| Client | Rostered | It's fine to show this client on rosters |
| Private | Do not display this client on external marketing | |
| Protected | Client is sensitive and/or in the process of departing. Do not publish info. | |
| Talent | ||
| Employee | ||
| Contact | ||
| Buyer | Brand | |
| Distributor | ||
| MP Studio | ||
| TV Studio | ||
| Touring | ||
| Platform | ||
| Network | ||
| External | ||
| Agency | Financing | |
| Foreign Sales | ||
| Packaging | ||
| Sales | ||
| Talent | ||
| Sport Organization | League | |
| Sport Team | Team |
Why a subType on the relationship, rather than on the Role node?
Here we've put a subType property on the HAS_ROLE relationship, rather than on the :Role node. The reason is that we want to be able to track the history of a party's role within a particular role type. For example, a party may have been a Buyer for a Brand for a period of time, and then become a Buyer for a Distributor. We want to be able to track that history.
The business rules for proper maintanenace of party-role relationships can get a little complex, because they differ based on the role type and relationship subType. We will try to catalog all of them below.
Client
| # | Operation | Rule |
|---|---|---|
| 1 | CREATE | The client party can be either a person or an organization |
| 2 | CREATE | Valid subtypes are Rostered, or Private |
| 3 | CREATE | There can be only one active client role. If there is an existing active client role for this party, reject the request with status code 409 |
| 4 | CREATE | Client and Talent roles are mutually exclusive. If the party already has an active Talent role, deactivate the talent role effective today, and activate the new client role effective today. |
| 5 | CREATE | If the client switches from Talent to Client per above, also deactivate any active IS_PURSUING relationships to Talent effective today. |
| 6 | CREATE | If the client came from a competitor agency, create an active CAME_FROM relationship to the appropriate :Party node with an active HAS_ROLE relationship to :Role { name: "Agency" } (CAA, Endeavour, etc). Review the rules for CAME_FROM for more details. |
| 7 | UPDATE | Updates are limited to activation and deactivation of the relationships; otherwise, rejected. |
| 8 | DELETE | A DELETE operation represents terminating our representation of the client, which usually means they have left the agency. If the relationship is active, deactivate it effective today. If the relationship is already inactive, reject the request with status code 409. |
| 9 | DELETE | If an active relationship is being deactivated, create a DEPARTED_TO relationship to the appropriate :Party node with an active HAS_ROLE relationship to :Role { name: "Agency" } (CAA, Endeavour, etc). Review the rules for DEPARTED_TO for more details. |
| 10 | DELETE | If an active client relationship is being deactivated, also deactivate any REPPED_AS relationships to :RepAreas effective today. |
| 11 | DELETE | If an active client relationship is being deactivated, also deactivate any ON_TEAM_FOR relationships to employee parties, effective today. |
| 12 | DELETE | If an active client relationship is being deactivated, create a relationship to :Role { name: “Talent”} to indicate their new relationship to the agency, which is now a potential client. The relationship is effective today. |
| 12 | DELETE | TODO Check for any other relationships connected directly to client |
CAN PARTIES WITH ACTIVE EMPLOYEE ROLES BE CLIENTS?
Yes. It is not common, but it does happen that an agency client is also an employee in the HR systems. For example, an agency employee might be sought after as a speaker, and the agency books that employee for the engagement. In this case, the employee shall have an active HAS_ROLE relationship to both Employee and Client.
Buyer
Buyer - Brand
Buyer - Distributor
Buyer - Financier
Buyer - MP Studio
Buyer - TV Studio
Buyer - Network
Talent
TODO: DISAMBIGUATING TALENT
It will not be uncommon in talent to have duplicate names. The disambiguator is usually the kind of work the talent does. Right now in the model I do not tie the talent to what UTA calls "vocation" (I've been mustly concerned with RepAreas) so we may need to add vocation back in here.
| # | Operation | Rule |
|---|---|---|
| 1 | CREATE | The party can be a person or an organization. |
| 2 | CREATE | Client and Talent roles are mutually exclusive. Reject if the party has a Client role. |
| 3 | CREATE | There can be only one active talent role. If there is an existing active talent role for this party, reject the request with status code 409 |
| 4 | CREATE |
Employee
The employee role is a special case, because UTA authoritative data is not the system of record for employees but rather a system of reference.
Agency
| # | Operation | Rule |
|---|
Contact
| # | Operation | Rule |
|---|
External
| # | Operation | Rule |
|---|
Examples
MATCH (p:Party {id :$id })
- [rel:HAS_ROLE]
-> (role:Role)
RETURN p{.*},
collect( {
relId: elementId(rel),
name: role.name,
active: rel.active
}) AS rolesMATCH (client:Party { id: $id })
MATCH (role: Role { name: "Client" })
MERGE (party)-[rel:HAS_ROLE {
active: true,
private: false,
fromDate: date()
}]->(role)
RETURN p{.*},
type(rel) as relationship,
role.name as roleMATCH (employee:Party { id: $id })
- [rel:IS_SUPERVISOR_OF { active: true } ]
-> (directs:Party)
RETURN directs{.*}MATCH (employee:Party { id: $id })
<- [rel:IS_SUPERVISOR_OF { active: true } ]
- (supervisors:Party)
RETURN supervisors{.*}