Resourcing page went blank in prod the first time a booking arrived
with a null resourceName (Airtable placeholder rows, or any booking
whose resource lookup didn't resolve). The Project Load per Person
chart's aggregate then crashed on `null.localeCompare(...)` during
sort, and with no error boundary in the tree, React unmounted the
entire route — visible to the user as "loads, then goes blank".
- ProjectLoadPerPerson.aggregate: coerce nullable lookup values to
scalars before keying/sorting; treat empty resourceName as
"Placeholder", missing project name as "Unknown", and NaN totals
as 0.
- New ErrorBoundary component (class — React still requires class
for boundaries) that renders a card with the error message instead
of unmounting the parent.
- Wrap each chart on both Resourcing and Department in its own
ErrorBoundary so a future chart-specific bug only blanks that one
card, not the whole page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>