Upload statements from the web app

The Accounts screen gets an Add statements panel: pick an account, drop
files on it or choose them, and they are saved into that account's folder
and imported. The folder stays the source of truth -- an upload only puts
a file where `money import` looks, then runs the same import as the
Import button, so deleting index.db and re-importing still loses nothing.

Files travel base64 inside JSON rather than as multipart. There is no
auth, and the JSON-only rule is what keeps another site's form from
posting here; multipart is exactly what such a form can send.

An upload never replaces a statement: identical contents are a no-op and
different ones are refused with 409. Names import would not read back --
not a plain file name, dotfiles, account.toml, outside the account's
include patterns -- are refused, and a batch is checked whole before any
of it is written. Files are written through a dotfile and renamed, so a
concurrent import never reads half of one.

The overview now lists the account folders on disk, read fresh so one
created after startup is a valid target; it replaces the configured
count the empty accounts screen used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 18:51:56 +02:00
co-authored by Claude Opus 5.5
parent ec8a844441
commit 7ec9976b80
6 changed files with 489 additions and 22 deletions
+18 -1
View File
@@ -102,7 +102,8 @@ money config # which data root is in use, and why
An account folder appears in the app only once its statements have been
imported — creating an `account.toml` is not enough on its own. Run
`money import` (or press Import in the web app) after adding one.
`money import` (or press Import in the web app) after adding one, or add its
first statements from the Accounts screen, which imports them as it saves them.
`--uniq` turns `ls` into a list of patterns still to write rather than a list of
rows to read: one line per distinct description, since fifty visits to the same
@@ -165,6 +166,22 @@ fresh command would:
Shift-click **Import** for `import --force`.
### Adding statements from the browser
The Accounts screen (`1`) has an **Add statements** panel: pick the account,
drop files on it (or click to choose them) and press **Upload and import**. The
files are saved into that account's folder, exactly where you would have copied
them by hand, and then imported — the folder stays the source of truth, so
deleting `index.db` and re-importing still gets everything back.
An upload never replaces a statement. A file whose name is already in the folder
is skipped if its contents are identical and refused if they differ; rename it
or remove the old one first. Names import would not read back — dotfiles,
`account.toml`, anything outside an account's `include` patterns — are refused
too, and a batch with one bad file writes none of them. The folder itself must
already exist with an `account.toml`: an upload adds statements to an account,
it does not create one.
### Keys
| Key | Action |