Skip to content

ATS-PFM-MTD-018Maintain Dated Links Between Records: Capability Test Specification

Markdown

ATS-PFM-MTD-018

Maintain Dated Links Between Records: Capability Test Specification

Markdown
  • DocumentProposed

KindAcceptance test setProduct areaPlatformModuleMetadata and Organization-defined RecordsRevision2

Read atservices-platform ad3f6a65react-console baf6dae3

Coverage

  • Rule gap: FND-PFM-MTD-080
  • Transition covered
  • Validation covered
  • Permission covered
  • Edge gap: FND-PFM-MTD-080
  • Failure covered
  • Boundary covered
  • Concurrency covered
  • Invariant covered
  • Interaction covered

Test Scenarios

13 scenarios proving CAP-PFM-MTD-018; 11 bound to an existing test.

01 Creating links validates both endpointsvalidationapinegativetest
Proves
BR-CAP-PFM-MTD-018-01
Preconditions
Registered types and compatible records exist.
Steps
[ { "do": "Use an unknown type, missing or foreign endpoint, self-link and a route-supplied endpoint.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses a record associated with itself" } ]
Expected
Invalid cases fail and the route-supplied counterpart creates a valid link.
Data
Registered types and compatible records exist.
Bound to
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses a record of another tenant, which the tenant policy never lets the seam see
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#creates the association with the path’s contact as its from side, without the write path’s keys
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses a record associated with itself
02 Future endings retain the occupied placeboundarybrowsernegativetest
Proves
BR-CAP-PFM-MTD-018-02 BR-CAP-PFM-MTD-018-03
Preconditions
A charter occupies Osprey until a future date.
Steps
[ { "do": "Book overlaps from today and the inclusive end date, then an adjacent booking and inspect after expiry.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses a second link of a one-place type that starts today, naming the link whose end date has not passed" } ]
Expected
Overlaps fail, the adjacent span succeeds and the current place becomes free after the end date.
Data
A charter occupies Osprey until a future date.
Bound to
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses a second link of a one-place type that starts today, naming the link whose end date has not passed
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S06.spec.ts#PLAT-M6-S06: a charter ending next month still holds Osprey and a second charter from today is refused naming the first
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses a second link of a one-place type that starts today, naming the link whose end date has not passed
03 Overlapping spans cannot share restricted placesinvariantbrowsernegativetest
Proves
BR-CAP-PFM-MTD-018-03 INV-DOM-PFM-MTD-006-04
Preconditions
Pair, cardinality and primary fixtures contain existing links.
Steps
[ { "do": "Add overlapping, adjacent, unbounded and competing primary links through API and console.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses a second link of one pair whose dates overlap the first, leaving the first alone" } ]
Expected
Conflicts identify the existing place, adjacent spans succeed and the console saves no conflicting insurer.
Data
Pair, cardinality and primary fixtures contain existing links.
Bound to
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses a second link of one pair whose dates overlap the first, leaving the first alone
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#reads a null start as from the beginning: an undated link overlaps one that ended in the past
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses a second open owner of a one-to-many type’s to record, naming it
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses two primaries of one from record whose dates overlap, and allows them when the dates do not
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S04.spec.ts#PLAT-M6-S04: a second insurer for Osprey is refused naming the first, and nothing is saved
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses a second link of one pair whose dates overlap the first, leaving the first alone
04 Concurrent occupancy remains exclusiveconcurrencyapinegativetest
Proves
BR-CAP-PFM-MTD-018-04 INV-DOM-PFM-MTD-006-05
Preconditions
A one-place relationship exists.
Steps
[ { "do": "Race overlapping creates and separately race adjacent spans.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses one of two writers of overlapping links of one pair, as a refusal and not a database error" } ]
Expected
Only one conflicting writer succeeds while adjacent writers can both succeed.
Data
A one-place relationship exists.
Bound to
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses one of two writers of overlapping links of one pair, as a refusal and not a database error
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses one of two writers of overlapping links of one pair, as a refusal and not a database error
05 Dates and primary flags depend on the typevalidationapinegativetest
Proves
BR-CAP-PFM-MTD-018-05
Preconditions
Dated and undated types vary in primary support.
Steps
[ { "do": "Submit forbidden dates, a reversed span, an invalid calendar day and a forbidden primary.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an end before the start on a dated type" } ]
Expected
Every unsupported input fails.
Data
Dated and undated types vary in primary support.
Bound to
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an end before the start on a dated type
06 Link correction cannot replace endpointsinvariantapinegativetest
Proves
BR-CAP-PFM-MTD-018-06 INV-DOM-PFM-MTD-006-06
Preconditions
A stored link has a current version.
Steps
[ { "do": "Replace an endpoint, correct notes and repeat with a stale version.", "provenance": "test", "source": "services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a replacement that names another record" } ]
Expected
Endpoint replacement and stale changes fail while valid notes change.
Data
A stored link has a current version.
Bound to
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a replacement that names another record
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#replaces the notes of the association read back, at its version
Source
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a replacement that names another record
07 Ending uses valid dated spanstransitionbrowsernegativetest
Proves
BR-CAP-PFM-MTD-018-07
Preconditions
Open, expired and undated links exist.
Steps
[ { "do": "End with default or explicit days, an invalid earlier day, an expired link and an undated type.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an end before the association started, leaving it open" } ]
Expected
Valid dated endings are stored, invalid and unsupported endings fail, and ended links appear in historical browsing.
Data
Open, expired and undated links exist.
Bound to
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#ends an open association of a dated type today in the tenant’s zone when no day is given
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S05.spec.ts#PLAT-M6-S05: an ended crew place shows under Show Ended with its dates and a mistaken entry leaves no history
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an end before the association started, leaving it open
08 Removal distinguishes open and historical linkstransitionapitest
Proves
BR-CAP-PFM-MTD-018-08
Preconditions
Open dated, end-dated and undated links exist.
Steps
[ { "do": "Remove each link.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#removes a link that has an end date when it is deleted, correcting history, and ends one with none" } ]
Expected
The open dated link ends today and the other links are deleted.
Data
Open dated, end-dated and undated links exist.
Bound to
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#removes a link that has an end date when it is deleted, correcting history, and ends one with none
09 Link limits include historyboundaryapinegativetest
Proves
BR-CAP-PFM-MTD-018-09 INV-DOM-PFM-MTD-006-07
Preconditions
A record already holds one thousand links of a type.
Steps
[ { "do": "Create another link.", "provenance": "test", "source": "services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an association past the per-record limit of the type, writing nothing" } ]
Expected
Creation fails and historical links count toward the limit.
Data
A record already holds one thousand links of a type.
Bound to
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an association past the per-record limit of the type, writing nothing
services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#counts the links in force and the ended ones together against the per-record limit
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an association past the per-record limit of the type, writing nothing
10 Both endpoint pages show the connectioninteractionbrowsertest
Proves
BR-CAP-PFM-MTD-018-10
Preconditions
Contact, organization and custom-record relationships exist.
Steps
[ { "do": "List from both directions and refresh each relevant console page.", "provenance": "test", "source": "services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the organization’s path in the reverse direction, naming the contact" } ]
Expected
Directional labels and opposite names appear locally and another workspace sees none of the links.
Data
Contact, organization and custom-record relationships exist.
Bound to
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the organization’s path in the reverse direction, naming the contact
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the contact’s path in the forward direction, naming the organization
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists nothing of the tests tenant to a context of the other tenant, which the path cannot reach
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S03.spec.ts#PLAT-M6-S03: a registrar adds Tom as crew of Osprey and Tom's page lists Osprey after a refresh
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S10.spec.ts#PLAT-M6-S10: a boat and its mooring are linked and each page shows the other
Source
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the organization’s path in the reverse direction, naming the contact
11 Link actions respect staff tierspermissionbrowsernegativetest
Proves
BR-CAP-PFM-MTD-018-11
Preconditions
Standard, read-only and API reader contexts exist.
Steps
[ { "do": "Maintain links as the standard user and attempt those actions as readers.", "provenance": "test", "source": "react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a standard user links, ends and removes but has no Relationship Types screen, and a read-only colleague sees no actions" } ]
Expected
The standard user succeeds, reader cards lack actions and unauthorized API creation fails.
Data
Standard, read-only and API reader contexts exist.
Bound to
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a standard user links, ends and removes but has no Relationship Types screen, and a read-only colleague sees no actions
services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 403 to an association create by a caller who may only read
Source
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a standard user links, ends and removes but has no Relationship Types screen, and a read-only colleague sees no actions
12 Locks remain effective for retired typesfailureapinegativeproposed
Proves
BR-CAP-PFM-MTD-018-13
Preconditions
A deactivated type has locked and unlocked links.
Steps
[ { "do": "Edit and end an update-locked link, remove a locked link and maintain an unlocked one.", "provenance": "proposed", "source": "services-platform:modules/associations/services/persistence/associations.ts:updateAssociation" } ]
Expected
Locks refuse the protected operations and the unlocked existing link can still change.
Data
A deactivated type has locked and unlocked links.
Source
services-platform:modules/associations/services/persistence/associations.ts:updateAssociation
13 Ending a link changes deletion protection and evidenceinteractionapiproposed
Proves
BR-CAP-PFM-MTD-018-07 BR-CAP-PFM-MTD-014-05 BR-CAP-PFM-MTD-015-01 BR-CAP-PFM-MTD-019-01
Preconditions
A dated restricting link joins two custom records.
Steps
[ { "do": "End it on a past valid date, inspect both histories and its event, then delete an endpoint.", "provenance": "proposed", "source": [ "services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an end before the association started, leaving it open", "services-platform:docs/associations.md#7a. History", "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.events.integration.spec.js#publishes nothing when the transaction that wrote the record rolls back, in the ledger or the queue", "services-platform:modules/associations/tests/integration/db/apply-endpoint-deletion.integration.spec.js#answers what endpointDeletionOutcome says for an open association on the to side under restrict" ] } ]
Expected
Compare ended browsing, captured change and subsequent deletion outcome.
Data
A dated restricting link joins two custom records.
Source
services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses an end before the association started, leaving it open,services-platform:docs/associations.md#7a. History,services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.events.integration.spec.js#publishes nothing when the transaction that wrote the record rolls back, in the ledger or the queue,services-platform:modules/associations/tests/integration/db/apply-endpoint-deletion.integration.spec.js#answers what endpointDeletionOutcome says for an open association on the to side under restrict

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.