Skip to content

CAP-CRM-REG-008Keep placements aligned with address changes

Markdown

CAP-CRM-REG-008

Keep placements aligned with address changes

Markdown
  • DocumentDraft
  • Product intentProposed
  • ImplementationObserved

KindCapabilityProduct areaCRMModuleRegionsRevision2

Read atservices-crm a8d1364freact-console baf6dae3

The Formal Contract

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

Outcomes
Calculated placements follow deciding-address changes and clear when coverage is lost.Remembering an unchanged placement does not invalidate the user’s saved version.
Surfaces
job
Intent sources
services-crm:docs/migrations/crm-regions/README.md#2026-10-12 — Final acceptance (second pass), decision 2026-10-11: the region follows an address change after the save, through the change-event queueservices-crm:docs/migrations/crm-regions/README.md#Behaviour changes (Andrew's requirement for the port: replace or remove stale calculated assignments)services-crm:docs/migrations/crm-regions/README.md#2026-10-12 — Final acceptance (second pass), decision 2026-10-12: the assignment bumps a record's version only when its region changesservices-crm:docs/milestones/CRM-M1-contacts-and-organizations.plan.md#CRM-ACC-0023services-crm:docs/milestones/CRM-M1-contacts-and-organizations.plan.md#CRM-ACC-0058

Controls

19 controls apply, from the corpus control catalogue.

TC-DAT-001 TC-DAT-002 TC-DAT-003 TC-IAM-001 TC-IAM-005 TC-IAM-006 TC-LOG-005 TC-MON-001 TC-MON-002 TC-PI-001 TC-PI-002 TC-PI-003 TC-PI-004 TC-PI-005 TC-PRV-001 TC-PRV-002 TC-TEN-001 TC-TEN-002 TC-TEN-003

Business Rules

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

IdRuleKindEnforced atProvenance
01must prove
Proposed
Automatic placement follows a committed contact or organization save asynchronously, so a create response does not yet contain the calculated region.
origin: services-crm:docs/migrations/crm-regions/README.md#2026-10-12 — Final acceptance (second pass), decision 2026-10-11: the region follows an address change after the save, through the change-event queue
no proof recorded yet
policyservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#initial assignment › answers no region from the create itself, because the assignment is a reaction to the committed save
02must prove
Confirmed
Changing a deciding address into another rule’s area changes the record to that rule’s region.
no proof recorded yet
calculationservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#moving › moves a contact from region A to region B when its address moves
03must prove
Proposed
Removing a previously deciding address or moving it outside all matching coverage clears the calculated region.
origin: services-crm:docs/migrations/crm-regions/README.md#Behaviour changes (Andrew's requirement for the port: replace or remove stale calculated assignments)
no proof recorded yet
policyservicetest
04must prove
Proposed
Editing an address outside the configured deciding source does not change regional placement.
no proof recorded yet
policyservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#moving › ignores a change to an address that does not decide the region
05must prove
Proposed
Placement uses the configured preferred or typed address and follows a newly preferred address when that source is selected.
no proof recorded yet
calculationservicetest
06must prove
Proposed
A record that has never had a deciding address retains a region supplied manually.
origin: services-crm:docs/migrations/crm-regions/README.md#Behaviour changes, Not changed (kept as Rhythm 1.0 did; accepted by Andrew 2026-10-08)
no proof recorded yet
policyservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#initial assignment › keeps a region the client sends with a contact that has no address (nothing decides it)
07must prove
Proposed
Assignment skips records locked against updates and treats records deleted before processing as successful work with nothing to change.
no proof recorded yet
policyserviceobserved
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-delivery.integration.spec.js#a record deleted while its event was in flight › succeeds with nothing to do, because a record that is gone has no region to decide; services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments
08must prove
Proposed
Processing reads current committed record state, making duplicate, late and out-of-order events converge on the same result without repeat writes.
origin: services-crm:docs/migrations/crm-regions/README.md#2026-10-12 — Final acceptance (second pass), decision 2026-10-11: the region follows an address change after the save, through the change-event queue
no proof recorded yet
invariantservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-delivery.integration.spec.js#two messages delivered out of order › ends in the region of the address the contact has now, not of the one the older message described
09must prove
Proposed
An assignment write does not trigger another assignment of its own.
no proof recorded yet
invariantservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-delivery.integration.spec.js#one delivery of one address change › is not called again by its own write, so an assignment cannot set off another
10must prove
Proposed
Assignment advances the version and modification stamp only when the region changes, preserving both when only the remembered address changes.
origin: services-crm:docs/migrations/crm-regions/README.md#2026-10-12 — Final acceptance (second pass), decision 2026-10-12: the assignment bumps a record's version only when its region changes
no proof recorded yet
policyservice, databasetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-delivery.integration.spec.js#a deciding-address change that leaves the region where it was › bumps no version, so the contact stands at the version its save answered
11must prove
Proposed
An organization address change reconciles linked contacts and can update their regions without writing their contact addresses.
no proof recorded yet
policyservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#a linked address (docs/affiliations/README.md §0b.3, the fan-out) › moves the linked contact when its organization’s address moves, though no contact row was written
12must prove
Proposed
Linked addresses supply placement only through effective affiliations, and affiliation expiry alone does not trigger regional reconciliation.
no proof recorded yet
policyserviceinferred
13must prove
Proposed
Failed assignment leaves placement unchanged and the queue can deliver the work again for successful processing.
no proof recorded yet
policyservicetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-delivery.integration.spec.js#a delivery that fails and is made again › assigns the region on the next delivery of the same message
14must prove
Proposed
Each workspace uses only its own policy, and missing settings disable placement.
no proof recorded yet
invariantservice, databasetest
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#tenant isolation, with rules on both sides › leaves a contact at that same address unassigned here, because the rule that covers it is the neighbour’s

Scenarios

IdGivenWhenThenProvenance
01Enabled rules cover a new member’s deciding address.The coordinator saves the contact and then reads it after processing.The calculated region appears after the create response.test
02A contact’s deciding address currently matches the first region.The address moves into another rule’s coverage.Placement changes to the second region with one assignment version increment.test
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#moving › moves a contact from region A to region B when its address moves

Edge Cases

IdGivenWhenThenProvenance
03A deciding-address edit stays within the current region.The coordinator submits another edit using the version returned by the first save.The unchanged placement introduces no additional version conflict.test
services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-delivery.integration.spec.js#a deciding-address change that leaves the region where it was › takes the next save sent with the version the save answered, which is no longer stale

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.