Money is a bigint of minor units and the sign carries the direction. No stored balance, no user_id denormalised onto transactions, category as free text until budgets need it to be a table. Not pushed to the database yet.
Finances
Money, on your own machine.
This is a skeleton with a data model. The repository, the mount prefix (/finances, /api/finances)
and the permission key (finances) are settled. db/schema.ts proposes the ledger — accounts,
transactions and imports — and has not been pushed to the database. The two panels still render a
placeholder and the one route answers GET /api/finances/ping.
Published in this state on purpose: the identity of a plugin is the part that is expensive to change later, and the feature is the part that is cheap to add.
The ledger, in three tables
finances_accounts— what a balance is of. No stored balance: it isopening_balanceplus the transactions, computed on read, because a stored one drifts silently.finances_transactions— the lines. Money is abigintof minor units and the sign carries the direction; negative leaves the account.finances_imports— one row per CSV import, so a run mapped wrong can be undone in one delete rather than by hand.external_idon a transaction makes re-importing an overlapping statement safe, which is the normal case rather than the exception.
What it ships
| Part | Present | Note |
|---|---|---|
manifest.ts |
yes | identity, one permission |
api/router.ts |
yes | one route, mounted at /api/finances |
web/ |
yes | two placeholder panels and a layout |
db/schema.ts |
yes | accounts, transactions, imports — written, NOT pushed yet |
sidecar/ |
no | nothing long-lived yet |
assets/icon.png |
no | the dock falls back to the manifest's lucide Wallet |
Installing
It is on disk and not installed until you install it from /plugins. Being in the tree makes it appear
on that page; it mounts nothing until then.
Further reading
plugins/example in the platform repo is the reference plugin and documents every convention this one
follows.