Approvals that remember what was approved

Approvals · 5 min read ·

An approval is only worth something if it still means what it meant when it was given. Someone approves a purchase of one amount, the requester edits the record to a larger amount afterward, and the sign-off sits there looking valid. This post describes how Appdor's approvals work and how they guard against that.

Two ways to ask

You can ask for an approval from a record, using Request approval on the record's Approvals tab, or you can put an approval step in a workflow, where it appears in the palette as Ask for an approval. In a workflow, the run parks on that step until someone decides, then resumes. An approval is always filed against a record, so the step needs the table and the record it concerns, and a workflow whose approval step names no approver fails validation, with the message that a gate nobody is asked to open never opens.

Both routes share the same rules. Only the named approvers can decide: nobody else in the app is shown the buttons, and the database refuses the write if they try. The step is complete either when any one of them approves or when all of them do, whichever you choose under Enough when. A rejection by anyone ends the run either way. Each approver decides once, and the requester cannot decide their own request; the message says "You asked for this approval, so you cannot decide it."

If nobody decides, a workflow step can carry on with no decision, or wait; left blank, it waits forever and nobody is chased. A request can also name a person to chase if nobody decides, and reminders and escalations are recorded on the request as "Reminder sent" and "Escalated to".

Choosing the facts

The part that makes an approval auditable is optional and worth switching on. When requesting, you can choose stored fields from the record under Facts this decision depends on, between one and thirty-two of them: an amount, a date, a status, a supplier email. The field types that qualify are text, long text, number, currency, percent, checkbox, date, date and time, email, URL, phone, select, rating, duration and attachment. Computed fields and relationships do not.

At the moment the request is saved, the database captures the selected values, the definition of those columns and the record's version. The client cannot supply or replace that snapshot. The approver then sees a small table with the fact, its value when requested, and its value now.

When a fact changes

A change to a selected value, deleting the record, or changing a selected column's name, type or configuration invalidates the evidence permanently. The decision screen then says "The selected facts changed. Request a new approval before proceeding." Changing the value back does not reinstate the approval, which closes the obvious workaround. Edits to fields you did not select do not matter, so a note added afterward does not force a new round.

The check is enforced where it counts rather than only on screen. The database checks direct approval updates, workflow signals and approval-step completion, and the worker checks queued signals, replayed results and external gate callbacks. A refusal for stale evidence cannot be skipped with a step's continue-on-error option. The documentation is careful about one limit: this is a check before authorisation is consumed, not a transaction spanning external systems, so effects already completed are not rolled back by later edits.

Two other details. A decision needs access to all of the selected facts under the approver's own permissions, and if some are hidden the screen says so instead of showing partial evidence. And for attachments, file versions are checked when requested and decided; historical file contents are not archived.

What is kept, and what is not

The request, its approvers, each decision with its comment and time, and the outcome stay with the record. A record's activity story shows lines such as "Recorded approval outcome: approved", a named approver and step for each timestamped decision, and "Saved approval evidence invalidated at" with the time. The original request, votes and comments remain available after the evidence is invalidated; what is lost is the standing of the approval, not the history.

A request made without chosen facts is labelled "This request has no saved evidence. Changes to the record are not checked." Workflows that predate the feature keep working that way until you choose fields in the approval step.

An emergency override exists only if the requester turned it on. It requires a reason, is recorded as an override rather than an approval, and sends a review back to the people who were bypassed. It cannot override stale evidence. We do not describe approval decisions as tamper-evident: the engine for a hash-chained decision record exists but is not connected to the product.

For a first try, pick one request type that already needs sign-off and choose the two facts the approver would check. See Appdor