-
Mahmoud Aglan authored
The two existing suites cannot catch a leaking dashboard. BranchIsolationTest proves the scope narrows a model; BranchScopedScreensTest looks for another branch's records in the rendered HTML. But a dashboard renders totals, not records — a revenue widget quietly summing every branch shows a number that is simply wrong, with no uuid anywhere to give it away, and both suites pass. Dashboards are also where the raw query builder lives, because that is what aggregates are written in, and a raw DB::table() goes straight past every global scope. So this asserts at the only layer that sees both: the wire. Two checks: - Every SQL statement each of sixteen dashboards runs is captured with DB::listen, and any query reading a branch-owned table without mentioning `branch_id` anywhere — its own WHERE, a join, a subquery the scope added — is a failure. Deliberately crude, because a strict SQL parse would be worse than useless here: a query that never says the word never asked. - The per-branch figures for participants, enrolments, invoices, payment totals, attendance and groups must add up to the academy-wide figure. A widget ignoring the branch returns the whole academy for every branch, so the sum comes out a multiple of the truth. Current state: all sixteen render, 1,354 queries captured, 902 of them touching branch-owned tables, and every one names a branch. Co-Authored-By:Claude Opus 5 (1M context) <noreply@anthropic.com>
73a61a77