Skip to content

Capstone 4 — Banking System

Scope: a term's work · Prerequisites: Modules 1–15


1. Problem statement

A small credit union needs a system of record for its accounts and transactions.

The requirements look simple and are not. Money must never be inexact, so every amount is integer pence. Every balance change must have a matching entry in a ledger, and the ledger must agree with the balances at all times — including after a failure halfway through an operation. Transfers between accounts must either happen completely or not at all, and the system must be able to answer, for any account and any date, what the balance was on that date.

The system is stopped and restarted daily, and its data file has been edited by hand at least once in the past.


2. Actors

Actor What they do What the system owes them
Teller Opens accounts, deposits, withdraws, transfers Operations that either complete or leave nothing behind, and a receipt
Customer Checks a balance, lists transactions, requests a statement The same balance every time it is asked, and a statement that reconciles
Auditor Reconciles the ledger against the balances An append-only ledger, and the ability to reconstruct any balance

3. Use cases

  1. Open an account, in one of several kinds (current, savings, fixed-term).
  2. Deposit and withdraw, with the balance never going negative where the account forbids it.
  3. Transfer between two accounts, atomically — either both entries exist or neither does.
  4. Compute interest, at a rate that depends on the account kind and the balance band.
  5. Apply a charge that depends on the account kind (a fixed-term withdrawal fee, for example).
  6. List transactions for an account, and compute the balance on a given date.
  7. Produce a statement for a period, showing an opening balance, entries and a closing balance.
  8. Refuse an operation and say why: insufficient funds, account closed, limit exceeded.
  9. Save and load everything; refuse a corrupted file with a line number and no partial state.

4. Suggested classes

Class Responsibility, in one sentence Notes
Money An exact amount in pence, with the arithmetic that is allowed A value type: no double, no rounding errors
AccountKind What differs between kinds: overdraft allowed, interest rate, withdrawal fee An interface or a value used by policies
Account One account's identity and current balance Exposes operations, never a settable balance
Ledger The append-only list of entries, and the source of truth Owns its entries
Entry One dated posting against one account, with a running balance Immutable once constructed
Transaction One operation that may post several entries, atomically The unit of the "all or nothing" rule
InterestPolicy Turns a balance and an account kind into interest Injected; the thing that varies
FeePolicy Turns an operation and an account kind into a charge Injected
Statement A rendered period for one account A projection, computed from the ledger
Bank Coordinates operations and owns accounts and the ledger Where atomicity is enforced

The class worth the most marks is Transaction. Atomicity in a single-threaded C++ program means: build the entries, validate everything, and only then apply them — so that an exception during validation leaves nothing behind. The design has to make "apply" a single step that cannot fail, and the test that proves it passes an operation that fails mid-way and shows the ledger unchanged.


5. Relationships

   Bank ◆── vector<Account>        composition
   Bank ◆── Ledger                 composition: one ledger for the institution
   Ledger ◆── vector<Entry>        composition, and append-only
   Entry ────> Account             association: an entry refers to an account it does not own
   Account ┈┈> AccountKind         dependency
   Bank ┈┈> InterestPolicy         dependency, injected
   Bank ┈┈> FeePolicy              dependency, injected
   Transaction ◆── vector<Entry>   composition: the entries a transaction will post
   Money <value>                   value type; no identity, no inheritance

6. Design constraints

  • No double anywhere in the domain. Report why, and what the alternative in your design is.
  • Balances are derived from the ledger, or maintained alongside it with the ledger as truth. Choose one and say which; two independently maintained answers is the invariant bug this project exists to prevent.
  • Atomicity is enforced in one place: validate fully, then apply in a step that cannot fail. An operation that fails must leave both the ledger and the balances untouched — demonstrated by a test.
  • Interest and fees are policies, injected, so a rate change is a value change rather than a code change.
  • The ledger is append-only. No correction edits an entry; a reversal is a new entry, and both remain visible.
  • A balance on a past date is a query over the ledger, and you must say what it costs in your data structures.
  • Format: a documented text format with a version marker and an escape rule; amounts stored as integers; a file whose marker is from a later version refused, not misread.

7. Milestones

# Milestone Done when
1 Design Diagram; the ledger/balance relationship decided and justified; the atomicity rule located in exactly one place
2 Money and accounts Money usable and tested; accounts with kinds; deposits and withdrawals with refusals
3 Ledger and atomicity Every operation posts entries; a failed operation leaves nothing behind, demonstrated
4 Policies Interest and fees from injected policies, with two implementations each
5 Persistence Documented format; round trip preserving every entry including an empty ledger; three hand-edited corruptions rejected with line numbers
6 Tests and report Ledger and balances agree under a scripted sequence; a deliberate bug caught; the reversal named with its cost

8. Minimum requirements

  • [ ] Money as an exact integer type, with the arithmetic the domain needs and no double
  • [ ] At least two account kinds, differing in overdraft permission, interest and fees
  • [ ] Deposit, withdraw and transfer, each refusing invalid requests with a reason
  • [ ] An append-only ledger, with every balance change matched by an entry
  • [ ] Atomic transfers: a transfer that fails leaves no entry and no balance change — demonstrated
  • [ ] Interest and fee policies injected, with two implementations each
  • [ ] A statement for a period, with an opening and closing balance that reconciles with the entries
  • [ ] Persistence with a version marker and escape rule; a round trip preserving every entry, including an empty ledger
  • [ ] Three hand-edited corruptions rejected with line numbers, leaving the loaded state untouched
  • [ ] At least two patterns, each justified by a named requirement; one declined, with the reason
  • [ ] Tests with assertions covering invariants, boundaries and failure paths
  • [ ] No warnings with -Wall -Wextra -Werror

9. Advanced requirements

  • [ ] A balance on any past date, with the complexity of the query stated and measured
  • [ ] Account closure that forbids further postings but keeps the history visible
  • [ ] Daily interest posting for a whole book, with a check that the total matches the sum of the individual postings
  • [ ] Overdraft limits per account kind, refused at the boundary, with the refusal naming the limit
  • [ ] A third account kind added, with the file count in the report
  • [ ] A reconciliation command that recomputes every balance from the ledger and reports mismatches — which is also the strongest test of your invariants
  • [ ] An audit export of the ledger to CSV behind the same interface as the console output

10. Testing requirements

  • Invariants: every balance equals the ledger's effect on that account; the sum of all postings is zero for a transfer; no double appears in the domain; an entry is never mutated
  • Boundaries: withdrawing exactly the balance; one penny over an overdraft limit; a zero-amount operation; a transfer between the same account twice; a date query exactly at midnight of a posting
  • Failure paths: insufficient funds; a transfer where the second posting is invalid; loading a truncated file; a corrupted amount; a negative interest rate
  • Round trip: populated and empty ledgers, every entry compared, including a name containing the separator, and the order of entries preserved
  • One deliberate bug (for example, applying the first posting before validating the second), caught by the suite, with the failing assertion kept

11. Extension ideas

  • Scheduled payments, with a rule for what happens on a day the system is not running.
  • Statement export in a second format, behind the same interface.
  • Interest tiers by balance band, added as a policy change with no edits to existing code — count the files.
  • A simple budget: postings tagged by category, summarised per period.
  • Multiple currencies, and the design decision that follows about Money (which the report should discuss, including why it is not in the minimum requirements).
  • A reconciliation report that runs on demand and prints the number of entries checked.

12. Evaluation checklist

  • [ ] The diagram matches the declarations, including multiplicities
  • [ ] grep for double in the domain finds nothing — and the report says why
  • [ ] One source of truth for balances is named, and the other is either derived or proven consistent
  • [ ] A failed operation left the ledger and balances untouched — demonstrated by a test
  • [ ] The ledger is append-only; a correction is a new entry, and both are visible
  • [ ] Interest and fees come from injected policies, and the rate change needed no code edit
  • [ ] A statement reconciles: opening + entries = closing, checked by the program, not by hand
  • [ ] The round trip preserves every entry and its order, including an empty ledger — output pasted
  • [ ] Three corruptions rejected with line numbers, leaving the loaded state untouched
  • [ ] The suite fails when a deliberate bug is introduced
  • [ ] One pattern considered and declined, in writing
  • [ ] The report names the decision I would reverse and the cost of reversing it

Related: Capstone options · Projects and the rubric · Module 16 — Capstone · Module 10 — Copying and Resource Management