Remove the transfer flag
A transfer was a second verdict carried alongside the tag: a boolean set by transfer = true in a rule or by x in the TUI, kept in its own pair of rule_ and manual_ columns, whose one real effect was to hold the row out of the report. The rest of it was display -- a T column in the transaction list, in the rules screen and in money ls. Money moved between your own accounts is now tagged like anything else and counts like anything else. The leg leaving checking is an outflow and the leg arriving in savings is an inflow, so a report over the whole data root roughly nets out while one scoped to a single account or month does not. That is the price of one verdict per transaction instead of two. A rule now needs a tag, and one that set only transfer = true is refused by number on load. A leftover transfer key beside a tag is ignored, as unknown TOML keys always were, and an index built by an older binary drops both columns when it is opened. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,22 +18,22 @@ internal/parser Parser interface + registry; nlb, revolut, traderepublic
|
||||
internal/store SQLite index (modernc.org/sqlite, no cgo)
|
||||
internal/importer directory walk, dedupe, balance checks
|
||||
internal/rules applies ordered rules to rule_* columns only
|
||||
internal/report per-tag aggregation, transfers excluded
|
||||
internal/report per-tag aggregation
|
||||
internal/tui Bubble Tea models
|
||||
```
|
||||
|
||||
## Invariants
|
||||
|
||||
**Rule verdicts and manual edits never share a column.** `rule_tag` /
|
||||
`rule_transfer` are rewritten wholesale on every retag; `manual_tag` /
|
||||
`manual_transfer` are only ever written by the user. Effective values are
|
||||
`COALESCE(manual_*, rule_*)`. This is what makes `money retag` safe to run at
|
||||
any time, and it is the first thing to preserve when touching the schema or the
|
||||
rules engine. Covered by `TestManualTagSurvivesRetag`.
|
||||
**Rule verdicts and manual edits never share a column.** `rule_tag` is
|
||||
rewritten wholesale on every retag; `manual_tag` is only ever written by the
|
||||
user. The effective tag is `COALESCE(manual_tag, rule_tag)`. This is what makes
|
||||
`money retag` safe to run at any time, and it is the first thing to preserve
|
||||
when touching the schema or the rules engine. Covered by
|
||||
`TestManualTagSurvivesRetag`.
|
||||
|
||||
**Statements are the source of truth; the index is disposable.** Deleting
|
||||
`index.db` at the root of the data directory and re-importing must reproduce
|
||||
everything except manual tags and manual transfer marks.
|
||||
everything except the tags set by hand.
|
||||
|
||||
**Dedupe is by fingerprint**: `sha256(date | amount | normalised description |
|
||||
ordinal)`, where the ordinal distinguishes identical lines *within one
|
||||
@@ -45,7 +45,7 @@ milliseconds. That is the checksum skip working, not a failure.
|
||||
**Money is `int64` minor units**, never a float. Per-account currency, no
|
||||
conversion, and totals are never summed across currencies.
|
||||
|
||||
**First matching rule wins**, so transfer rules belong above general tag rules.
|
||||
**First matching rule wins**, so specific rules belong above general ones.
|
||||
A rule setting both `match` and `type` requires both of them.
|
||||
`config.AppendRule` therefore appends — never prepends — so saving from the
|
||||
rule builder cannot shadow a rule the user wrote by hand.
|
||||
|
||||
Reference in New Issue
Block a user