fix(core,store): child accounts share their parent's type; periods nest; lines checked when added
Three spec decisions from Stephen (2026-10-13), each test-first:
- A child account has its parent's type (ParentTypeMismatch): a child
subdivides its parent. Test: a_child_account_has_its_parents_type.
- Periods nest (a month in a quarter in a year) but never partially
overlap (PeriodsOverlap; a refusal uses no id). Test:
periods_nest_but_never_partially_overlap.
- A line's account must exist and take postings when the line is added,
not only at post (UnknownAccount / PlaceholderAccount from add_line
and add_line_fx); posting still re-checks. Two older tests that pinned
the post-time refusal now check both (the post-time check is reached
through the unchecked replay path, as old journals can).
Compatibility: replay reads history through new Ledger::replay_*
commands (add_account, add_line, add_line_fx, create_period) that skip
checks added later, so books written before these rules still open.
The contract test books_written_under_older_rules_still_open writes such
a journal directly and found, on its first run, that the SQLite
cross-check rebuild used the checked commands and would have failed
verification ("sqlite projection can't be read back"); it now replays
too. Documented in docs/spec/README.md; decisions recorded in rules.md
(B-1, B-4, B-12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX
This commit is contained in:
1 parent
df38dcccf9
commit
925c3ba523
7 files changed
+362
-12
No files matched your search
@@ -123,6 +123,42 @@ pub enum LedgerError {
|
||||
spec: String,
|
||||
},
|
||||
|
||||
/// A child account subdivides its parent, so it must be the same type
|
||||
/// (Stephen, 2026-10-13).
|
||||
#[error(
|
||||
"account {code} is {found:?}, but its parent {parent_code} is {expected:?}; a child account must be the same type as its parent"
|
||||
)]
|
||||
ParentTypeMismatch {
|
||||
/// The new account's code.
|
||||
code: String,
|
||||
/// The parent's code.
|
||||
parent_code: String,
|
||||
/// The parent's type, which the child must share.
|
||||
expected: crate::AccountType,
|
||||
/// The type the child was given.
|
||||
found: crate::AccountType,
|
||||
},
|
||||
|
||||
/// Periods nest (a month in a quarter in a year) but never partially
|
||||
/// overlap (Stephen, 2026-10-13).
|
||||
#[error(
|
||||
"period {name} ({start} to {end}) partially overlaps period {other} ({other_start} to {other_end}); periods may nest, but not overlap"
|
||||
)]
|
||||
PeriodsOverlap {
|
||||
/// The new period's name.
|
||||
name: String,
|
||||
/// Its first day.
|
||||
start: chrono::NaiveDate,
|
||||
/// Its last day.
|
||||
end: chrono::NaiveDate,
|
||||
/// The existing period's name.
|
||||
other: String,
|
||||
/// The existing period's first day.
|
||||
other_start: chrono::NaiveDate,
|
||||
/// The existing period's last day.
|
||||
other_end: chrono::NaiveDate,
|
||||
},
|
||||
|
||||
/// The referenced journal entry does not exist.
|
||||
#[error("entry {0} does not exist")]
|
||||
UnknownEntry(u64),
|
||||
|
||||
Reference in new issue
Block a user