the ledger schema — accounts, transactions, imports

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.
This commit is contained in:
2026-08-27 17:30:49 +01:00
parent 6e88d849e7
commit 7a4859fc28
2 changed files with 187 additions and 4 deletions
+15 -4
View File
@@ -2,13 +2,24 @@
Money, on your own machine.
**This is a skeleton.** The repository, the mount prefix (`/finances`, `/api/finances`) and the permission
key (`finances`) are real and settled. What the plugin actually does is not written yet — the two panels
render a placeholder and the one route answers `GET /api/finances/ping`.
**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 is `opening_balance` plus the
transactions, computed on read, because a stored one drifts silently.
- **`finances_transactions`** — the lines. Money is a `bigint` of 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_id` on a transaction makes re-importing an overlapping statement safe,
which is the normal case rather than the exception.
## What it ships
| Part | Present | Note |
@@ -16,7 +27,7 @@ later, and the feature is the part that is cheap to add.
| `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` | no | no tables until the data model is settled |
| `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` |