Skip to content

CAP-ACC-PRD-002Create a product with a permanent identity

Markdown

CAP-ACC-PRD-002

Create a product with a permanent identity

Markdown
  • DocumentDraft
  • Product intentProposed
  • ImplementationObserved

KindCapabilityProduct areaAccountingModuleProductsRevision3

Read atservices-accounting f47cb263react-console baf6dae3

The Formal Contract

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

Outcomes
Creation preserves a durable catalogue identity.
Surfaces
consoleapi
Preconditions
The workspace contains the selected business unit.
Postconditions
Creation stores the product and its owned configuration at the first version, or the local transaction writes nothing.
Intent sources
services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D3services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D4services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#D12services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#R10services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#Notes on the decisions:services-accounting:docs/milestones/ACCT-M1-books-and-invoices.md#R11

Controls

24 controls apply, from the corpus control catalogue.

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

Permissions

KeyChecked atScope
accounting.products.createapitenant

Business Rules

15 rules, 13 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
A new product uses a supplied or name-derived configuration identity of at most 63 characters, starting with a lowercase letter and using lowercase letters, digits and single underscores without reserved words.
✓ The name Café Parking Permit (Annual) produces the readable Code cafe_parking_permit_annual.✗ A Code containing uppercase letters and a hyphen fails validation.
validationapi, service, databasetest
services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses an id that is not a configuration id, with the configuration-id sentence, and writes nothing
02must prove
Proposed
Name-derived identities receive no automatic suffix: a collision or a name yielding no valid identity requires the caller to supply one.
validationservicetest
services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses a second product whose name suggests a taken id, as other configuration does, naming the id
03must prove
Proposed
Within a workspace, product identities are unique across product kinds.
invariantdatabasetest
services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 400 to the same id under another type: a product id is unique across every type
04must prove
Proposed
Creation requires an active registered kind, an existing business unit in the workspace and a nonblank name.
validationservice, databasetest
services-accounting:modules/products/tests/e2e/products-shared-base.e2e.spec.js#refuses a type registered inactive (an Events type), 400 with its sentence
05must prove
Proposed
The server discards a submitted pricing model and uses the kind’s model, which the database also requires.
invariantapi, databasetest
06must prove
Proposed
Creation fixes the product’s identity, kind and business unit, and both service and database reject later changes.
invariantservice, databasetest
07
Proposed
Creation defaults to active and permits inactive, while ordinary creation and replacement requests cannot choose retired.
lifecycleapiobserved
08must prove
Proposed
A sale window with both boundaries requires its opening instant to precede its closing instant.
validationservice, databasetest
09must prove
Proposed
Cancellation and restocking fees use nonnegative whole minor units of the business unit’s base currency.
validationapi, databasetest
10must prove
Proposed
Unsellable kinds reject fees and selling settings, while giver-priced kinds also reject quantity discounts and bundles.
validationservicetest
11must prove
Proposed
Product creation commits its record, pricing, components and feature collections together or retains none of those writes.
invariantservicetest
12must prove
Proposed
Products with older generated identities remain readable, referenceable and deletable, but replacement, retirement and reactivation fail.
lifecycledatabasetest
services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses a replacement, 409, saying why, and leaves the product unchanged
13must prove
Proposed
Products support no custom field values and reject requests containing them.
validationapitest
services-accounting:modules/products/tests/e2e/products-shared-base.e2e.spec.js#refuses a body that names custom fields, 400 naming the property
14must prove
Proposed
Product creation requires product create permission.
permissionapitest
15
Proposed
The console derives an editable Code from Name during creation, selects the list’s unit or the working unit, and returns to the list after successful creation.
policyconsoleobserved

Scenarios

IdGivenWhenThenProvenance
01A chapter business unit uses US dollars.A controller creates Parking Permit with a 25000-minor-unit standard price.The saved product has a readable identity, active status, version one and a $250.00 price.test
services-accounting:modules/products/tests/e2e/products.e2e.spec.js#creates it under the id it was given, in the tenant of the path, at version 1
02A donation already uses the identity gala.An administrator creates an Accounting Product with that identity.The collision is rejected across product kinds.test
services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 400 to the same id under another type: a product id is unique across every type

Edge Cases

IdGivenWhenThenProvenance
03An older product retains its generated identity.An administrator submits a new name.The refusal explains that a readable-identity replacement product is needed.test
services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses a replacement, 409, saying why, and leaves the product unchanged

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.