WHAT THE NUMBERS DO NOT SAY

Caveats

Three items from the design were left unbuilt because the data does not exist, and eight shipped fields carry a reading that is not the obvious one. Three of those eight will mislead someone eventually.

Not built
3no data to build on
Gotchas
83 actively misleading
New tables
0nor columns, nor crons
Routes changed
0the DTO grew, additively

Deliberately not built3

Each is in the design and absent from the card, because the column behind it does not exist.

↓4 pts 90d health trendnot built

Nothing records historical fleetHealthPct. Needs a snapshot table and a daily job, then 90 days elapsed before it reads true.

Unsupported OS risk drivernot built

No OS or firmware field exists on equipment_models or camp_inventory_items.

End-of-support datesnot built

No such column. eol_data holds booleans only; discontinue_date is per-asset on inventories. Hence supportStatus is a three-state enum rather than a date.

the trend is not a coding task

It is cheap to write and expensive to have: a snapshot table, a daily job, and then ninety days of waiting before the number means anything. If it is ever wanted, the useful move is to start recording now and build the card against it later — every day of delay is a day added to the end.

Gotchas worth knowing8

Ordered by how likely each is to be read wrongly.

fleetHealthPctreads wrong

Counts only Healthy. Potential Risk and Retired are in neither bucket, so health % + at-risk % ≠ 100 — which is exactly what a reader will assume.

avgAgeYearsreads wrong

An asset with no usable purchase date contributes age 0, not NULL. Poor date coverage makes a category read younger — the wrong direction for a risk signal.

topEquipment[]reads wrong

equipment_model_id is nullable, so every unlinked asset collapses into one row that competes on count and can look like a model without being one.

supportStatusworth knowing

If the EOL pipeline has not run, reads Supported everywhere — a coverage artefact, not a fact.

replacementCostDueWithin12Moworth knowing

Deliberately disagrees with the “Nearing EOL” risk tag: the tag is year-granular, this window is date-granular.

replacementCostDueWithin12Moworth knowing

Assets with no purchase_date are anchored to 1 January of purchase_year, so they enter the window early.

totalReplacementCostworth knowing

An AI benchmark for a new unit — not what was actually paid.

topEquipment[]worth knowing

A row that resolves to no name is skipped, so a card may show fewer than four models.

What the change does not touchscope

migrations & schemanone

No new table, column or cron.

tables usedall pre-existing

camp_inventory_items, equipment_models, equipment_categories, service_contracts, manufacturers, work_orders.

existing outputsunchanged

TierTotal.manufacturerCount is mathematically unchanged despite its query being restructured — checked rather than assumed.

routesnone added or removed

The DTO change is purely additive.