What you will build.
Reconcile fictional payroll instruction DEMO-PAY-01. A payment provider reports paid, but the accounting entry may already exist. Work through a failed payment, a repeated notification and an unapproved instruction without calculating payroll or initiating a payout.
Your working record
Create a private worksheet with columns for the source reference, observed state, responsible system, observation time, expected result and unresolved issue. Use the same fictional case throughout the steps; do not paste live personal or financial records into this exercise.
Run the example before changing it.
Inspect the baseline record below. Download and read the complete JavaScript file before running it. It uses only Node’s built-in test and assertion modules; there is no package installation, account connection or secret to configure.
{
"approved": true,
"providerState": "paid",
"journalPosted": false
}Save it as accounting-and-payroll-systems.mjs. Open a terminal in that folder and run:
node --version
node --test accounting-and-payroll-systems.mjsExpected result: four passing tests and zero failures. These tests verify the teaching classifier only. They do not verify a production integration, security boundary or financial outcome.
File or test runner will not start?
Check that Node.js 22 or later is installed, the filename ends in .mjs rather than .mjs.txt, and your terminal is in the download folder. If a managed browser blocks scripts, open “Read the full exercise” and save that text locally under the same filename. Do not disable organizational security controls.
Read the full exercise
// Hybrid-Chain offline teaching model: accounting-and-payroll-systems
// Fictional fields/states; NOT an API client, authorization system or production implementation.
// No network calls, credentials, payments or file writes. Review before running.
// Requires Node.js 22+. Run: node --test accounting-and-payroll-systems.mjs
import test from 'node:test';
import assert from 'node:assert/strict';
export function inspect(record) {
if (!record.approved) return 'APPROVAL_REQUIRED';
if (record.journalPosted) return 'ALREADY_RECONCILED';
if (record.providerState !== 'paid') return 'KEEP_OUTSTANDING';
return 'READY_FOR_JOURNAL_REVIEW';
}
const baseline = {
"approved": true,
"providerState": "paid",
"journalPosted": false
};
const cases = [
{
"name": "ready for accounting review",
"patch": {},
"expected": "READY_FOR_JOURNAL_REVIEW"
},
{
"name": "unapproved source",
"patch": {
"approved": false
},
"expected": "APPROVAL_REQUIRED"
},
{
"name": "failed provider outcome",
"patch": {
"providerState": "failed"
},
"expected": "KEEP_OUTSTANDING"
},
{
"name": "duplicate notification",
"patch": {
"journalPosted": true
},
"expected": "ALREADY_RECONCILED"
}
];
for (const example of cases) {
test(example.name, () => {
assert.equal(inspect({...baseline, ...example.patch}), example.expected);
});
}
Know what the tests demonstrate
- ready for accounting review
READY_FOR_JOURNAL_REVIEW- unapproved source
APPROVAL_REQUIRED- failed provider outcome
KEEP_OUTSTANDING- duplicate notification
ALREADY_RECONCILED
Now change one fixture at a time. If you change a case’s input without changing its expected result, the test should fail. Read the actual-versus-expected difference and use the walkthrough to decide whether your rule or your expectation needs correcting. Keep an unchanged copy for comparison.
Work through the case, step by step.
- 01
Create the source instruction
Do this
- Label the fictional instruction DEMO-PAY-01 and mark approval separately from the batch's existence.
- Keep the batch total and each instruction's amount/currency in distinct worksheet cells.
- Identify the payroll owner, payout-provider owner and accounting-close owner.
Expected resultOne stable source reference can connect the records without exposing employee data in public evidence.
If your result is different
If the source system can regenerate an ID on each export, agree a stable business key before designing retry handling.
- 02
Interpret the provider result
Do this
- Run the baseline with approved=true, providerState=paid and journalPosted=false.
- Set providerState=failed and confirm KEEP_OUTSTANDING.
- Add a pending row manually and ensure it also stays outstanding rather than being marked paid on notification receipt.
Expected resultThe model only proposes a journal review after a paid provider state; the presence of a callback is not enough.
If your result is different
If a callback is ambiguous or unauthenticated, retrieve authoritative provider state through the actual supported integration.
- 03
Model the duplicate boundary
Do this
- Set journalPosted=true and expect ALREADY_RECONCILED.
- Record the source instruction and existing journal reference together.
- Write down how the real accounting adapter will enforce uniqueness atomically; the local flag is only a teaching representation.
Expected resultYou can explain why a repeated notification should not create a second journal entry or another payment.
If your result is different
An in-memory check is not sufficient under concurrent workers. Require a tested durable uniqueness boundary in the implementation.
- 04
Close the batch with exceptions visible
Do this
- Set approved=false and verify that provider status cannot replace source approval.
- Group worksheet rows into reconciled, outstanding and review-required, preserving failed items.
- Keep the report private and use the Data Vault guide to inspect document-access boundaries for supporting records.
Expected resultThe close process accounts for successful, failed and unresolved items without suppressing the exceptions.
If your result is different
Do not fabricate balancing entries to make the fixture totals agree; investigate each missing source or provider reference.
Review what you produced.
Save the worksheet, unmodified test output, one deliberately failing case and the explanation of its fix. A useful result includes an unresolved item with an owner; it is not just a screenshot of four green tests.
Map the model to actual systems.
Your payroll/accounting system owns calculations, approvals, employee data, statutory reporting, and journal entries. Agree a separately authorized payout provider or route.
For each worksheet field, name the owning system, exact current operation, permission and error behavior. Put “not available” next to any missing operation and assign a dependency owner. Do not substitute the teaching classifier for that missing integration.
Open the current API reference and inspect each operation’s request, response, scope and implementation status. Code examples on this page are local models only; they do not call those operations.
Take the next technical step.
Use your worksheet and failing-case notes in the next walkthrough. Keep the same reference trail so you can see which assumptions become actual observations—and which remain dependencies.
Inspect protected supporting records