I-1/M-1: introduce resolvedSupplierProjects() private helper on Project
model; rewrite aggregateSyncStatus(), aggregateLastSyncedAt(),
getSupplierLinks() to read from eager-loaded supplierB1/B2/B3 relations
instead of SupplierProject::find() — eliminates up to 120 SELECTs/page.
I-2: aggregateLastSyncedAt() now uses sortBy(timestamp) instead of
Collection::min() on Carbon objects (string-comparison was unreliable).
M-2: add explanatory comment on intval+array_filter silent-drop behaviour
in the ?ids batch-fetch path.
M-3: new test — ?ids batch silently excludes foreign-tenant project IDs.
M-4: new test — show returns 200 for archived project (read preserved).
PHPStan baseline updated: 2 new test functions raise actingAs() count 7→9.
Tests: 9/9 passed (33 assertions). Larastan: 0 errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>