Skip to content
Preptima

Banking and financial services fundamentals

What a bank looks like from the inside: the append-only ledger and its four balances, the rails money moves over and what finality costs, cards and disputes, credit decisioning, and the controls wrapped around all of it. Sixty items, fourteen worked through with ledger rows, arithmetic or a diagram.

60 questions

Go deeper on Banking & Financial Services
Standard Sheet View

The core entities

What is a bank, from a systems point of view?

A ledger, a set of connections to external payment rails, and a financial-crime apparatus wrapped around both. Everything customer-facing is a read model over that core. The framing matters because it locates the hard engineering outside your own service boundary: the ledger has to balance to the minor unit and stay defensible for years, the rails are third-party systems with operating hours, cut-offs and finality rules you cannot retry your way past, and the compliance layer can freeze a transaction your product logic has already accepted. A candidate who describes a bank as CRUD over an accounts table has missed all three, and will design a payment API that assumes the money movement is a function call which either returns or throws. The interesting constraints are almost never in the application tier.

Why are the customer and the account modelled separately?

Because the relationship is many-to-many in both directions and it changes over time. One customer holds several accounts, one account has several parties — a joint account, a company account with signatories, a trust with beneficiaries — and a person can be a beneficial owner without being a party to the account at all. Collapsing them makes the joint account unrepresentable and leaves the due-diligence record with nothing to hang on, since diligence is performed on a person or a legal entity rather than on an account number. There is a lifecycle consequence too: closing an account must not remove the customer, because the identity evidence carries its own retention obligation and other products may still be open. Interviewers ask because the wrong answer surfaces in the schema immediately.

What is a product, and what does it do to your schema?

A product is the set of terms an account is opened under — interest rate, fee schedule, overdraft eligibility, currency, statement cycle, early-withdrawal penalty — held separately so that a hundred thousand accounts share one definition rather than each carrying a copy. Modelling it properly is what stops a rate change becoming a mass update with no history. The part candidates omit is the version: an account is opened under a product version, and every version must be retained, because "what rate was this customer promised in 2021" is a question you will be asked by the customer, by a regulator and possibly by a court. So product configuration is effective-dated reference data with an audit trail, not a settings table somebody edits in place.

What does KYC actually require, and what does it produce?

Verified identity for every party, evidence of that verification, a risk rating, and a record you can defend years later. In practice that means identity and address documents checked against an authoritative source or a bureau, liveness or biometric matching on a remote channel, beneficial-ownership resolution for a corporate customer, sanctions and politically-exposed-person screening, and source-of-funds enquiry for the higher-risk cases. What it produces is what matters to engineering: an immutable case file recording what was checked, by which provider, with what result, at what time, and who decided. That is why onboarding cannot be a stateless form. It is an evidence-generating workflow with a persisted state machine, idempotent retries against flaky third parties, and manual review as a designed path rather than an error branch.

Show me the customer, account and product model and where it goes wrong.

Four tables and one join table carry most of retail banking, and the join table is the one that gets flattened away.

party             a person or legal entity. Diligence attaches here.
  party_id, party_type, legal_name, date_of_birth, country,
  risk_rating, kyc_case_id

account_party     the relationship. Many to many, and effective dated.
  account_id, party_id,
  role         holder | signatory | beneficial_owner | mandate_delegate
  valid_from, valid_to

account           the container postings are made against.
  account_id, product_version_id, currency, status,
  opened_at, closed_at            -- closed, never deleted

product_version   the terms. New row per change, never edited in place.
  product_version_id, product_id, version, interest_rate,
  fee_schedule_id, effective_from, effective_to

posting           the ledger. Append only. One row per side of a transaction.
  posting_id, account_id, dr_cr, amount_minor, currency,
  transaction_id, value_date, booked_at

The role column is the whole point of the join table. A signatory can instruct payments but is not an owner of the funds, a beneficial owner is subject to diligence but cannot instruct anything, and a delegate holds a time-boxed mandate that must expire. Systems that store a single customer_id on the account cannot express any of that, and the workaround is invariably a second hidden account per extra party, which then breaks every balance and every statement.

Effective dating on account_party is what lets you answer who was authorised on the day a disputed payment was made. Without valid_from and valid_to you know the current mandate and nothing else, and the dispute you are being asked about is eight months old.

currency sits on the account and not on the product because a multi-currency product issues one account per currency, and a posting must never mix units. Storing amounts as integer minor units rather than a decimal or a float is the other non-negotiable, since binary floating point cannot represent a tenth of a penny and a rounding error in a ledger is a reconciliation break somebody has to investigate.

The closed_at column instead of a delete is the pattern repeated throughout banking. Nothing is removed, because the transaction history, the diligence evidence and the tax records all outlive the relationship, and an erasure request against a closed account is answered by a legal retention exemption rather than a DELETE.

What is AML transaction monitoring, in engineering terms?

A stream of every money movement evaluated against rules and models that raise alerts for human investigation, plus the case-management system those alerts land in. The rules are recognisable — structuring just under a reporting threshold, rapid movement through an account that keeps no balance, unexpected geography, sudden change from an established pattern, layering through many small counterparties — and each needs history and context rather than the current transaction alone. The engineering shape is therefore a feature store keyed by party with rolling windows, a rules engine whose versions are retained so a decision can be reproduced, and a queue with investigator assignment, decision rationale, escalation and permanent history. Two constraints define the work: you may not tip off the subject, and false positives dominate volume, so the real problem is raising precision without dropping a true case.

Show me a sanctions screening hit and the false-positive arithmetic.

Screening is the clearest example in banking of a control whose costs are operational rather than computational.

Outbound payments screened, one month: 1,000,000
Fuzzy name matching, threshold tuned to catch transliteration variants

  alerts raised                     4,200     0.42% of volume
  confirmed true matches                3
  false positives                   4,197     99.93% of alerts
  analyst time per alert              4 min
  review effort                     280 hours ~2 full-time analysts

Raise the threshold to cut the queue:

  alerts raised                     1,200
  false positives                   1,198
  true matches missed                   1     <- a sanctions breach
  effort saved                      200 hours per month
  cost of the miss                  fine, licence risk, personal liability

The asymmetry is the answer. Two hundred analyst hours a month is a real cost with a known price, and a single missed designated party is an unbounded one, so the threshold cannot be tuned by optimising a single accuracy metric. Anyone who proposes trading recall for precision here has not understood what the control is for, and saying so unprompted is worth more than knowing the matching algorithm.

The engineering answer is to reduce false positives without moving the threshold. Resolved matches are whitelisted per party and per list version, so the same supplier is not re-alerted every month, and the whitelist is invalidated whenever the list changes because the entry may now be a genuine hit. Secondary attributes discriminate where names cannot: date of birth, country, and a structured address turn "Ali Hassan" from a match into a mismatch, which is one of the strongest practical arguments for ISO 20022's structured party data.

The reproducibility requirement is the one candidates miss. A screening decision must be replayable years later, so you retain the list version, the matching configuration, the score, the decision and the analyst, not merely the outcome. A regulator reviewing a payment from 2024 will ask why it was released, and "the current engine says it is fine" is not an answer about 2024.

Note also where screening sits in the flow. It runs before submission to the rail, which makes it a synchronous dependency on the payment path with a human in the loop, and that is exactly how a payment misses a cut-off — which is a different worked item and the same root cause.

What is perpetual KYC, and why is it a data problem?

The move from re-verifying customers on a fixed cycle — high risk yearly, low risk every five years — to continuously re-evaluating risk as evidence changes. It exists because periodic review is simultaneously wasteful and late: most files are reviewed when nothing has changed, and the file that mattered went stale eleven months before its review date. Engineering-wise it turns onboarding data into a living entity with triggers: an address change, a new director, a screening list update, a change in transaction behaviour, an adverse-media hit, an expiring document. Each trigger re-scores the party and may open a review case. What makes it hard is that the evidence lives in a dozen systems and the triggers arrive as events, so you need a party-level event history and a risk model that can be recomputed and explained, not a last_reviewed date.