Portal project-detail 500 for API-key callers — fixed
Date: 2026-07-16
Commit: entirely-api 24a1909 (routes/portal_projects.py)
GET /portal/projects/{record_id} uses get_current_portal_user_or_api_key, which returns user=None for API-key auth. Two spots called user.get() unguarded, so every API-key request for a non-archival project 500’d with AttributeError: 'NoneType' object has no attribute 'get' (seen twice 2026-07-16 on MAN-9126 / 5abfc3901ed1b3aa9b8a94cc):
- The live-invoice-estimate triage check (
user.get("role") != "triage"). _strip_financials(user, result)— would have crashed identically once (1) passed.
Fix: API-key callers (user is None) are treated as full-access at both points, matching the account-scoping check earlier in the same handler. Route annotations corrected to Optional[dict]. routes/tracker.py (the only other user of this dependency) already handled None via _upload_allowed — no change needed there.
Verified live post-rebuild: MAN-9126 via API key → 200 with invoice_total present; quick-search → 200; no new tracebacks.
Related: portal-auth, Mostly-platform