CalicoParser now tracks how many rows it drops for a blank/N-A covering type
and how many references it drops for not resolving to a portfolio UPRN, exposed
for the load reconciliation report so nothing vanishes silently.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The real Calico export lodges the literal string "N/A" (not an empty cell) for
placeholder rows; _clean_str now treats N/A-family sentinels as no covering, so
the 1,239 placeholders are dropped on parse (5,346 -> 4,107 real observations).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CalicoParser reads the workbook into CalicoAssetCondition rows, drops rows
with no covering type, and groups them by asset reference into CalicoProperty,
resolving each reference to a UPRN via the injected lookup (unmatched dropped).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>