TT Lab
Get started
Learn Learning paths Courses

Irreversible Changes

Hand Off a Customer Change End to End

Continue in TT Lab

In one line

A customer change coordinator has to freeze the approved input and manage the execution response, the DB observation, the report saving, and a separate compensation as different results.

Why this was needed

It is the last day of the space festival cancellation job. The customer approved the cancellation, and the orders really became cancelled. But an error appeared on the owner's screen. This is because there was a problem with the disk where the report is to be saved. Since the screen has an error, should you run the cancellation again? Should you roll it back? If you cannot tell what failed, the recovery work becomes a new incident.

In the earlier units, you learned the input boundary, conditional changes, audit, compensation, chunk resume, schema coexistence, and evidence reporting separately. This time the goal is not to write those functions again at length. You receive the already verified features as a small library and build a coordinator that handles one customer request. What is new is deciding which input to accept as whose approval, and what more you may call after which result.

Even if the provided library handles SQL well, if the coordinator keeps retrying with a new ID or automatically compensates because of a report error, the whole system is wrong. A part passing its tests and the correctness of the business that connects the parts are separate. The capstone checks the space between them.

How it works

1. A preview and an approval are not the same file

A preview reads the explicit IDs of a specific customer and shows the revision and quantity. From this observation you can build the shape of an execution request, but you leave approved as False. You must not regard a change to those values as approved by a person just because there are observed values.

Only a file in which the learner checked the contents and actually changed approved to True is accepted as an execution request. The string true or the integer 1 is not treated as an approval. This flag is an explicit input contract of this fictional business and is not an electronic signature or user authentication. A real organization needs a separate system to confirm who approved it with what authority. The fact that a JSON file can be edited does not prove the identity of the approver.

If the order values change after the approval, you do not quietly update the earlier approval to the new values. If the customer approved after seeing qty=4 and revision=9, but right before the run it is changed to qty=6 and revision=10 and applied, that is a different request even if it is the same target. Code that automatically calls preview again to reduce failures can instead break the approval boundary.

2. Split the execution response into four kinds

If the provided apply returns True, this call committed a new change. False means that a record of the same ID and the same approval contents already existed, so it did not apply again. This alone does not guarantee that even the current row has the desired value. This is because another owner may change it afterward.

Conflict is the case where the provided operation rejected a conflict of the approval and the current condition. Any other ordinary exception is separated as an unknown outcome. In particular, if delivering the response fails after the commit, the DB change can exist even though you received an exception. The coordinator does not turn an exception into a confirmed failure or into an unconditional success.

This is why, even if you need to call again, you must keep the same approval and the same ID. This coordinator does no automatic retry and returns the result of one execution and the read observation that follows. It builds the basis on which a person or a higher-level system chooses the next action, and does not guess that choice itself.

3. In the observation, reconcile the approval contents, not just the IDs

After receiving the execution response, you check the original approval, the audit, and the current rows with observe. Even if the stored change_id is the same, if the tenant or targets differ, it is a different approval. A list with only the same count, or a different revision or quantity for the same ID, is not allowed. It also blocks publishing a report that corresponds to a different approval as if it were the result of the current request.

If there is no observation or the DB query fails, it is unknown. If the reconciliation that it is the same approval fails, it is mismatch. If the query succeeded and it is the same approval, you keep the complete, incomplete, and hold verdict from the earlier unit as it is. Even if the execution response is replayed, you do not turn hold into complete.

The execution and the observation are not one transaction. This structure is a flow of investigating a committed job afterward. When you read PostgreSQL isolation levels, distinguish the consistency of one transaction from the current state between separate calls. The fact that the coordinator has finished the execution does not stop later writes.

4. A report failure is the failure of a separate job

After the execution and observation are done, you save the report file. The result is kept separately as saved or failed. If saved, you also keep the returned SHA-256, but that does not mean author authentication. Even if the DB observation is complete, the report saving can be failed, and even if the report file is saved successfully, the business verdict inside it can be hold.

The report action that only rebuilds the report must have no apply or undo call. There is no reason to change an already cancelled order again or make it pending again. The fact that the word recovery appears in a report error message does not create authority for business compensation.

The observation and the report collection are also separate calls. If a later change happens in between, the observed returned earlier and the verdict in the file saved later may differ. observed is the result of the earlier observation, and report=saved is whether the file was saved. You do not combine the two and claim that "the whole current system is normal and the report is at the same point in time". The final content delivered to the customer must be read together with the observation time and the scope in the report file.

5. Compensation is not an automatic error handler

The undo action needs a separate undo_id, the original change_id, a reason that is not only whitespace, and an explicit approval. It verifies the original audit and runs the conditional compensation only when the current row matches the customer, quantity, state, and revision right after the original change. If a row in the middle has changed, the restoration of the earlier rows is rolled back along with it.

A compensation does not lower the revision to a past value. Even when it goes back to pending, it is a new change, so the version increases and a separate audit remains. The original approval and the original audit are not deleted. Erasing the traces of an error and recovering from the effects of an error are different jobs.

In a compensation too, an ordinary exception is uncertain. If the compensation result is unclear, you do not make another undo_id and run it again. This coordinator does no automatic follow-up work after a compensation. The procedure for checking the compensation receipt and the current state leads to inspect_undo and reconcile_undo of the earlier compensation unit. Leaving in a document the scope of the automation and the boundary that a person must check is also part of the handover.

What it looks like in the field

When the error boundary is drawn too wide

If you put apply, observe, and publish in one try and call undo in the except, you lose which step failed. A write error, a read failure, and a file error need different next actions. This lab splits the boundaries with small functions and composes the result of each step. Stability does not arise merely because you caught an exception.

psycopg transaction management distinguishes the transaction context from the connection lifetime. The provided operations clean up the connection that each call owns, and the coordinator does not wrap the whole request again in an outer transaction. If you wrap it that way, whether the completion of a lower function is a real commit or a savepoint release can differ. The lab confirms the real effect on the installed psycopg 3.2.3.

When exit code 0 is mistaken for business completion

If the CLI processed the request and printed a structured result, it returns exit code 0. execution=conflict, observed=hold, and report=failed inside the JSON can also be normal processing results. A higher-level automation that sends a success notification by looking only at code 0 can reach a wrong conclusion. If the request format or the file interpretation itself failed, it returns code 2 and a fixed error object.

Do not put the DSN, the password, or the original exception string as they are into the error output. The learning material is a fictional DB, but real production habits are formed here. It also handles invalid UTF-8, duplicate keys, truncated JSON, non-finite constants, and size limits. The object_pairs_hook and parse_constant of the Python JSON documentation are tools for checking such input as data. You must not execute it with eval.

An FDE who makes the customer's next action clear

The Palantir FDSE job posting covers customer-specific software and stakeholder collaboration. This capstone is our own learning assignment that interprets that requirement as "a tool that explains which change the customer approved, what has been confirmed now, and who decides what next". It does not reproduce a specific company's internal procedures or hiring exam.

What you will do in the next lab

You receive the space festival's cancellation request as JSON and connect preview, execution, observation, reporting, and a separate compensation. On a real DB you check the rejection of a stale approval, a response lost after the commit, a report file failure, and a later change and compensation. At the end, you call the real CLI and read the exit code and the business result separately. It rejects not only the right answers but also the wrong answers that create automatic re-approval, automatic compensation, or a false completion.

It uses only per-learner fictional data and a disposable DB. This is not a lesson that completes customer permission management, approval signatures, sending reports externally, distributed transactions, or server power failure durability.