Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support both naturalKey and referenceKeys declared through DomainObjects #21

Open
uladkasach opened this issue Dec 15, 2022 · 1 comment

Comments

@uladkasach
Copy link
Member

it has become clear that for many valid domain objects we need to define more than one type of unique key:

  • most often, the naturalKey is the only uniqueKey which needs to be declared (this is what is currently supported)
  • however, often, one or more referenceKeys, which may be nullable and updatable, may also uniquely reference the domain object

we find the referenceKeys relevant most often when an external system also assigns a unique identifier to the entity which we want to track

  • this referenceKey does not naturally identify the entity (since it is arbitrarily assigned by an external system at some point in time) (hence it is not a naturalKey of the entity)
  • this referenceKey does uniquely identify the entity though (since each instance of a reference key is guaranteed to reference one and only one entity, when defined)

see below implementation and description

/**
 * the `DomainEntity.unique` property defines the keys upon which this entity is unique
 * - you must define the `natural key` of the domain entity
 * - you many optionally also define `reference keys` of the domain entity
 *
 * the `natural key`
 * - uniquely identifies the domain object based on its non-metadata properties
 * - this is required in order to identify distinct entities
 *   - this key must be defined for every entity
 *   - the values of this key must be present
 * - note
 *   - this may be a `uuid` if there are no keys upon which the entity is naturally unique on (unideal, but valid)
 *
 * the `reference key`
 * - when it exists, uniquely references a specific domain entity based on one its non-metadata properties
 * - this type of key
 *    - may not exist on a domain entity, it may not be relevant
 *    - may be nullable and updatable, starting with null until being instantiated at some point in the future  
 * - note
 *   - typically, these keys are properties known about the entity assigned by some external system to reference the entity
 *     - i.e.,
 *       - they uniquely reference the entity,
 *       - but the entity is not naturally identified by these properties
 *
 * for example
 * - a `GoogleAdsCampaign { account, name, googleReferenceName: string | null }` is likely unique `{ byNaturalKey: ['account', 'name'], byReferenceKeys: [['googleReferenceName']] }` since `account` and `name` are always present to identify it by, and `googleReferenceName` becomes a unique identifier for it once the campaign is created inside of the google-ads system
 * - an `InvaluableAuction { catalogRefId, catalogId, invoiceGroupId, name }` is likely unique `{ byNaturalKey: ['catalogRefId'], byReferenceKeys: [['catalogId'], ['invoiceGroupId' ]] }` since `catalogRefId` is always available, and `catalogId` and `invoiceGroupId` may or may not eventually be defined for it but are guaranteed to uniquely identify it once they are
 */
type unique = string[] | { byNaturalKey: string[], byReferenceKeys: string[] }
@uladkasach
Copy link
Member Author

note unique: { onNaturalKey, onReferenceKeys } is better than { byNaturalKey, byReferenceKeys } since

findByUnique -> [findByUniqueOnNaturalKey, findByUniqueOnReferenceKey]

otherwise it'd be a double by and be more confusing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant