---
id: WF-ACC-PRD-002
title: Save a product and its accounting setup from the console
trigger: A person saves the common editor in Accounting or a product host application.
product_area: accounting
module: products
revision: 3
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
- CAP-ACC-PRD-002
- CAP-ACC-PRD-004
- CAP-ACC-PRD-015
- CAP-ACC-PRD-016
- CAP-ACC-PRD-007
moves:
- STATE-ACC-PRD-001
- STATE-ACC-PRD-003
crosses:
- SVC-ACC-PRD-products
idempotency: Completed stages update the editor baselines. Retrying unchanged input skips those stages and
  sends the last setup version. Once creation succeeded, later product changes use replacement.
concurrency: Each request uses its retained stage version. Concurrent edits can produce a conflict and Reload
  while earlier stage commits remain saved.
hops:
- n: 1
  actor_or_service: Console product editor
  action: Validate product and accounting forms and build the product payload with retained availability, portal
    visibility and status; browser finance checks may be stricter.
  anchor: react-console:components/accounting-config/products/product-editor.tsx:useProductEditorState
  seam: sync
  on_failure: Show browser issues and send no save requests.
  left_inconsistent: No stage has written data.
  observer: The form identifies invalid fields.
  provenance: observed
  source: react-console:lib/accounting-config/product-form.ts:preservedProductFields
- n: 2
  actor_or_service: Products API (product stage)
  action: Create a product with no successful baseline, or replace a changed product at the baseline version.
  anchor: services-accounting:modules/products/services/persistence/products.ts:updateProduct
  seam: sync
  on_failure: Show a product error or conflict and stop later stages.
  left_inconsistent: No successful stage has completed in this attempt.
  observer: The person sees the product-stage failure.
  provenance: observed
  source: react-console:components/accounting-config/products/product-editor.tsx:useProductEditorState
- n: 3
  actor_or_service: Products API (accounting stage)
  action: Save changed accounting when the editor has both read and edit authority, using the setup version;
    serialization does not return share identities.
  anchor: services-accounting:modules/products/services/persistence/product-accounting-setups.ts:replaceProductAccounting
  seam: sync
  on_failure: Report financial failure while retaining any earlier product commit.
  left_inconsistent: The product has its old setup, or none if its first setup failed.
  observer: The person sees the accounting-stage problem; others receive no separate notice.
  provenance: observed
  source: react-console:lib/accounting-config/product-accounting-rules.ts:accountingForSave
- n: 4
  actor_or_service: Host application (domain stage)
  action: Run the host's optional callback after common product and accounting stages succeed.
  anchor: react-console:components/accounting-config/products/product-editor.tsx:ProductEditorProps
  seam: sync
  on_failure: Report host failure without reversing completed common stages.
  left_inconsistent: The product can remain without an extension or with its earlier extension.
  observer: The person sees the host problem; the host owns completion or retirement.
  provenance: observed
  source: react-console:components/accounting-config/products/product-editor.tsx:useProductEditorState
- n: 5
  actor_or_service: Console product editor page
  action: After success, notify the person, invalidate catalogue caches and return to the list with kind and
    unit context.
  anchor: react-console:components/accounting-config/products/product-editor-page.tsx:ProductEditorPage
  seam: sync
  on_failure: The success callback declares no further persistence failure handling.
  left_inconsistent: The completed stage commits remain saved.
  observer: The person sees the notice and list navigation.
  provenance: observed
  source: react-console:components/accounting-config/products/product-editor-page.tsx:ProductEditorPage
branches:
- The financial stage is skipped without accounting read and edit authority.
- An unchanged saved product is skipped when only accounting changed.
waits: []
evidence:
- 'react-console at baf6dae3: components/accounting-config/products/product-editor.tsx (useProductEditorState,
  save), product-editor-page.tsx; lib/accounting-config/product-form.ts (formToWrite, preservedProductFields),
  product-accounting-form.ts, product-accounting-rules.ts; lib/accounting/configuration/client.ts.'
- 'services-accounting at f47cb263: modules/products/services/persistence/products.ts, product-accounting-setups.ts.'
controls: [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-DAT-001, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005]
---

# Save a product and its accounting setup from the console

## What It Does

The shared console editor saves the common product, then changed accounting, then any supplied host-application extension. Each request has its own permission checks, version and commit outcome.

## The Flow

```mermaid
sequenceDiagram
  participant U as Person
  participant E as Shared editor
  participant A as Accounting API
  participant H as Host application
  U->>E: Save form
  E->>E: Check browser issues
  opt New or changed product
    E->>A: Save common product
    A-->>E: Product baseline
  end
  opt Changed setup and permitted
    E->>A: Save financial setup
    A-->>E: Setup baseline
  end
  opt Host callback supplied
    E->>H: Save specialized record
    H-->>E: Result
  end
  E-->>U: Success and return navigation
```

## When Something Fails

A failed stage stops later requests and leaves earlier successes committed. The editor retains returned baselines so an unchanged retry can skip completed work. First creation may therefore leave a product without its setup or extension. Setup serialization drops revenue-share identities, causing the service to generate new ones.

## Open Design Questions

The staged contract remains the observed implementation. Product must decide whether to add a combined save and how to reconcile stricter browser accounting validation with service-valid records.
