Orders & fulfilment
Order Timeline
Generated from docs/plan/core/order-timeline/PLAN.md in the project's planning notes, which are not part of the public repository. Nothing described below is implemented — it is the written plan for it.
Committed, number 6 in the build order. One history of everything that happened to an order. Bulk actions write to it. The whole list.
This plan takes over all or part of Order Status History, an entry merged into it.
Merchants see fragmented order events scattered across multiple screens. This feature provides a unified chronological timeline showing all order changes, payments, shipments, and notes in one visual place.
Partly built (2026-10-26). The core now ships the timeline:
src/lib/commerce/order-timeline.tsandGET /api/orders/{id}/timeline, tested intests/order-timeline.test.mjs. It covers status, payment, refund, shipment, note and tag events, newest first, 20 at a time, with the actor, a filter and a CSV export. Not built: a “shipment delivered” event (there is no delivered status), a “customer contacted” event, and per-type icons. The timeline is a section on each order in the list, not a tab on an order page. At most 100 stored events are kept per order, oldest dropped first; derived events such as placement and refunds are always kept. This item stays planned until the rest is built or the plan is narrowed.
The problem
I have to jump between order status, notes, history, and payment screens to understand what happened to an order. A single timeline showing everything chronologically would save time and reduce confusion.
What it does
- Merge order_events, notes, shipments, payment_events, and customer interactions into one timeline
- Display timeline as vertical chronological list, newest first, with icons for event type
- Show event types: order placed, status changed, payment captured/refunded, shipment created/delivered, note added, customer contacted
- Include actor (staff member or ‘system’) and timestamp on each event
- Color-code by event type: blue for status changes, green for payments, orange for shipments, gray for notes
- Support timeline filtering (e.g., ‘show only shipment events’) from dropdown
- Show amount in payment events (e.g., ‘Refund: -$50.00’)
- Render timeline responsively so it’s readable on mobile admin views
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Collaborative comments on timeline events (e.g., reply to a shipment event) — that is threading, separate feature
- Animated timeline playback or scrubbing through time — that is UX complexity, defer to plugin
- Predictive timeline (e.g., ‘next event estimated at: X time’) — that requires ML/automation, separate
Data model
No new schema; order-timeline aggregates data from order_events, notes, shipments, payments collections. Computed view only.
API
- GET /api/admin/orders/:orderId/timeline — fetch aggregated timeline events
- GET /api/admin/orders/:orderId/timeline?filter=shipments — fetch filtered timeline events
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Order detail page includes ‘Timeline’ tab. Vertical chronological list showing: (1) event timestamp, (2) event type icon (status, payment, shipment, note), (3) event summary (‘Status changed: processing → shipped’), (4) actor name (‘John Admin’ or ‘system’), (5) details when expanded (e.g., tracking number for shipment). Dropdown filter: ‘All Events’, ‘Status’, ‘Payments’, ‘Shipments’, ‘Notes’.
The seam — why this is core
Core owns timeline aggregation and UI. No paid seam — order visibility is infrastructure.
Core owns the interface + honest timeline renderer; order visibility is infrastructure, not a support commitment or credential.
Dependencies
- order-status-history (order_events collection)
- order-notes collection
- shipment-management-tracking (shipments collection)
- payments collection
- existing admin dashboard
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Fetch order timeline and confirm events are sorted by timestamp, newest first
- Verify all 4 event types (status, payment, shipment, note) appear in timeline if they exist for order
- Filter timeline by ‘shipments’ and confirm only shipment-related events are shown
- Verify actor name is displayed correctly (staff member for manual actions, ‘system’ for automated)
- Verify payment amounts are shown correctly (e.g., ’-$50.00’ for refund)
- Confirm timeline renders correctly on mobile (vertical layout, no horizontal scroll)
Risks
Aggregating events from 4+ collections can be slow for orders with 100+ events. Implement pagination (load 20 events at a time) or lazy-loading on timeline scroll. Timestamp accuracy is critical; ensure all event sources use same timezone.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Shopify: included (Order Timeline); Magento: included |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and CONTRIBUTING.md for how to work on this repository.