- add grouped platform admin hub pages, view models, and shared card UI\n- simplify the super admin nav and dashboard quick links around the new hubs\n- fix the AiQuoteService EstimatedMinutes assignment so the infrastructure project builds cleanly
Two bugs caused AI estimates to collapse to the shop minimum floor:
1. Coating rate with no guard: when a shop hadn't calibrated their
coating gun (rate = 0), the prompt injected '~0 sqft/hr' paired
with 'MUST use shop-specific rates' — Claude returned near-zero
estimatedMinutes, zeroing labor cost and triggering the floor.
Fixed to mirror the existing blast-rate guard: rate=0 now sends
a fallback instruction to use conservative industry-average times.
2. Per-item minutes divided by quantity: both the system prompt and
user prompt explicitly tell Claude to return estimatedMinutes 'per
single item', but CalculatePricingPreview() was dividing by qty
anyway. For qty > 1 this halved (or more) the labor cost, again
pushing toward the floor. Removed the incorrect divide.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Anthropic returns overloaded_error (HTTP 529) during high-demand periods.
Previously this failed immediately with a generic error. Now the service
retries Sonnet once after 5s, then falls back to Haiku (a separate
capacity pool) after another 3s before giving up. If all three attempts
are overloaded the user sees a clear "high demand" message rather than a
generic error. Non-overload errors still log at Error level.
Also consolidated AI wizard error display in item-wizard.js: photo upload
failures were using browser alert() while analyze failures used the inline
red alert bar. All errors now go through aiShowError() so they always
appear consistently as the red bar below the Analyze button. Removed the
alert() fallback from aiShowError() itself.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PWA: manifest.json + minimal service worker so iOS/Android persist camera
permission after "Add to Home Screen"; theme-color and apple meta tags in layout
- PWA icons: 192x192 and 512x512 from transparent PCL logo; updated pcl-logo.png
- AI pricing: apply AdditionalCoatLaborPercent per extra coat on AI items,
matching the calculated-item path (was ignoring extra coats entirely)
- AI wizard: live price recalc when coats are added/removed; session-expiry
errors now show a clear "refresh and sign in" message instead of raw HTTP status;
smooth-scroll to follow-up/results sections on AI response
- Catalog lookup: exclude SKUs already in company inventory from results;
pass currentId on edit so own entry still appears; vendor-scoped search
with cross-vendor fallback; result count shown in multi-match modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>