Skip to content

ATS-PFM-MTD-012Maintain Valid Custom Records: Capability Test Specification

Markdown

ATS-PFM-MTD-012

Maintain Valid Custom Records: Capability Test Specification

Markdown
  • DocumentProposed

KindAcceptance test setProduct areaPlatformModuleMetadata and Organization-defined RecordsRevision2

Read atservices-platform ad3f6a65react-console baf6dae3

Coverage

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

Test Scenarios

19 scenarios proving CAP-PFM-MTD-012; 15 bound to an existing test.

01 Object status gates record writestransitionapinegativetest
Proves
BR-CAP-PFM-MTD-012-01 INV-DOM-PFM-MTD-005-01
Preconditions
Draft and archived objects and retained records exist.
Steps
[ { "do": "Attempt draft creation, read an archived-object record and perform each write action on it.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#refuses every write of it with 409 and changes nothing" } ]
Expected
Creation and writes fail while identity reads remain available.
Data
Draft and archived objects and retained records exist.
Bound to
services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#reads the record by id with its properties and an empty association list
Source
services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#refuses every write of it with 409 and changes nothing
02 Property errors are specific and discreetvalidationapinegativetest
Proves
BR-CAP-PFM-MTD-012-02 INV-DOM-PFM-MTD-005-02
Preconditions
An active object has typed properties.
Steps
[ { "do": "Submit invalid, unknown and archived properties.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names the object’s label in that refusal, never \"custom records\" (D4)" } ]
Expected
Refusals identify the property and object label without echoing rejected values.
Data
An active object has typed properties.
Bound to
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names the object’s label in that refusal, never "custom records" (D4)
03 Required values cannot be omitted or clearedvalidationapinegativetest
Proves
BR-CAP-PFM-MTD-012-03
Preconditions
A property is API-required.
Steps
[ { "do": "Create without it and clear it on update.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a record without a property required by the API" } ]
Expected
Both writes fail.
Data
A property is API-required.
Bound to
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a record without a property required by the API
04 Conditional rules evaluate resulting valuesrulebrowsernegativetest
Proves
BR-CAP-PFM-MTD-012-04
Preconditions
Insured and survey fields have conditional rules.
Steps
[ { "do": "Save an insured boat without its survey date, save an unrequired case and submit a hidden value.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a sail area on a vessel that is not a sloop, the property being hidden" } ]
Expected
The unmet requirement and changed hidden value fail; the optional case succeeds.
Data
Insured and survey fields have conditional rules.
Bound to
services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#never hides a property whose visible_when cannot be decided
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S04.spec.ts#PLAT-M5-S04: Survey Due is required only when Insured is ticked
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a sail area on a vessel that is not a sloop, the property being hidden
05 Creation fills compatible defaultsruleapitest
Proves
BR-CAP-PFM-MTD-012-05
Preconditions
Date and text properties have defaults.
Steps
[ { "do": "Create with omitted values, supplied values and blank inputs.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#defaults a date to the tenant’s today, and a text to its literal" } ]
Expected
Defaults fill absent information while explicit valid values prevail.
Data
Date and text properties have defaults.
Bound to
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#defaults a date to the tenant’s today, and a text to its literal
06 References identify records of the correct typevalidationapinegativetest
Proves
BR-CAP-PFM-MTD-012-06 INV-DOM-PFM-MTD-005-04
Preconditions
Contact and custom-object references exist.
Steps
[ { "do": "Reference missing, foreign, wrong-object and archived targets.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a manufacturer that is a boat" } ]
Expected
Invalid targets are refused while compatible existing targets succeed.
Data
Contact and custom-object references exist.
Bound to
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a manufacturer that is a boat
07 Unique values are normalized and releasedinvariantbrowsernegativetest
Proves
BR-CAP-PFM-MTD-012-07 INV-DOM-PFM-MTD-005-03
Preconditions
One record already reserves its Hull Number.
Steps
[ { "do": "Submit the same normalized text on another record, change the holder and try the released value.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a hull number another boat holds, naming the property and the boat" } ]
Expected
The duplicate fails without a save; the changed value releases the old reservation.
Data
One record already reserves its Hull Number.
Bound to
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S05.spec.ts#PLAT-M5-S05: a duplicate Hull Number is refused, naming Hull Number, and nothing is saved
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a hull number another boat holds, naming the property and the boat
08 Naming properties remain single-lineboundaryapinegativetest
Proves
BR-CAP-PFM-MTD-012-08
Preconditions
Primary and secondary naming properties are configured.
Steps
[ { "do": "Submit an internal line break, boundary line breaks and a multiline unrelated value.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a create whose secondary display property holds one, naming the property, and writes no record" } ]
Expected
Internal naming breaks fail, boundaries are trimmed and unrelated multiline information survives.
Data
Primary and secondary naming properties are configured.
Bound to
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a create whose secondary display property holds one, naming the property, and writes no record
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a create whose secondary display property holds one, naming the property, and writes no record
09 Names and numbers are derived consistentlyruleunittest
Proves
BR-CAP-PFM-MTD-012-09
Preconditions
An object has primary and secondary naming fields and a prefix.
Steps
[ { "do": "Create records with populated and absent naming values and oversized names.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#is the number with the object’s prefix when the display property holds nothing" } ]
Expected
Names combine available components or the prefixed number and are bounded without splitting a character.
Data
An object has primary and secondary naming fields and a prefix.
Bound to
services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#is the display property followed by the secondary properties in parentheses
services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#is the number with the object’s prefix when the display property holds nothing
Source
services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#is the number with the object’s prefix when the display property holds nothing
10 Patch and replacement have different omission semanticsruleapitest
Proves
BR-CAP-PFM-MTD-012-10
Preconditions
A record contains several properties.
Steps
[ { "do": "Patch one value, clear another with null and replace with an incomplete property map.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#clears every property a replacement leaves out" } ]
Expected
Patches retain omitted properties and replacement clears omitted live properties.
Data
A record contains several properties.
Bound to
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#clears every property a replacement leaves out
11 Concurrent editors receive a recoverable conflictconcurrencybrowsernegativetest
Proves
BR-CAP-PFM-MTD-012-11 INV-DOM-PFM-MTD-005-07
Preconditions
Two registrars open one boat version.
Steps
[ { "do": "Save the first edit and submit the second stale edit, then try an update-locked record.", "provenance": "test", "source": "react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S06.spec.ts#PLAT-M5-S06: two registrars edit one boat; the second is told and nothing is lost" } ]
Expected
The stale and locked edits fail without overwriting the committed record, and the console retains the unsaved work.
Data
Two registrars open one boat version.
Bound to
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S06.spec.ts#PLAT-M5-S06: two registrars edit one boat; the second is told and nothing is lost
Source
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S06.spec.ts#PLAT-M5-S06: two registrars edit one boat; the second is told and nothing is lost
12 External identities cannot collideinvariantapinegativetest
Proves
BR-CAP-PFM-MTD-012-12 INV-DOM-PFM-MTD-005-12
Preconditions
A record holds an external identifier.
Steps
[ { "do": "Create or patch another record to the same identifier.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a create under an external id another record of the object holds, naming sys_external_id" } ]
Expected
Both requests fail and identify the external-identifier conflict.
Data
A record holds an external identifier.
Bound to
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a create under an external id another record of the object holds, naming sys_external_id
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a patch to an external id another record of the object holds, and leaves the record unchanged
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses a create under an external id another record of the object holds, naming sys_external_id
13 Files are prepared before the record mutationinteractionapinegativetest
Proves
BR-CAP-PFM-MTD-012-13 INV-DOM-PFM-MTD-005-06
Preconditions
Image and document properties are configured.
Steps
[ { "do": "Save valid file sources and attempt missing or unsavable sources.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names a create’s missing upload at properties.<key>, without the address sent" } ]
Expected
Valid files are managed in the record folder; failures identify the property without revealing the address.
Data
Image and document properties are configured.
Bound to
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#copies an uploaded image into the record’s custom-objects folder and stores its permanent reference
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names a reference outside the file store at properties.<key>, without the address sent
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names a create’s missing upload at properties.<key>, without the address sent
14 Lists, reads and audits follow record contractsruleapitest
Proves
BR-CAP-PFM-MTD-012-14 INV-DOM-PFM-MTD-005-11
Preconditions
Records span publication and archive states.
Steps
[ { "do": "List with filters and limits, read a record and create or edit records.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#audits the read of a record as a view" } ]
Expected
Lists contain appropriate ordered pages, reads include links and view audits, and mutation audits disclose actions rather than values.
Data
Records span publication and archive states.
Bound to
services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#lists the unarchived boats by display name, a page with its cursor
Source
services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#audits the read of a record as a view
15 Untouched hidden values are retainededgeapiproposed
Proves
BR-CAP-PFM-MTD-012-04
Preconditions
A stored value has a conditional visibility driver.
Steps
[ { "do": "Patch only the driver to hide the property.", "provenance": "proposed", "source": "services-platform:modules/custom-objects/services/persistence/custom-object-records.ts:requireRecordRules" } ]
Expected
The save retains the untouched value.
Data
A stored value has a conditional visibility driver.
Source
services-platform:modules/custom-objects/services/persistence/custom-object-records.ts:requireRecordRules
16 An active object permits deletion of an archived recordtransitionapiproposed
Proves
BR-CAP-PFM-MTD-012-11
Preconditions
An archived record is unlocked and has no restricting links.
Steps
[ { "do": "Delete it using its current version.", "provenance": "proposed", "source": "services-platform:modules/custom-objects/services/persistence/custom-object-records.ts:deleteRecord" } ]
Expected
The record is removed despite its archive state.
Data
An archived record is unlocked and has no restricting links.
Source
services-platform:modules/custom-objects/services/persistence/custom-object-records.ts:deleteRecord
17 Scaled numeric storage respects safe precisionboundaryapitest
Proves
BR-CAP-PFM-MTD-012-15
Preconditions
Numeric definitions specify precision.
Steps
[ { "do": "Store a decimal and evaluate a value beyond safe scaled range.", "provenance": "test", "source": "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#stores a decimal with its scaled integer shadow" } ]
Expected
The decimal stores its exact integer shadow and the unsafe result produces no shadow.
Data
Numeric definitions specify precision.
Bound to
services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#is null for a value whose scaled form is beyond a safe integer
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#stores a decimal with its scaled integer shadow
18 Saving a prepared record precedes owner-link effectsinteractionapiproposed
Proves
BR-CAP-PFM-MTD-012-13 BR-CAP-PFM-MTD-014-01 BR-CAP-PFM-MTD-015-01 BR-CAP-PFM-MTD-018-01
Preconditions
An active object has a file property, a conditional rule and an owner type.
Steps
[ { "do": "Prepare a file, save valid properties, create the owner link, inspect record history and events, then reject a conditional-property save.", "provenance": "proposed", "source": [ "services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names a create’s missing upload at properties.<key>, without the address sent", "services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers the association, the update and the creation, newest first", "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/services/persistence/associations.integration.spec.js#refuses a record associated with itself" ] } ]
Expected
Compare committed record and link effects with the rejected save’s unchanged history and event counts.
Data
An active object has a file property, a conditional rule and an owner type.
Source
services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#names a create’s missing upload at properties.<key>, without the address sent,services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers the association, the update and the creation, newest first,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/services/persistence/associations.integration.spec.js#refuses a record associated with itself
19 A failed owner change preserves the earlier content savefailurebrowsernegativeproposed
Proves
BR-CAP-PFM-MTD-012-10 BR-CAP-PFM-MTD-018-01
Preconditions
A saved boat has an owner and an editable property.
Steps
[ { "do": "Save a model correction, allow removal of the previous owner link, refuse the new owner link and reload the boat.", "provenance": "proposed", "source": "specs/platform/metadata/design/workflows/WF-PFM-MTD-006-change-a-custom-record-s-owner-after-its-save.md:hops" } ]
Expected
The corrected model remains saved and the owner replacement has not completed; retry uses the current content and link state.
Data
A saved boat has an owner and an editable property.
Source
specs/platform/metadata/design/workflows/WF-PFM-MTD-006-change-a-custom-record-s-owner-after-its-save.md:hops

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.