Ledger travel (as-of audit)
Ledger travel lets staff and auditors view commerce ledgers as they existed at a specific moment in the past. The desk rebuilds figures from append-only history: accounting journals use posted_at; inventory stock uses each movement’s at timestamp.
Use it when you need to answer questions like “What did our trial balance show on 14 June at 04:12 UTC?” or “How many units did we show in stock before that manual adjustment?”
Where to open it
The Ledger travel button appears on:
| Surface | Route |
|---|---|
| Accounting (chart, journals, trial balance) | /dxp/accounting/* or /dxp/core/accounting/* |
| Products list | /dxp/products |
| Product editor | /dxp/products/edit?id=… |
Same commerce ledger module gate as Accounting — staff only.
How to use
- Open Ledger travel (toolbar on accounting or products).
- Set As of (UTC) — date and time in UTC (second precision).
- Click Travel to.
The desk enters historic mode:
- A banner shows the instant you are viewing.
- Trial balance and Journals (on accounting screens) reload with only entries posted on or before that instant.
- Stock on the products table and product editor balance updates to counts from movements on or before that instant.
- Click Return to now to leave historic mode and restore live figures.
Your last as of choice is remembered for the session (sessionStorage) until you clear it or return to now.
What is time-travelled (and what is not)
| Data | At as-of | Notes |
|---|---|---|
| Trial balance totals | Yes | Aggregated from journals with posted_at ≤ as_of |
| Journals list | Yes | Filtered to the same window when you travel |
| Product stock (list + editor) | Yes | Sum of inventory ledger rows with at ≤ as_of |
| Chart of accounts names/types | No | COA rows are current metadata; only balances and stock rewind |
| Product prices / sale windows | No | Use Products for pricing; ledger travel is stock + accounting only |
Accounting consolidation still applies: when a Space uses a parent ledger book, travel uses that consolidated book the same way live views do (Accounting → Consolidation).
Events near this instant
After you travel, the slide-in lists events near this instant (default window about five minutes centred on your chosen time):
- Inventory lines from the per-Space
audit_log(inventory.append). - Journal entries in the book for that period.
Click an event to open Detail:
| Tab | Contents |
|---|---|
| Summary | Who, when, memo, and notes for inventory or journal rows |
| Partner webhook | JSON envelope from commerce_webhook_intent (core) or engine webhook_outbox (billing), when an event_id is available |
| Hub stream | Decoded hub event from engine hub_event_log when the commerce path published a cursor (stock/price fan-out) |
Use Partner webhook when reconciling with an integration or payment provider. Use Hub stream when you need the exact payload edges may have received. Copy JSON copies the active tab’s payload.
Hub events are persisted when the engine runs with billing Mongo and commerce writes publish through the hub (new installs from the ledger-travel release onward). Older moments may have webhook envelopes but no hub row.
APIs (staff automation)
All routes require the same staff + commerce ledger gate as accounting. Optional ?scope=core on workspace-scoped books.
| Method | Path | Purpose |
|---|---|---|
| GET | /dxp/api/ledger-travel/snapshot?as_of=RFC3339 | Trial balance + optional product_ids=id1,id2 stock map |
| GET | /dxp/api/ledger-travel/events?as_of=RFC3339&window_sec=300 | Audit + journal rows near the instant |
| GET | /dxp/api/ledger-travel/envelope/:event_id | Partner webhook JSON (core intent, else billing outbox) |
| GET | /dxp/api/ledger-travel/webhook-outbox/:event_id | Billing webhook_outbox row only |
| GET | /dxp/api/ledger-travel/hub-event?cursor=N | Hub event by cursor |
Accounting JSON APIs also accept as_of as an alias for posted_before on trial balance and journals:
GET /dxp/api/accounting/trial-balance?as_of=2025-06-14T04:12:00ZGET /dxp/api/accounting/journals?as_of=2025-06-14T04:12:00Z
Typical audit workflow
- Note the discrepancy date from finance or a stock-take.
- Open Trial balance or Products, open Ledger travel, and travel to just after the last known-good posting.
- Step forward in small increments if needed (adjust the datetime and Travel to again).
- Open Events near this instant and inspect Manual journals or inventory.append rows.
- Open Partner webhook / Hub stream on the suspect event to compare with external systems.
- Return to now when finished so day-to-day operations see live data.
Limits
- Not full bi-temporal accounting (no separate “valid time” vs “transaction time” axes). One timestamp per journal or inventory row is the bound.
- Large books: snapshot uses indexed aggregations; the UI loads on-screen product ids only, not the entire catalogue history.
- Chart screen does not change when travelling — open Trial balance or Journals for financial as-of views.
Related
- Accounting — chart, journals, trial balance, consolidation
- Products — inventory adjustments and stock history on the product editor
- Observe → Webhooks — outbound event types (
commerce.inventory.adjusted,accounting.journal.posted, …) - Troubleshooting — engine unavailable or 403 on ledger APIs