---
id: CAP-MBR-MEM-016
title: Let officers act for their members
feature: FEAT-MBR-MEM-06
product_area: membership
module: memberships
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: partially-observed
supersedes:
  - 'inventory:CAP-MBR-SEC-005'
  - 'inventory:CAP-MBR-SEC-007'
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-membership:README.md#2026-10-18 — Final acceptance'
  - 'services-membership:docs/migrations/scope/README.md'
purpose: >-
  Officers can keep their members' contact details current within the fields their role allows, renew and enrol
  members of their units, and see the money lines that concern their units.
outcomes:
  - Officers do the routine work of their chapter without staff help and without CRM-wide authority.
  - Money information is shown to an officer only for their own units.
concepts:
  - CON-MBR-MEM-001
  - CON-MBR-MEM-003
actors:
  - ACT-MBR-009
  - ACT-MBR-007
surfaces:
  - portal
  - console
  - api
permissions:
  - key: membership.member-contact.update
    where_checked: service
    scope: record
  - key: membership.terms.renew
    where_checked: service
    scope: record
  - key: membership.memberships.enroll
    where_checked: service
    scope: record
  - key: membership.members.read
    where_checked: service
    scope: record
rules:
  - id: BR-CAP-MBR-MEM-016-01
    statement: >-
      An officer changes a member's CRM contact only for a membership in scope and only in the fields allowed; every
      refused field is named at once and nothing is sent.
    kind: permission
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/integration/services/unit-scope.integration.spec.ts#refuses a
      field outside the list, field_not_allowed naming it, and sends nothing
    origin: none
  - id: BR-CAP-MBR-MEM-016-02
    statement: >-
      The allowed fields are the union of the lists of the roles that granted the key and reach the membership; a
      unit-scoped role with no list allows nothing, and a workspace-wide role with no list allows every field.
    kind: calculation
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/unit/unit-scope.spec.ts#unions the lists of two roles that reach the
      membership
    origin: none
  - id: BR-CAP-MBR-MEM-016-03
    statement: The contact change is made in CRM as the officer, never with CRM's own contact-update authority.
    kind: policy
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/integration/services/unit-scope.integration.spec.ts#passes an
      allowed field to CRM’s contact update as the officer
    origin: none
  - id: BR-CAP-MBR-MEM-016-04
    statement: >-
      An officer may order a renewal for a membership in scope, members in grace included whatever the roster rule,
      with the package named or else the latest term's renewal package.
    kind: permission
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/integration/services/unit-scope.integration.spec.ts#places the
      Atlanta officer’s renewal of Gil, in grace, with the officer as acting user
    origin: none
  - id: BR-CAP-MBR-MEM-016-05
    statement: >-
      An officer may enrol a new member only when every unit of the new membership is in their scope, and must name at
      least one unit; staff may enrol a member with none.
    kind: permission
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/unit/unit-scope.spec.ts#refuses an officer an enrolment of no unit,
      which is National’s
    origin: none
  - id: BR-CAP-MBR-MEM-016-06
    statement: >-
      Officer orders are prepared through Membership's own checkout preparation with the officer as acting user and the
      member as recipient, and placed through Commerce; the request identifier makes a retried request name the same
      order, and a refused preparation is answered with its reason.
    kind: policy
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: 'services-membership:tests/acceptance/security/MBR-ACC-0465.acceptance.ts#MBR-ACC-0465'
    origin: none
  - id: BR-CAP-MBR-MEM-016-07
    statement: >-
      The financial summary shows an officer a dues line only when the affiliation that carries it is in scope, and a
      package line only through the membership's identity unit; a package line of a membership with no unit is shown to
      staff only.
    kind: permission
    enforced_at: [service]
    must_prove: true
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/integration/services/unit-scope.integration.spec.ts#shows a
      National-scoped officer both dues lines and never the national package line
    origin: none
  - id: BR-CAP-MBR-MEM-016-08
    statement: >-
      The financial summary answers a membership's terms even when Commerce's order lines cannot be read.
    kind: policy
    enforced_at: [service]
    must_prove: true
    provenance: unknown
    source: FND-MBR-MEM-055
    origin: none
  - id: BR-CAP-MBR-MEM-016-09
    statement: >-
      An enrolment into a program bound to an identity unit checks that the unit is an active unit of the program's
      identity unit type.
    kind: validation
    enforced_at: [service]
    must_prove: true
    provenance: unknown
    source: FND-MBR-MEM-054
    origin: none
scenarios:
  - id: SC-CAP-MBR-MEM-016-01
    given: Dana's officer role allows the e-mail address but not the date of birth.
    when: Dana changes Jo's e-mail address and then her date of birth.
    then: The e-mail change reaches CRM as Dana; the date of birth is refused, naming the field.
    provenance: test
    source: 'services-membership:tests/e2e/s07-regional-officer.e2e.spec.ts#refuses a date of birth 403 field_not_allowed, naming the field'
  - id: SC-CAP-MBR-MEM-016-02
    given: Jo holds Atlanta and Savannah dues lines and a national package line; Lee is Atlanta's officer.
    when: Lee and a staff member read Jo's financial summary.
    then: Lee sees the Atlanta dues line only; staff see every line.
    provenance: test
    source: 'services-membership:tests/e2e/s08-cross-chapter-restrictions.e2e.spec.ts#shows Lee only the Atlanta dues line of Jo’s financial summary'
edge_cases: []
constraints: []
depends_on:
  - CAP-MBR-MEM-015
  - CAP-MBR-MEM-009
related: []
journeys:
  - JNY-MBR-MEM-005
open_questions: []
evidence:
  - repository: services-membership
    source_sha: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
    paths:
      - modules/memberships/services/access/member-contact.ts
      - modules/memberships/services/operations/officer-orders.ts
      - modules/memberships/services/reads/financial-summary.ts
      - modules/memberships/ports/order-lines.ts
      - modules/memberships/ports/crm-contacts.ts
      - modules/memberships/tests/unit/unit-scope.spec.ts
      - modules/memberships/tests/integration/services/unit-scope.integration.spec.ts
      - tests/e2e/s07-regional-officer.e2e.spec.ts
      - tests/e2e/s08-cross-chapter-restrictions.e2e.spec.ts
      - tests/acceptance/security
  - repository: react-console
    source_sha: baf6dae382d6f41dce976c7f848667ccc37e076f
    paths:
      - acceptance/membership/reports/defects/security.md
      - acceptance/membership/reports/defects/data-operations.md
controls: [TC-AVL-002, TC-AVL-003, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-007, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PRV-001, TC-PRV-002, TC-SEC-001, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004]
---

# Let officers act for their members

## Purpose

Officers do much of a chapter's routine work: correcting a member's e-mail address, renewing a member who forgot, signing up a new member at a meeting, and checking who paid chapter dues. They need to do this within their units without holding CRM-wide or Accounting authority.

## How It Works

An officer changes a member's contact details through Membership rather than through CRM. Each officer role has a list of contact fields it may change, set by the workspace. A change is allowed only for a member in scope and only in fields the officer's roles allow together. Any other field is refused by name and nothing is sent. Staff roles without a list may change every field. An officer may order a renewal for a member in scope, including one in grace, and may enrol a new member into units they cover. These orders are prepared exactly as a checkout would prepare them, with the officer as the acting user, and placed through Commerce. A retried request names the same order. The financial summary shows an officer only the dues lines of their units, and never the national package line. Today the CRM change, the orders and the summary all reach ports that are not connected, so in a deployed workspace they fail. The product should show the summary's terms even without order lines, and should check an enrolment's identity unit.

## Relationships

- Depends on `CAP-MBR-MEM-015` because every action is confined to the officer's scope.
- Depends on `CAP-MBR-MEM-009` because officer orders are prepared through the checkout preparation.
- Depends on CRM Entities (`MOD-CRM-ENT`) for the contact update, and on Commerce orders (`MOD-COM-ORD`) for placement and order lines.
