Files
pastilhas 7a4859fc28 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.
2026-08-27 17:30:49 +01:00

43 lines
2.2 KiB
Markdown

# 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 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 |
| ------------------ | ------- | ------------------------------------------------------------ |
| `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.