What you will build.
Design one fictional customer's onboarding-to-service journey in tenant DEMO-A. The interface is ready, but the financial provider has not approved the account. Check isolation and service activation without presenting a branded portal as an operational bank account.
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.
{
"callerTenant": "DEMO-A",
"recordTenant": "DEMO-A",
"providerApproved": true,
"operationEnabled": true
}Save it as decentralized-neobanking.mjs. Open a terminal in that folder and run:
node --version
node --test decentralized-neobanking.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: decentralized-neobanking
// 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 decentralized-neobanking.mjs
import test from 'node:test';
import assert from 'node:assert/strict';
export function inspect(record) {
if (record.callerTenant !== record.recordTenant) return 'DENY_TENANT';
if (!record.providerApproved) return 'WAIT_FOR_PROVIDER';
if (!record.operationEnabled) return 'SERVICE_UNAVAILABLE';
return 'READY_FOR_SERVICE_REVIEW';
}
const baseline = {
"callerTenant": "DEMO-A",
"recordTenant": "DEMO-A",
"providerApproved": true,
"operationEnabled": true
};
const cases = [
{
"name": "scoped service review",
"patch": {},
"expected": "READY_FOR_SERVICE_REVIEW"
},
{
"name": "other tenant",
"patch": {
"recordTenant": "DEMO-B"
},
"expected": "DENY_TENANT"
},
{
"name": "provider pending",
"patch": {
"providerApproved": false
},
"expected": "WAIT_FOR_PROVIDER"
},
{
"name": "operation not enabled",
"patch": {
"operationEnabled": false
},
"expected": "SERVICE_UNAVAILABLE"
}
];
for (const example of cases) {
test(example.name, () => {
assert.equal(inspect({...baseline, ...example.patch}), example.expected);
});
}
Know what the tests demonstrate
- scoped service review
READY_FOR_SERVICE_REVIEW- other tenant
DENY_TENANT- provider pending
WAIT_FOR_PROVIDER- operation not enabled
SERVICE_UNAVAILABLE
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
Draw one customer journey
Do this
- Start with a customer request, provider review and the first proposed service; avoid designing a whole bank in one diagram.
- Give each stage a responsible organization and support contact role.
- Distinguish the Hybrid-Chain interface, identity/wallet components and contracted financial services.
Expected resultThe worksheet explains what the customer is using and which party actually provides each service.
If your result is different
If a provider is not contracted or its operation is unavailable, mark the journey incomplete instead of using a generic bank label.
- 02
Test the tenant boundary
Do this
- Run the baseline with callerTenant and recordTenant both DEMO-A.
- Change recordTenant to DEMO-B and expect DENY_TENANT.
- List the real API resources that would need server-side tenant enforcement; the local comparison is not authentication.
Expected resultYou have an explicit cross-tenant negative test to carry into the authorized integration environment.
If your result is different
Never rely on hiding another tenant's records in the browser. Enforcement belongs to authenticated server-side authority.
- 03
Separate provider approval from UI readiness
Do this
- Set providerApproved=false and confirm WAIT_FOR_PROVIDER.
- Keep the customer application state visible without labelling the financial service active.
- Record what a rejected, pending or missing provider response should look like in the customer interface.
Expected resultThe design can explain why a signed-in customer is not yet entitled to use a particular financial service.
If your result is different
Do not infer provider approval from successful identity login, a wallet record or a branded account page.
- 04
Check enabled operations individually
Do this
- Set operationEnabled=false and confirm SERVICE_UNAVAILABLE.
- Restore the fixture and retain READY_FOR_SERVICE_REVIEW, not a real account-activation result.
- Use the wallet guide to define recovery, authorization and evidence checks for the selected first operation.
Expected resultThe initial scope is a tested service journey with clear dependencies, not a claim that all financial modules are live.
If your result is different
A later product expansion needs its own availability and provider checks; do not copy the first operation's active state.
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 institution and contracted providers own account terms, safeguarding, regulated permissions, customer service, and the applicable payment rails.
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.
Map wallet authority and recovery