Skip to content

CAP-CRM-ACT-001Log one interaction for all related people and organizations

Markdown

CAP-CRM-ACT-001

Log one interaction for all related people and organizations

Markdown
  • DocumentDraft
  • Product intentProposed
  • ImplementationObserved

KindCapabilityProduct areaCRMModuleActivities, Follow-ups and Task WorkRevision2

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
A shared account of the interactionDetails suited to the activity typeNo duplicate entry after a retried create
Surfaces
consoleapijob
Preconditions
At least one activity type is active in the workspace.All selected contacts and organizations belong to this workspace.
Postconditions
Activity details and links commit together or are rolled back together.
Intent sources
services-crm:docs/milestones/CRM-M8-activities-and-tasks.md#D-43services-crm:docs/milestones/CRM-M8-activities-and-tasks.md#D-50services-crm:docs/milestones/CRM-M8-activities-and-tasks.md#D-51R2-ARCH-001 D1 (Andrew 2026-10-19), recorded at services-crm:docs/migrations/activities/README.md#9. Decisions

Controls

18 controls apply, from the corpus control catalogue.

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

Permissions

KeyChecked atScope
crm.activities.createapitenant
crm.activities.createconsoletenant

Business Rules

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

IdRuleKindEnforced atProvenance
01must prove
Proposed
An activity links between one and 200 distinct workspace records, and each link identifies either a contact or an organization.
✓ A meeting involving two contacts and their organization saves as one activity.✗ A single link identifying a contact and an organization fails validation.
no proof recorded yet
validationapi, service, databasetest
02must prove
Confirmed
Only one link can be primary; if none is selected, Rhythm makes the first link primary.
no proof recorded yet
policyservice, databasetest
03must prove
Proposed
Creating an activity requires an active activity type from the same workspace.
no proof recorded yet
validationservicetest
04must prove
Proposed
Field modes control hidden and required details, with required duration and outcome checked only on completion and hidden attendees still permitted as links.
no proof recorded yet
validationconsole, serviceobserved
05must prove
Proposed
An activity type that requires attendees needs a linked contact other than the primary record.
no proof recorded yet
validationconsole, servicetest
services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#asks for an attendee besides the primary record when the type requires attendees
06must prove
Proposed
A newly selected outcome must be active and belong to the selected activity type, with the type relationship also checked in storage.
no proof recorded yet
validationservice, databasetest
07must prove
Proposed
The end cannot precede the start, duration must be between zero and 1,440 minutes, and the subject cannot exceed 500 characters; refusals identify the affected field.
no proof recorded yet
validationservice, databasetest
08must prove
Proposed
Rhythm cleans formatted notes of scripts, styles, frames, event handlers and unsafe links, treats content reduced to nothing as empty, and limits the result to 100,000 characters.
no proof recorded yet
calculationservice, databasetest
09must prove
Proposed
A new activity defaults to the current time, its type’s initial status and visible default duration, and the signed-in user as owner.
no proof recorded yet
calculationservicetest
services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#defaults the status, the time and the owner from the type, the clock and the caller
10
Confirmed
Ownership is optional and remains separate from creation and modification attribution.
policyconsole, servicetest
react-console:lib/activities/form-rules.test.ts#does not ask for an owner: an activity may have none (D-51)
11must prove
Confirmed
Repeating an identical create under the same client-selected identifier returns the existing activity, while different content under that identifier causes a conflict.
no proof recorded yet
invariantservice, databasetest
12must prove
Proposed
Rhythm supplies the activity’s origin, and an imported external reference must be unique within its workspace.
no proof recorded yet
invariantservice, databasetest
13must prove
Proposed
Activity saves reject custom field values because activities do not support custom fields.
origin: R2-ARCH-001 D1 (Andrew 2026-10-19), recorded at services-crm:docs/migrations/activities/README.md#9. Decisions
no proof recorded yet
validationapitest
services-crm:modules/activities/tests/e2e/activities.e2e.spec.js#refuses a custom field value, an activity having no custom fields (R2-ARCH-001): 400 naming custom_fields
14
Proposed
For a future-dated new activity, the console selects Scheduled unless the user already chose a status; editing preserves the saved status.
policyconsoletest
15must prove
Proposed
A field-mode refusal reports the detected field problems together, and a rejected transaction keeps neither its activity nor its follow-up.
no proof recorded yet
invariantserviceobserved
16must prove
Proposed
Hiding the attendee control leaves additional contact links valid.
no proof recorded yet
validationservicetest
services-crm:modules/activities/tests/unit/services/activities/field-modes.spec.js#refuses nothing about the links when attendees are hidden
17must prove
Proposed
A user create replaces absent or empty ownership with the caller, while a subsequent edit can retain empty ownership.
no proof recorded yet
calculationserviceobserved

Scenarios

IdGivenWhenThenProvenance
01The coordinator opens a member record with Meeting available.Record a meeting linked to the member, an attending colleague and that colleague’s organization.The same meeting appears on all three timelines with the member primary.test
02Call requires direction and an outcome for completed work.Submit a completed call with both details missing.The refusal identifies both fields and leaves no saved call.test

Edge Cases

IdGivenWhenThenProvenance
03The browser receives no answer to an activity create.Retry the identical create from the console.Rhythm returns the existing activity without another entry.test
react-console:lib/activities/retry-safe-writes.test.ts#answers a lost response with the activity it logged, and logs no second one

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.