---
id: WF-ACC-PRD-006
title: Hand migrated special prices over to Commerce
trigger: The member-pricing migration converts old special-price rows to audience-based prices.
product_area: accounting
module: products
revision: 3
status: draft
design_intent: proposed
implementation_evidence: partially-observed
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
- CAP-ACC-PRD-009
- CAP-ACC-PRD-008
moves:
- STATE-ACC-PRD-005
crosses:
- SVC-ACC-PRD-products
idempotency: Migration bookkeeping governs one-time application. After the old table is dropped, replaying
  its conversion SQL is unsafe. A realization stamp supplies no proof of consumer replay behavior.
concurrency: The SQL performs conversion, but this scope establishes no deployment exclusion of live writers.
  Commerce completion concurrency and write authority remain unproved.
hops:
- n: 1
  actor_or_service: Member-pricing migration
  action: Mint a product-local audience and always-period cell for each special price, appending them after
    the existing grid in original order.
  anchor: services-accounting:db/migrations/20261018030710_products_a12_member_pricing.sql
  seam: sync
  on_failure: Propagate SQL failure to the migration runner, which must provide transactional execution.
  left_inconsistent: The runner must prevent a partially committed migration.
  observer: The migration runner receives the SQL error.
  provenance: test
  source: services-accounting:modules/products/tests/integration/db/special-prices-a12-migration.integration.spec.js#mints
    one always price row per special price under its audience, after the product’s existing prices, in 1.0
    order
- n: 2
  actor_or_service: Member-pricing migration
  action: Keep criteria, amount, currency, formula and rank in handovers, delete converted special rows and
    drop their emptied table.
  anchor: services-accounting:modules/products/db/pricing-audience-handovers.table.ts:pricingAudienceHandovers
  seam: sync
  on_failure: Propagate failure so the runner cannot complete the migration successfully.
  left_inconsistent: The runner's transaction is required to prevent partial conversion.
  observer: The migration runner receives the SQL error.
  provenance: test
  source: 'services-accounting:modules/products/tests/integration/db/special-prices-a12-migration.integration.spec.js#hands
    each special price over as a product-local audience: minted id, product, name, criteria, amount in the
    base currency, formula, rank'
- n: 3
  actor_or_service: Products API (any later replacement)
  action: During later HTTP replacement, allow held audiences without a Commerce register and require active
    entries once it exists.
  anchor: services-accounting:modules/products/services/persistence/pricing-audiences.ts:readAdmittedAudiences
  seam: sync
  on_failure: Refuse replacement even if the changed fields are unrelated to prices.
  left_inconsistent: The stored product remains but the resubmitted audience blocks saving.
  observer: The editor receives an audience refusal.
  provenance: test
  source: services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#admits
    an audience the product already holds on a replacement (a migrated special price), even without the vocabulary
- n: 4
  actor_or_service: Commerce
  action: The documented Commerce consumer creates audience eligibility and stamps completion; its invocation
    has not been verified.
  anchor: services-accounting:modules/products/db/pricing-audience-handovers.table.ts:pricingAudienceHandovers
  seam: sync
  on_failure: Consumer retries, compensation and reporting remain unknown.
  left_inconsistent: The documented pricing flow cannot use the migrated audience until Commerce establishes
    it.
  observer: No consumer monitor or failure report is established.
  provenance: unknown
  source: FND-ACC-PRD-046
branches: []
waits:
- No verified deadline or completion monitor exists for Commerce realization.
evidence:
- 'services-accounting at f47cb263: modules/products/db/pricing-audience-handovers.table.ts, product-prices.table.ts;
  services/persistence/pricing-audiences.ts; docs/migrations/accounting-modernization/products-a12-a13/README.md
  (The special-price migration, Decisions taken in the session 1 and 2, Open items).'
- 'services-accounting at f47cb263: tests/integration/db/special-prices-a12-migration.integration.spec.js.'
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-DAT-004, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-006, TC-CHG-007, TC-PI-001, TC-PI-002, TC-PI-003]
---

# Hand migrated special prices over to Commerce

## What It Does

The schema migration converts former special prices to local-audience cells and preserves qualification context in handover rows. Those rows support the documented Commerce realization step; they do not establish a queue or worker.

## The Flow

```mermaid
sequenceDiagram
  participant M as Migration
  participant D as Database
  participant P as Product writer
  participant C as Commerce, intended consumer
  M->>D: Preserve handovers and audience cells
  M->>D: Empty and drop special-price table
  P->>D: Apply audience admission on later replacement
  Note over C,D: Realization invocation and recovery are unverified
  C-->>D: Intended audience completion stamp
```

## When Something Fails

Migration rollback depends on the runner's transaction. Later HTTP edits reject a resubmitted migrated audience missing from an existing Commerce register, even when only descriptive fields changed. Domain saving admits audiences differently. Commerce retries, compensation and alerts remain unverified.

## Open Design Questions

Product must settle held-audience editing during realization. Commerce must supply a consumer contract covering completion, replay and failure before the downstream hop can be treated as implemented.
