Finish FindAsync tenant sweep: CompanySettings, dashboards, lookups

Completes the multi-tenant defense-in-depth FindAsync/Count/Any pass.

- CompanySettings (~21): in-use Count checks, dup-code Any checks, and the
  Quote-status "single approved/converted" Any checks now filter by
  CompanyId. (Were scoped for normal users via the global filter; this
  hardens them against raw platform-admin sessions.)
- ReportsController.Analytics: powder-usage transactions scoped.
- Dashboard pill counts (Invoices, Jobs) + onboarding status-history check.
- JobsPriority / Jobs ShopDisplay+ShopMobile: today's priorities,
  maintenance, and status-lookup queries scoped.
- OvenScheduler: scheduled-coat set and CompanyOperatingCosts lookup
  (c => true) scoped — the latter could return another tenant's defaults
  under a raw platform-admin session.

Confirmed safe / left as-is: parent-FK child queries, by-PK fetches,
platform tables (PowderCatalog, SubscriptionPlanConfig), SuperAdmin-only
controllers (AuditLog/UserActivity/StripeEvents/SubscriptionManagement),
already-filtered IQueryables, and intentional IgnoreQueryFilters number
generators. Build clean; 293 unit tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 17:30:21 -04:00
parent c0d3a30176
commit f804906481
7 changed files with 53 additions and 42 deletions
@@ -590,7 +590,8 @@ public class ReportsController : Controller
// === POWDER USAGE ANALYTICS ===
var powderTransactions = (await _unitOfWork.InventoryTransactions
.FindAsync(t => t.TransactionType == InventoryTransactionType.JobUsage
.FindAsync(t => t.CompanyId == companyId
&& t.TransactionType == InventoryTransactionType.JobUsage
&& t.TransactionDate >= startDate,
false,
t => t.InventoryItem))