If a prepared request and a delivered order are both simply “complete,” the next person loses sight of the remaining work. Partial delivery followed by partial payment needs even clearer state boundaries.

I did not treat the exceptions in the public experience as decorative number changes. This article follows the relationships between remaining units, outstanding money and the state that needs checking again.

Separate a step from its calculated consequences

The detailed experience follows synthetic order J01 through quotation, order, request preparation, delivery check and collection check. Step, quantity and scenario are inputs. Delivered units, example sales, receipts and receivables are derived from them. That avoids changing a completion label while separately typing a financial result that could tell a different story.

The monetary example is delivered units multiplied by a fictional KRW 100,000 unit price. Tax and accounting treatment are omitted. It is not a declaration of a real company’s recognition policy. Before adding exceptions, I separated the relationships the example should preserve from the operational policies it does not implement. A small teaching experience should remain clear about that boundary.

Partial delivery and partial payment leave different things open

With quantity six, the partial scenario delivers three units at the delivery-check step and leaves three awaiting delivery. The example sales amount is KRW 300,000. At the collection-check step, half is received: KRW 150,000 collected and KRW 150,000 outstanding. The remaining three units and the outstanding money are different kinds of unfinished work.

The experience derives and displays both from the same state. In a real service, partial deliveries could span multiple dates and items, while receipts could be allocated across several documents. This synthetic model does not implement that entire ledger. Its job is to show the separate calculations that make remaining work visible, without calling either one a generic incomplete status.

A returned unit is not automatically another unit to deliver

In the return scenario, one of six units is returned. Net delivered quantity becomes five and the example amount becomes KRW 500,000. Remaining delivery is the ordered quantity minus net delivery and returned units, giving zero. This is an explicit simplified policy: a returned unit is not automatically queued for delivery again.

The quantity-one boundary matters as well. Returning one unit leaves zero net delivery, zero amount, one returned unit and zero remaining delivery. A real business may require a replacement shipment, refund, return authorization or tax documents. Those need their own policies and transitions. I explain the current decision rather than treating this small synthetic rule as a universal return process.

Cancellation must hold in the model as well as the button

The cancellation scenario becomes cancelled from the order step and does not advance further. A cancellation notice would contradict a model that continued to increase delivered quantities or receipts. I therefore include cancellation in both the derived values and the progression condition. It is easier to inspect that boundary when the model agrees with the interface.

Invalid quantity also blocks progress. The current experience stores quantity as text, preserving a blank or out-of-range draft for correction rather than substituting a plausible number. Cancellation and invalid input both stop progression, but their reasons and next actions differ. One asks the visitor to start another example; the other asks them to correct the input.

Which revision did the earlier confirmation belong to?

Changing quantity or scenario in the current experience returns the workflow to its first step. This prevents an earlier completion from appearing to cover a changed amount. For reuse, I developed a separate module that makes the connection explicit with a revision number. Preparation and confirmation only apply when their stamps match the current revision.

Preparing and confirming quantity six, then changing it to seven, increments that number and clears both stamps. Entering six again without a change does not create another revision. The module is a synthetic state transition example, not an actor’s signed approval or a durable server record. It exposes what needs checking again before another action is permitted.

Explore the implementation

Current experience resets the step after edits

export function editJourney(s,key,value){
  if(key==='quantity'&&typeof value==='string')return {...s,quantity:value,phase:0};
  if(key==='scenario'&&scenarios.includes(value))return {...s,scenario:value,phase:0};
  throw Error('Unsupported synthetic edit');
}

Restoration should not bypass the state contract

The new module checks the snapshot format, synthetic marker, exact known keys, safe revision number and current-revision stamps. It rejects stale confirmation numbers and confirmation without preparation. An invalid draft can be restored as an invalid draft, but does not become prepared during restoration. Recovery must not manufacture a valid state that the ordinary workflow would reject.

Independent tests compare the state invariants and snapshot results across all quantities from one to twenty and 4,320 short action sequences. The bilingual demo wiring was checked in code; I did not repeat device rendering tests. The shared module includes implementation, tests and reuse boundaries. A production extension must separately handle actor permissions, concurrent edits, network request idempotency, cancellation documents and external delivery.