---
id: WF-COM-CAT-012
title: Replace a price schedule and reconcile its periods
trigger: >-
  Schedule replacement reconciles intervals while enforcing adjacency and protection. Purchasing selection and
  schedule disabling coordinate through the same row lock.
product_area: commerce
module: catalog
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-CAT-011
  - CAP-COM-CAT-012
moves:
  - STATE-COM-CAT-005
crosses:
  - SVC-COM-CAT-pricing
idempotency: >-
  Replacement uses the read version and matches periods by key. Resubmitting unchanged protected periods
  leaves their rows untouched.
concurrency: >-
  Schedule disable and deletion take an exclusive row lock; purchasing selection takes a shared lock on that
  row. Period adjacency is evaluated once at commit.
hops:
  - 'n': 1
    actor_or_service: Pricing service
    action: Lock and version-check the schedule; count following products before disable or deletion.
    anchor: 'services-commerce:modules/pricing/services/persistence/pricing-schedules.ts:updatePricingSchedule'
    seam: sync
    on_failure: Reject stale versions and referenced schedules with dependency details.
    left_inconsistent: The previous schedule remains unchanged.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/pricing/tests/integration/services/persistence/pricing-schedules.integration.spec.js#refuses
      with schedule_in_use, the count in the sentence, and the count and the first five product ids in the
      details
  - 'n': 2
    actor_or_service: Pricing service
    action: >-
      Reconcile submitted periods by key, preserving unchanged rows and updating, inserting or deleting the
      remaining rows.
    anchor: 'services-commerce:modules/pricing/services/persistence/pricing-schedules.ts:updatePricingSchedule'
    seam: sync
    on_failure: 'Roll back changes prohibited by period protection, including restrictions on used or elapsed intervals.'
    left_inconsistent: The schedule keeps its previous period set.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/pricing/tests/integration/services/persistence/pricing-schedules.integration.spec.js#answers
      the replaced record at version 2: the kept period at version 1, the changed one at version 2, the new
      one inserted, the one left out gone
  - 'n': 3
    actor_or_service: Database at commit
    action: Validate the full interval sequence at transaction commit.
    anchor: 'services-commerce:modules/pricing/db/pricing-periods.table.ts'
    seam: sync
    on_failure: 'Reject gaps, overlaps and internal open boundaries.'
    left_inconsistent: The failed commit retains no partial schedule replacement.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/pricing/tests/integration/db/member-pricing-tables.table.integration.spec.js#refuses
      an overlap, a second open end and an open start that is not first
branches:
  - Selecting a disabled schedule in purchasing settings receives an inactive refusal.
waits: []
evidence:
  - >-
    services-commerce at c8b66a98: modules/pricing/services/persistence/pricing-schedules.ts,
    product-purchasing-settings.ts; db/pricing-periods.table.ts;
    docs/milestones/COMM-M1-set-up-what-you-sell.md (D2, D4-F1, D6);
    docs/debt/pricing-schedules-owned-by-event.md.
controls: [TC-IAM-006, 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-CRY-001, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-004, TC-LOG-005, TC-AVL-004, TC-MON-001, TC-MON-002, TC-MON-004, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PRV-001, TC-PRV-002]
---

# Replace a price schedule and reconcile its periods

## What It Does

Schedule replacement reconciles intervals while enforcing adjacency and protection. Purchasing selection and schedule disabling coordinate through the same row lock.

## The Flow

```mermaid
sequenceDiagram
  participant X as API caller
  participant P as Pricing service
  participant D as Database
  X->>P: replace schedule (version read)
  P->>D: lock schedule, count followers if switching off
  P->>D: insert new, update changed, delete omitted periods
  D->>D: immutability trigger per period
  D->>D: contiguity at commit
  D-->>P: committed or refused
  P-->>X: schedule
```

## When Something Fails

Reject stale versions and referenced schedules with dependency details. The previous schedule remains unchanged. Roll back changes prohibited by period protection, including restrictions on used or elapsed intervals. The schedule keeps its previous period set. Reject gaps, overlaps and internal open boundaries. The failed commit retains no partial schedule replacement.

## Open Design Questions

The implemented recovery and concurrency behaviour above defines the current boundary. Any change to transaction scope or product authority requires a recorded decision.
