---
id: CAP-MBR-STR-010
title: Set a program’s affiliation requirements
feature: FEAT-MBR-STR-03
product_area: membership
module: structure
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes:
  - react-console acceptance inventory CAP-MBR-CFG-002
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources: []
purpose: Staff describe the categories and numbers of units associated with an affiliation-bound program.
outcomes:
  - Program unit requirements express the intended affiliation structure.
  - Removing a category respects retained affiliations that still use it.
concepts:
  - CON-MBR-STR-003
actors:
  - ACT-MBR-001
surfaces:
  - api
preconditions: []
postconditions: []
permissions:
  - key: membership.programs.manage
    where_checked: api
    scope: tenant
  - key: membership.programs.read
    where_checked: api
    scope: tenant
  - key: membership.application.access
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-MBR-STR-010-01
    statement: >-
      Replacing program unit requirements saves the complete list at the program’s version and advances that
      version.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf
    origin: none
  - id: BR-CAP-MBR-STR-010-02
    statement: >-
      A nonempty unit-kind list requires affiliation binding, while an empty replacement is permitted for
      other bindings.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf
    origin: none
  - id: BR-CAP-MBR-STR-010-03
    statement: >-
      Listed kinds must exist, allow member affiliations and appear once, with any maximum at least the
      minimum; validation reports all detected problems.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:unitTypeProblems
    origin: none
  - id: BR-CAP-MBR-STR-010-04
    statement: >-
      A kind cannot be removed while a non-cancelled program term has an affiliation of that kind with no end
      or an end on or after today.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:replaceProgramUnitTypesOf
    origin: none
  - id: BR-CAP-MBR-STR-010-05
    statement: >-
      Each category records primary-designation, portal-change and suggestion choices, but portal and
      suggestion choices have no implemented consumer.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: observed
    source: >-
      services-membership:modules/configuration/services/configuration/configuration-records.ts:programUnitTypesContent
    origin: none
  - id: BR-CAP-MBR-STR-010-06
    statement: Reducing a maximum does not automatically rewrite existing affiliations.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json'
    origin: none
scenarios:
  - id: SC-CAP-MBR-STR-010-01
    given: National membership permits up to three chapters and unrestricted sections.
    when: Staff replace the list with those two category requirements.
    then: The saved program returns the selected counts for both categories.
    provenance: test
    source: >-
      services-membership:tests/acceptance/configuration/MBR-ACC-0080.acceptance.ts#MBR-ACC-0080: An
      administrator builds an association's membership configuration from nothing and a first member is
      enrolled on it
edge_cases:
  - id: SC-CAP-MBR-STR-010-02
    given: Retained affiliations still use the chapter category.
    when: Staff remove chapters from the program requirements.
    then: Removal fails while the qualifying affiliations still depend on that category.
    provenance: documented
    source: 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json'
constraints: []
depends_on:
  - CAP-MBR-STR-009
  - CAP-MBR-STR-001
related:
  - CAP-MBR-STR-013
journeys:
  - JNY-MBR-STR-004
open_questions: []
evidence:
  - 'services-membership: Examination of the program unit-type replacement, its schema and route.'
  - >-
    services-membership: Examination of acceptance journeys MBR-ACC-0080, 0095 and 0096; react-console
    inventory CAP-MBR-CFG-002.
  - 'react-console:acceptance/membership/journeys/configuration/MBR-ACC-0096.json'
  - 'services-membership:modules/configuration/services/configuration/configuration-records.ts'
controls: [TC-AVL-002, TC-AVL-003, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, 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-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-PI-001, TC-PI-003, TC-SEC-001, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Set a program’s affiliation requirements

## Purpose

Staff describe the categories and numbers of units associated with an affiliation-bound program.

## How It Works

An administrator opens the program’s complete affiliation requirements. Each row names a kind of unit and the allowed count. Optional maximums distinguish bounded choices from unrestricted counts. Staff also record primary-designation and future portal behavior choices. The service checks the list for duplicate kinds, unavailable categories and contradictory counts. A nonempty list requires an affiliation-bound program. Saving replaces the complete list and advances the program’s version. Removing a kind can fail while retained affiliations still use it today or later. Lowering a maximum leaves existing affiliations untouched. Staff therefore need to assess current memberships as well as future enrolment choices. The product should explain which saved portal settings remain inactive.

## Relationships

- Programs supply the binding and version used by list replacement.
- Unit kinds identify the categories allowed in affiliations.
- Package-specific requirements can override counts for particular offerings.
