feat(package): one attention engine over PackageBooks (U0b)
Needs attention was computed by the viewer alone, while books.start hand-picked a handful of next steps. The human's list and the agent's could disagree, and a new item had to be written twice (or, as books.start showed, not at all). Move the engine to ledger-package over PackageBooks: one function, find/find_with(books, today, settings, integrity), reads the ledger, the journal's event types (an entry's origin), the attachments and their links, the statements, the reconciliations, and the database check. The viewer's attention module now only maps Target to Route; books.start turns the same items into its next steps (why = the item's title, top 12), so the list the human sees and the steps the agent gets cannot drift. PackageBooks gains settings, journal, statements, reconciliations and disk_check, implemented for Store and Snapshot, so both views answer alike. The W-9, reconciliation and 1099 predicates move beside the items to keep one copy. ledger-package gains ledger-config and serde_json (the receipt policy and the tool arguments the items carry). Tests: view_model.rs and spec_kept.rs pass unchanged; the new attention_parity.rs compares the viewer and books.start item for item on the demo books and on a book written entry by entry. just check green.
This commit is contained in:
1 parent
eeee9658da
commit
0cf2f8f5c5
17 files changed
+2026
-895
No files matched your search
@@ -9,10 +9,12 @@ description = "wanderbooks' CPA handoff package and the reports and worksheets i
|
||||
[dependencies]
|
||||
ledger-core = { path = "../ledger-core" }
|
||||
ledger-store = { path = "../ledger-store" }
|
||||
ledger-config = { path = "../ledger-config" }
|
||||
ledger-import = { path = "../ledger-import" }
|
||||
ledger-vault = { path = "../ledger-vault" }
|
||||
chrono = "0.4"
|
||||
rust_decimal = "1"
|
||||
serde_json = "1"
|
||||
zip = "9.0.1"
|
||||
|
||||
[lints]
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -9,22 +9,40 @@
|
||||
//! INVARIANTS:
|
||||
//! 1. Every method only reads.
|
||||
//! 2. A Store and a Snapshot of the same journal answer every method
|
||||
//! alike: the same ledger, journal seq, attachments (withdrawn ones
|
||||
//! included), entry links, and bytes.
|
||||
//! alike: the same ledger, settings, journal, journal seq,
|
||||
//! attachments (withdrawn ones included), bytes, statements, and
|
||||
//! reconciliations, and the same entry links once the filing entry
|
||||
//! is added (a store lists it in `links_of`; a snapshot only lists
|
||||
//! the explicit links, so callers take the union with
|
||||
//! `all_attachments`, as `build_package` and the attention module
|
||||
//! do).
|
||||
//! ```
|
||||
|
||||
use ledger_core::Ledger;
|
||||
use ledger_store::{Attachment, Snapshot, Store, StoreError, Subject};
|
||||
use ledger_store::{
|
||||
Attachment, DiskCheck, JournalLine, Reconciliation, Snapshot, Statement, Store, StoreError,
|
||||
Subject,
|
||||
};
|
||||
|
||||
/// The books, read-only, as the CPA package reads them.
|
||||
/// The books, read-only, as the package reads them.
|
||||
pub trait PackageBooks {
|
||||
/// The ledger every figure comes from.
|
||||
fn ledger(&self) -> &Ledger;
|
||||
|
||||
/// The settings journaled in the books (the same ones the server and
|
||||
/// the viewer read).
|
||||
fn settings(&self) -> &ledger_core::settings::Settings {
|
||||
self.ledger().settings()
|
||||
}
|
||||
|
||||
/// Sequence number of the last journal line: the journal state the
|
||||
/// package reflects.
|
||||
fn journal_seq(&self) -> u64;
|
||||
|
||||
/// Every journal line, in order: what an entry's origin and its events
|
||||
/// are read from.
|
||||
fn journal(&self) -> Result<Vec<JournalLine>, StoreError>;
|
||||
|
||||
/// Every attachment (receipts and documents), withdrawn ones
|
||||
/// included, in id order.
|
||||
fn all_attachments(&self) -> Result<Vec<Attachment>, StoreError>;
|
||||
@@ -36,6 +54,20 @@ pub trait PackageBooks {
|
||||
|
||||
/// An attachment's bytes, verified against its hash.
|
||||
fn attachment_bytes(&self, attachment_id: u64) -> Result<Vec<u8>, StoreError>;
|
||||
|
||||
/// Recorded bank and card statements, by period end.
|
||||
fn statements(&self) -> Result<Vec<Statement>, StoreError>;
|
||||
|
||||
/// Reconciliations, voided ones included, by date then id.
|
||||
fn reconciliations(&self) -> Result<Vec<Reconciliation>, StoreError>;
|
||||
|
||||
/// How the writer's database compares with the journal. A snapshot
|
||||
/// compares them; the store is the only writer and applies each line
|
||||
/// before it returns (a failed apply heals on its next open), so it
|
||||
/// reports a match.
|
||||
fn disk_check(&self) -> DiskCheck {
|
||||
DiskCheck::Matches
|
||||
}
|
||||
}
|
||||
|
||||
impl PackageBooks for Store {
|
||||
@@ -47,6 +79,12 @@ impl PackageBooks for Store {
|
||||
Store::journal_seq(self)
|
||||
}
|
||||
|
||||
fn journal(&self) -> Result<Vec<JournalLine>, StoreError> {
|
||||
ledger_store::journal::read_and_verify_journal(
|
||||
&Store::data_dir(self).join(ledger_store::JOURNAL_FILE),
|
||||
)
|
||||
}
|
||||
|
||||
fn all_attachments(&self) -> Result<Vec<Attachment>, StoreError> {
|
||||
Store::list_attachments(self, None)
|
||||
}
|
||||
@@ -58,6 +96,14 @@ impl PackageBooks for Store {
|
||||
fn attachment_bytes(&self, attachment_id: u64) -> Result<Vec<u8>, StoreError> {
|
||||
Store::attachment_bytes(self, attachment_id)
|
||||
}
|
||||
|
||||
fn statements(&self) -> Result<Vec<Statement>, StoreError> {
|
||||
Store::statements(self, None)
|
||||
}
|
||||
|
||||
fn reconciliations(&self) -> Result<Vec<Reconciliation>, StoreError> {
|
||||
Store::reconciliations(self, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl PackageBooks for Snapshot {
|
||||
@@ -69,6 +115,10 @@ impl PackageBooks for Snapshot {
|
||||
Snapshot::journal_seq(self)
|
||||
}
|
||||
|
||||
fn journal(&self) -> Result<Vec<JournalLine>, StoreError> {
|
||||
Ok(Snapshot::journal(self).to_vec())
|
||||
}
|
||||
|
||||
fn all_attachments(&self) -> Result<Vec<Attachment>, StoreError> {
|
||||
Snapshot::attachments(self, None)
|
||||
}
|
||||
@@ -84,4 +134,16 @@ impl PackageBooks for Snapshot {
|
||||
fn attachment_bytes(&self, attachment_id: u64) -> Result<Vec<u8>, StoreError> {
|
||||
Snapshot::attachment_bytes(self, attachment_id)
|
||||
}
|
||||
|
||||
fn statements(&self) -> Result<Vec<Statement>, StoreError> {
|
||||
Snapshot::statements(self, None)
|
||||
}
|
||||
|
||||
fn reconciliations(&self) -> Result<Vec<Reconciliation>, StoreError> {
|
||||
Snapshot::reconciliations(self, None)
|
||||
}
|
||||
|
||||
fn disk_check(&self) -> DiskCheck {
|
||||
Snapshot::check_disk(self)
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
//! whichever [`PackageBooks`] they are read through.
|
||||
//! ```
|
||||
|
||||
mod attention;
|
||||
mod books;
|
||||
mod iif;
|
||||
mod invoice;
|
||||
@@ -33,6 +34,10 @@ mod text;
|
||||
mod tins;
|
||||
mod vendor_1099;
|
||||
|
||||
pub use attention::{
|
||||
Attention, Integrity, Report, Severity, Target, files_1099, find, find_with, reconcile_prompt,
|
||||
w9_missing, w9_prompt,
|
||||
};
|
||||
pub use books::PackageBooks;
|
||||
pub use iif::export_iif;
|
||||
pub use invoice::invoice_document;
|
||||
|
||||
@@ -1264,6 +1264,9 @@ impl PackageBooks for AtSeq<'_> {
|
||||
fn journal_seq(&self) -> u64 {
|
||||
self.1
|
||||
}
|
||||
fn journal(&self) -> Result<Vec<ledger_store::JournalLine>, ledger_store::StoreError> {
|
||||
PackageBooks::journal(self.0)
|
||||
}
|
||||
fn all_attachments(&self) -> Result<Vec<ledger_store::Attachment>, ledger_store::StoreError> {
|
||||
PackageBooks::all_attachments(self.0)
|
||||
}
|
||||
@@ -1273,6 +1276,14 @@ impl PackageBooks for AtSeq<'_> {
|
||||
fn attachment_bytes(&self, id: u64) -> Result<Vec<u8>, ledger_store::StoreError> {
|
||||
PackageBooks::attachment_bytes(self.0, id)
|
||||
}
|
||||
fn statements(&self) -> Result<Vec<ledger_store::Statement>, ledger_store::StoreError> {
|
||||
PackageBooks::statements(self.0)
|
||||
}
|
||||
fn reconciliations(
|
||||
&self,
|
||||
) -> Result<Vec<ledger_store::Reconciliation>, ledger_store::StoreError> {
|
||||
PackageBooks::reconciliations(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// [`books`] with equipment accounts and a bank fee dated `as_of` with its
|
||||
|
||||
Reference in new issue
Block a user