Skip to content

CAP-PFM-MTD-012Maintain Valid Custom Records

Markdown

CAP-PFM-MTD-012

Maintain Valid Custom Records

Markdown
  • DocumentDraft
  • Product intentConfirmed
  • ImplementationObserved

KindCapabilityProduct areaPlatformModuleMetadata and Organization-defined RecordsRevision1

Read atservices-platform ad3f6a65react-console baf6dae3

The Formal Contract

The narrative above explains; the sections below are authoritative — the rules, scenarios and tests this document binds.

Outcomes
Record keepers need to capture and correct the organization information without breaking its definitions.A rejected write identifies the field that needs attention without returning the rejected value.
Surfaces
consoleapi
Preconditions
Writes target an active object; identity reads can address records of other object states.
Postconditions
Record mutations leave transactional audits; individual API reads record a view.
Intent sources
services-platform:docs/milestones/PLAT-M5-custom-records.md#Scope (the record store), PLAT-M5 D3, D4, D5, D9, D17services-platform:docs/milestones/plans/PLAT-M5-plan.md#PLAT-M5-S03, S04, S05, S06services-platform:docs/proposals/custom-objects/09-decisions.md#D-01, D-02

Controls

29 controls apply, from the corpus control catalogue.

TC-AVL-005 TC-AZ-001 TC-AZ-002 TC-AZ-003 TC-AZ-004 TC-DAT-001 TC-DAT-003 TC-DAT-004 TC-IAM-001 TC-IAM-002 TC-IAM-004 TC-IAM-005 TC-LOG-002 TC-LOG-003 TC-LOG-004 TC-LOG-005 TC-MON-002 TC-PI-001 TC-PI-003 TC-PI-005 TC-PRV-001 TC-PRV-002 TC-TEN-001 TC-TEN-002 TC-TEN-003 TC-TEN-004 TC-VEN-001 TC-VEN-002 TC-VEN-003

Permissions

KeyChecked atScope
platform.custom-records.readapirecord
platform.custom-records.createapirecord
platform.custom-records.updateapirecord

Business Rules

15 rules, 15 to be proved before approval. A rule's product intent is derived from its origin: 15 confirmed by a product decision, the rest inheriting this capability's confirmed.

IdRuleKindEnforced atProvenance
01must prove
Confirmed
Record writes require an active object; records of draft or archived objects remain readable by identity with their links, reject writes and cannot be reached through another object path.
origin: services-platform:docs/milestones/PLAT-M5-custom-records.md#PLAT-M5 D3 (Andrew, 2026-10-19: readable, read-only)
lifecycleservicetest
02must prove
Confirmed
Property validation uses live definitions and typed conversion, names invalid or unavailable properties without disclosing rejected values and uses the object label in its refusal.
validationservicetest
03must prove
Confirmed
API-required properties need a value at creation and reject attempts to clear them.
validationservicetest
04must prove
Confirmed
Visibility validation rejects non-null submitted changes to hidden properties while retaining untouched stored values; conditional requirement checks resulting visible values, and unknown evaluations neither require nor hide.
validationservice, consoleobserved
05must prove
Confirmed
Creation fills omitted, empty or null properties from compatible defaults using literals, workspace dates or caller contact, while supplied values override defaults.
calculationservicetest
06must prove
Confirmed
References must resolve to a record of their target type in the workspace, with custom-object targets requiring unarchived records of the specified object.
validationservicetest
07must prove
Confirmed
Unique-property reservations reject duplicate values without saving, name the holder, normalize text case and surrounding whitespace and release a reservation when its value changes.
validationservice, database, consoletest
08must prove
Confirmed
Display properties reject internal line breaks by property name, trim boundary line breaks and leave unrelated properties unaffected.
origin: services-platform:docs/milestones/PLAT-M5-custom-records.md#PLAT-M5 D5 (Andrew, 2026-10-19: "Refuse, name the field")
validationservicetest
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
09must prove
Confirmed
Each save derives the name from the primary display value or prefixed record number plus populated secondary values, limits it to five hundred characters and assigns numbers from the object sequence.
origin: services-platform:docs/proposals/custom-objects/09-decisions.md#2. Choices taken as internal (record numbering, display name composition)
calculationservicetest
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
10must prove
Confirmed
Patches affect named properties and use null to clear them, while replacements clear omitted live properties and accept a complete record representation.
policyapi, servicetest
11must prove
Confirmed
Updates require the read version and respect update locks; archived records reject editing and publication but remain deletable when the object is active and deletion safeguards allow it.
validationservice, consoletest
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
12must prove
Confirmed
Caller-supplied external identifiers are unique within the object and reject conflicting creation or patch requests.
validationservice, databasetest
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
13must prove
Confirmed
New image and file values pass through managed asset preparation before saving, with unavailable or unsavable sources reported at the property without exposing the address.
validationservicetest
14must prove
Confirmed
Record lists default to unarchived entries ordered by name, offer bounded pages and publication, archive and prefix filters, while reads include grouped links and write view audits and mutations audit actions without values.
policyservicetest
15must prove
Confirmed
Decimal, currency and percent storage also records an exact precision-scaled integer, leaving that shadow empty when the value exceeds the supported safe integer range.
calculationservicetest
services-platform:modules/custom-objects/tests/unit/record-rules.spec.ts#is null for a value whose scaled form is beyond a safe integer

Scenarios

IdGivenWhenThenProvenance
01Boat is active with contact ownership configured.Create Miss Daisy for Jane Smith from its app.The first boat number appears in the Explorer and Jane Boats card.test
react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S03.spec.ts#PLAT-M5-S03: a registrar creates a boat owned by a contact: numbered 1, listed, and on the contact's Boats card
02A boat already reserves a unique hull number.Create another boat using the same text in different case with extra boundary spaces.The refusal identifies Hull Number and its existing holder without saving the duplicate.test

Edge Cases

IdGivenWhenThenProvenance
03A custom object includes an HTML property.Save markup in that property.The finding records an unresolved sanitization obligation in the storage path.unknown

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.