← Technical series

Architecture for business software

Designing approvals that preserve the original record

How to separate a preview, a reviewed decision, and a posted result in business software, using an anonymized workforce workflow example.

A business system needs to explain more than the latest value. It needs to show what was known when someone approved a result, and what changed afterward.

Consider a simple example: an attendance correction arrives after a pay calculation has been reviewed. Silently replacing the calculation leaves the reviewer approving one result while the application displays another. Refusing every later correction makes ordinary operations difficult. The design needs a deliberate path between those extremes.

1. Separate preview, review, and posting

A preview answers “what would this calculation produce now?” A review records a decision about a specific result. Posting applies the approved business effects. Giving each step its own meaning makes it easier to decide what may change and who may act.

  1. Preview from dated inputs
  2. Review a specific result
  3. Post the approved effects
  4. Link later corrections
An illustrative approval lifecycle for business applications.

The workforce workflow example uses retained pay reviews, original slips, and linked corrections to keep calculations connected to their history. It remains in development.

2. Pin the inputs behind the decision

A number on its own is difficult to audit. Keep the relevant input versions, rule versions, calculation breakdown, reviewer, and decision time with the reviewed result. An effective date matters as much as the current value: a salary or leave rule that changed today may not apply to an earlier period.

Before posting, check that the review still applies. If an input changed in a way that affects the result, send the operation through the appropriate correction or review path. Do not let a screen's old snapshot stand in for a fresh server-side check.

Design for an explanation

A reviewer should be able to answer: which inputs produced this result, who approved it, and which later adjustment changed its effect?

3. Add a correction without erasing the original

In the attendance example, retain the original calculation and describe the proposed adjustment separately. Link the new operation to the record it corrects. Capture a reason and require the review appropriate to its effect.

Separate the corrected amount from what has already been paid. Updating a calculation does not undo a transfer. If money or another external action has already moved, the application needs a settlement or reconciliation workflow that acknowledges that fact.

The same principle applies to stock adjustments, invoice corrections, and entitlement changes. The exact workflow differs, but the original event and the later decision both remain meaningful.

4. Make concurrent actions and retries explicit

Two operators can act on the same record. A browser can repeat a request after a timeout. A worker can restart after committing a change. These are ordinary delivery conditions, so they belong in the design from the beginning.

  • Expected version: detect when the record changed after an operator loaded it.
  • Stable request identity: recognize a repeat of the same operation and return its existing result where appropriate.
  • Atomic database changes: apply related local effects together, or leave them unapplied.
  • Explicit external status: track work involving another system separately; a database transaction cannot undo an external action.

Rules should be enforced by the application and supported by database constraints where possible. Hiding a button in the interface is helpful guidance, but it does not protect a business invariant.

5. Test the history, not just the final total

A useful test starts with an approved result, introduces a correction, and checks that the original remains intact. Add a repeated request, a stale review, and two competing actions. Check the records, permissions, and intermediate states as well as the final arithmetic.

The supporting implementation includes tests around approval, correction, attendance, leave, and finance boundaries. For your application, choose scenarios from the decisions users actually make. A smaller set of meaningful workflow checks is more useful than tests that only repeat the calculation's implementation.

Project context

This walkthrough is informed by the documented structure of auditable workforce workflows, a private product in development. The attendance scenario is illustrative.

Work together

Resolve the next decision
in your system.

Discuss your current design, the risks you see, and what needs to move forward.

Discuss your requirements