2026 04 13 Task Cost Display Four Decimals Design
Task / scorecard cost display: four decimal USD (no millidollars)
Context
The AI Route Hub shows average per-candidate cost in the task routing scorecard (TaskRoutingScorecardTable) and rolled-up cost on the task detail overview (TaskDetail). A local formatCost helper currently switches to a millidollar representation when cost < 0.001 (suffix m, value × 1000). Other task-detail surfaces already show cost as $ plus four fractional digits (toFixed(4)).
Goal
Remove millidollar formatting. Always show cost as a USD amount with exactly four digits after the decimal, e.g. $0.0007 or $0.0000 when rounding would zero it out at that precision.
Formatting choice (confirmed)
Option B — plain template: use `${value.toFixed(4)}` (no Intl / formatUsd), so values stay ungrouped and align cleanly with tabular-nums. Product assumption: these fields are not expected to reach thousands of dollars.
Approaches considered
-
Minimal change — duplicate logic
Delete thecost < 0.001branch in both files; keep two identicalformatCostimplementations.
Pros: Smallest diff. Cons: Duplication drifts over time. -
Recommended — shared helper in
src/lib/currency.ts
Add a small exported function, e.g.formatOptionalUsdPlainFourDecimals(cost: number | null): string, returning the em dash ("\u2014") fornulland`${cost.toFixed(4)}`otherwise. Import fromTaskRoutingScorecardTableandTaskDetail; remove localformatCost.
Pros: Single definition, matches chosen plain style, lives next to other currency helpers. Cons: One new export to name and test. -
Inline at call sites
ReplaceformatCost(x)with ternary +toFixedat each use.
Pros: No new API. Cons: Repeated null/em-dash logic, easier to get wrong.
Recommendation: approach 2.
Behavior specification
| Input | Output |
|---|---|
null |
Em dash — (U+2014), same as today |
| Any finite number | $ + Number#toFixed(4) (standard IEEE-754 rounding as implemented by JavaScript) |
No special branch for “very small” costs. Values that round to zero at four decimals display as $0.0000.
Scope
src/components/TaskRoutingScorecardTable.tsx— cost column.src/pages/TaskDetail.tsx— overview rollup cost usingformatCost; keep existing metadata / table cells that already usetoFixed(4)unless consolidating into the helper is trivial in the same change.
Out of scope: Tasks.tsx list (formatUsd for avg_cost_usd), billing UI, or API changes.
Testing
- Add unit tests in
src/lib/currency.test.tsfor the new helper:null→ em dash; very small cost0.0000007→$0.0000;0.00005→$0.0001;0.01234→$0.0123(matchesNumber#toFixed(4)). - Run
npm run test(or targeted vitest forcurrency.test.ts).
Implementation plan
Follow-up: use the writing-plans skill to produce a short implementation checklist (helper + imports + tests).