Skip to content

CAP-MBR-STR-012Offer membership through an Accounting product

Markdown

CAP-MBR-STR-012

Offer membership through an Accounting product

Markdown
  • DocumentDraft
  • Product intentProposed
  • ImplementationObserved

KindCapabilityProduct areaMembershipModuleOrganizational Structure, Membership Configuration and TermsRevision1

Read atservices-membership 5994c270react-console baf6dae3

The Formal Contract

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

Outcomes
The offering has one shared product identity.Membership holds the term and renewal configuration needed for the offering.
Surfaces
apijob
Intent sources
services-membership:docs/migrations/packages-as-products/README.md#D-1 (Andrew, 2026-10-18: the package is the product)services-membership:docs/migrations/packages-as-products/README.md#D-2 (Andrew, 2026-10-18: the console saves the product through Accounting first, then the package)

Controls

36 controls apply, from the corpus control catalogue.

TC-AVL-002 TC-AVL-003 TC-AVL-004 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-004 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-PI-004 TC-PI-005 TC-SEC-001 TC-SEC-004 TC-TEN-001 TC-TEN-002 TC-TEN-003

Permissions

KeyChecked atScope
membership.configuration.readapitenant
membership.configuration.manageapitenant
membership.application.accessapitenant

Business Rules

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

IdRuleKindEnforced atProvenance
01must prove
Proposed
Package creation requires the identity of an existing Accounting membership-package product and refuses a missing identity, missing product or wrong product type.
origin: services-membership:docs/migrations/packages-as-products/README.md#D-2 (Andrew, 2026-10-18: the console saves the product through Accounting first, then the package)
no proof recorded yet
validationservicetest
services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a package whose product Accounting does not have, 400
02must prove
Proposed
Package writes reject shared product fields such as name, description, status and visibility, and reads obtain those fields from Accounting.
origin: services-membership:docs/migrations/packages-as-products/README.md#D-1 (Andrew, 2026-10-18: the package is the product)
no proof recorded yet
validationapi, servicetest
services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses the common fields a package no longer carries of its own (they are the product’s)
03must prove
Proposed
Package activity follows Accounting product activity, including the activity filter used by package lists.
origin: services-membership:docs/migrations/packages-as-products/README.md#D-1 (Andrew, 2026-10-18: the package is the product)
no proof recorded yet
calculationservicetest
services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › lists packages with the product’s fields and filters is_active by the product’s status
04must prove
Proposed
One Accounting product can have only one Membership package extension.
origin: services-membership:docs/migrations/packages-as-products/README.md#D-1 (Andrew, 2026-10-18: the package is the product)
no proof recorded yet
validationservice, databasetest
services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a second extension of the same product: the package id is the product id
05must prove
Proposed
Each package names a program and a membership type belonging to that program.
no proof recorded yet
validationdatabasetest
services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through the API › DEF-MBR-0086: a configuration write a check, a foreign key or an integer column refuses › refuses a package of a type of another program 400 naming membership_type_id, and writes no package nor unit rule
06must prove
Proposed
A default renewal target must be a different package within the same program.
no proof recorded yet
validationdatabasetest
services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through the API › DEF-MBR-0086: a configuration write a check, a foreign key or an integer column refuses › refuses a package renewing into itself 400 naming renews_into_package_id
07
Proposed
Package configuration includes renewal timing, continuation, auto-renew choice, reinstatement, seats and pricing hints, with Commerce responsible for amounts.
policyservicetest
services-membership:tests/acceptance/configuration/MBR-ACC-0115.acceptance.ts#MBR-ACC-0115: The renewal window and the reinstatement period decide what a member may buy, read live from the package: narrowing the window shuts an open renewal, widening the reinstatement period turns a rejoin back into a reinstatement, a blank period means no reinstatement at all, and the default renewal package is the one the configuration names
08must prove
Proposed
A referenced change policy set must exist in the workspace.
no proof recorded yet
validationdatabasetest
services-membership:tests/e2e/database-refusals.e2e.spec.ts#mistakes only the database catches, through the API › DEF-MBR-0086: a configuration write a check, a foreign key or an integer column refuses › refuses a change policy set that does not exist 400 naming change_policy_set_id
09must prove
Proposed
Package deletion removes the Membership extension while leaving its Accounting product in place.
no proof recorded yet
lifecycleserviceobserved
10must prove
Proposed
Package display order is returned as zero because the Accounting port has no product display order.
no proof recorded yet
calculationserviceobserved
11must prove
Proposed
Activity filtering follows each underlying package page, so even an empty filtered page can carry a continuation cursor.
no proof recorded yet
policyserviceobserved

Scenarios

IdGivenWhenThenProvenance
01Accounting already holds Regular Annual as a membership-package product.Staff extend it for the National program’s Regular classification.The offering returns the existing product’s shared information.test
services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › extends a product of type membership_package and answers the product’s name, status and visibility as the package’s

Edge Cases

IdGivenWhenThenProvenance
02Accounting makes a package’s product inactive.Staff attempt to add a renewal using the package.The renewal attempt fails.test
services-membership:tests/e2e/packages-as-products.e2e.spec.ts#packages as products, through the API › refuses a renewal term on a package whose product Accounting deactivated

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.