Re:Double-Entry Bookkeeping as a Directed Graph
by ectopasm83 on Wednesday April 10, 2024 @12:03PM
(#39992247)
Think of a ledger as a list of transactions.
Transactions are directed hyper-edges: they are composed of a set of credits and a set of debits. For each transaction, the sum of debits must be equal the sum of credits. "Double-sided" might be a better term. Also a DAG doesn't convey the historical aspect of a ledger, each ledger should be conceived as a sequence diagram lifeline. See temporal graphs: https://teneto.readthedocs.io/en/latest/what_is_tnt.html#add...
Going further with this model, you could introduce the notion of higher-order links between transactions to keep related entries together, for instance to link a correcting transaction to the corrected transaction, grouping recurring payments for a loan together and so on.
You could (should!) model this on top of a bitemporal database to overcome the painful limitation of the event sourcing model, namely that corrections aren't retroactive. Imagine you need to establish due taxes for the past year for certain ledgers in your database, and for some of them you performed corrections to transactions for that fiscal period after the fiscal period ended. With an event-sourced model (a single timestamp for each transaction), the corrections won't impact your tax calculations unless you explicilty track those corrections in your query. But with a bitemporal model (two time axis), you'll be able to record both the time when you made the correction and when it should apply in the past and you'll be able to query your database normally, without even thinking about it. This could also be used to perform corrections that remain invisible to your customers while being fully tracked in your db. Another case were this could prove to be useful is with transactions that are not immediate and can be rolled back. Typically in these situations, you move money from one ledger to a counterpart dedicated temporary outgoing ledger before the transaction is confirmed. This allows you to prevent double spending. Using a bitemporal model, you could get rid of these temporary counterpart ledgers provided you add a status field to your transactions.
Going further with this model, you could introduce the notion of higher-order links between transactions to keep related entries together, for instance to link a correcting transaction to the corrected transaction, grouping recurring payments for a loan together and so on.
You could (should!) model this on top of a bitemporal database to overcome the painful limitation of the event sourcing model, namely that corrections aren't retroactive. Imagine you need to establish due taxes for the past year for certain ledgers in your database, and for some of them you performed corrections to transactions for that fiscal period after the fiscal period ended. With an event-sourced model (a single timestamp for each transaction), the corrections won't impact your tax calculations unless you explicilty track those corrections in your query. But with a bitemporal model (two time axis), you'll be able to record both the time when you made the correction and when it should apply in the past and you'll be able to query your database normally, without even thinking about it. This could also be used to perform corrections that remain invisible to your customers while being fully tracked in your db. Another case were this could prove to be useful is with transactions that are not immediate and can be rolled back. Typically in these situations, you move money from one ledger to a counterpart dedicated temporary outgoing ledger before the transaction is confirmed. This allows you to prevent double spending. Using a bitemporal model, you could get rid of these temporary counterpart ledgers provided you add a status field to your transactions.