- Vendor
- Umbrella Logistics
- Cost center
- CC-4021
- Payment terms
- Net 30
- Total
- $12,400.00
- Requested
Pattern: record detail
Who uses it: whoever owns this record, checking its status or adding to its history — a buyer, an approver, anyone who clicked in from a list row. How often: every time a list row is opened — this is the default landing for "tell me about this one," many times a day across a team. What "done" looks like: the current state is read in one glance, without opening anything else. The composed detail screen behind any list row: record cards, a status timeline, and an audit trail stacked in a feed — all standard components, generic to any ERP. This example is a purchase order; the shape is the same for an invoice, a change request, or a leave request. Not once the record stops fitting in one scan — when a reader has to hunt for a section, it wants anchor navigation and a sticky action bar, which is object page. Same content, different reading problem.
The screen
Purchase order PO-88213 Approved
Status
- Completed: Requested
- Completed: Approved
- Receiving
- Not started: Invoiced
Audit trail
- R. Vance raised PO-88213
- J. Kim approved"Within CC-4021 budget."
- M. Okafor changed 2 fields on receipt
Fields changed on this receipt Field Old New Change Qty received 3 5 Modified Status Partial Partial Modified
The document frame — measured, not asserted
An ERP document screen is read far more often than it is edited, so the chrome above the content is a recurring tax. The shape here is one identity line — what the document is, which one, what state it is in, and the actions — then the facts, then the content:
| Region | 1440px | 390px | Note |
|---|---|---|---|
| Identity line | 36px | 68px | one row on desktop; actions wrap to a second row on a phone |
| Facts strip | 124px | 277px | five facts, auto-fit — this is content, not chrome, and it scrolls |
| Facts strip before | 127px | 331px | six facts: Status was repeated here and in the line above |
Zero new components. The identity line is a split cluster holding the type badge, the record number and a status badge — all shipped. A dedicated document-header component would be a second way to do what a cluster already does.
Two rules worth keeping: status lives in the identity line, not in the facts — it was in both, which cost 54px at phone width for a fact the reader had already seen; and put the actions in the line, not in a bar of their own, because a separate action bar is another band of chrome competing for the same vertical space. The detail form uses the same line; before this it had no identity region at all, so nothing on screen said which purchase order you were editing.
Anatomy
- Breadcrumb — breadcrumb; where this record sits, and how users get back to the filtered list.
- Facts strip — key-value facts (
.bo-kv) for the header facts (vendor, cost centre, total): display data, never readonly inputs. - Record feed — one card per related document (order, receipt, invoice) in chronological order.
- Status timeline + audit trail — timeline and audit trail: where it is now, and every state change with actor and timestamp. This is the human-monitoring signal: the actor column is where an agent's own changes become visible to the human owning the record.
Follows the review-screen anatomy contract — this is the short-record shape; see that page for when to reach for object page or approval instead.
Data contract
| Request | Returns / on failure |
|---|---|
| GET /po/:id | the full screen. 404 → the not-found screen, same as any deep link to a record that no longer exists |
| POST /po/:id/records | one new card fragment appended to the feed |
| GET /po/:id/audit?after=… | newer audit entries for polling; empty body when nothing changed. 5xx/timeout: the per-section alert in States, not a page-level failure — the facts strip and feed already rendered and must stay readable |
The AI-manages / human-monitors split, stated: any actor — human or agent — can append to the feed or the audit trail through the same endpoints; the human's channel is the audit trail's actor column, where an automated change is as visible as a person's.
States
| State | What ships |
|---|---|
| Loading | skeleton cards in the feed; the facts strip renders from the record itself, so it never blanks |
| Empty feed | the record exists with no related documents yet — say so and offer the first action |
| Error loading a section | a per-section alert; one failed audit fetch must not blank the record |
| Read-only | no composer, no action buttons — the timeline and facts are the whole screen |
| Stale (someone else acted) | poll or push the timeline fragment; a decided record showing "awaiting approval" is the failure mode to avoid |
| No JS | fully functional — this page has no JS dependency. Every card, the status timeline, the audit trail and the field-diff table are static markup; the composer's "Add" control has no <form> wrapper or script wiring either way, so it is illustrative only, never a working control, regardless of JS |
Components used
complexity 1 of 4