BillDateDetectorService — bill-date detection (read half of workflow #2)
Workflow #2's read/detect front half: scans recent QBO bills for the receipt-date signature (TxnDate = the day the bill was created in QBO) and returns candidates for human review.
Overview
src/workflows/bill-date-correction/bill-date-detector.service.ts. The Fishbowl→QBO sync sets a pushed bill’s TxnDate to the warehouse receipt date — by
design, not a bug (QBO audit gotcha #1), and Fishbowl pushes on receipt, so an uncorrected bill’s
ledger date equals the day it landed in QBO. One vendor read (Accounting Read (customers · bills · reports · aging)Accounting Read (customers · bills · reports · aging)Queryv0.1.0QBO customers, bills (creation-window queries for the bill-date detector), cash-flow/P&L reports and AR/AP aging (OAuth2...Ownervisionary-engineeringMapView docs — bills
created in the scan window, filtered server-side on MetaData.CreateTime), one comparison, no
writes.
Honest limits, carried in the tool output: the match is a heuristic (a same-day manual bill matches too — candidates are leads, not verdicts), and the correct invoice date is NOT in QBO — a human confirms it before each fix is queued via Propose Bill-Date CorrectionPropose Bill-Date CorrectionCommandv0.1.0Workflow #2 — the next-day QBO follow-up: correct a bill's TxnDate/DueDate to the vendor invoice date. Queued for approv...Ownervisionary-engineeringSchemaMapView docs. Detection and correction together are the full workflow #2: detect → confirm → propose → approve → sparse update (BillDateCorrectionApplier (workflow #2)BillDateCorrectionApplier (workflow #2)Servicev0.1.0Applies an approved bill-date correction: re-fetches the bill for a fresh SyncToken, then sparse-updates the one date fi...Publishesaccounting-read, qbo-update-billSubscribesproposal-approvedOwnervisionary-engineeringMapRepoView docs).
Layering: MCP tool → this workflow service (orchestration, cross-system joins) → foundational services (clean domain models, vendor envelope stripped) → clients (raw vendor APIs) — each behind DI, every connector swappable to fixtures via *_USE_MOCK.
CQRS note: reads are the “typical reactions” side — normal request/response, no event lifecycle. Only commands flow through the Approval Bus (command service — owns the queue)Approval Bus (command service — owns the queue)Servicev0.1.0The command side: owns the proposal queue. propose_* only queue; a cleared human approves in the card; only then does th...Publishesproposal-created, proposal-approved +3Subscribespropose-vendor-bill, propose-bill-date-correction +6Ownervisionary-engineeringMapRepoView docs.