Skip to content
This repository was archived by the owner on Aug 23, 2026. It is now read-only.

refactor(quality): Rector wave 5 — model scopes public to protected (AID-540) - #192

Merged
abkrim merged 1 commit into
mainfrom
abdelkarim/aid-540-rector-scopes-protected
Jul 17, 2026
Merged

abkrim merged 1 commit into
mainfrom
abdelkarim/aid-540-rector-scopes-protected

Conversation

@abkrim

@abkrim abkrim commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Split from AID-531 as a public-surface change and reviewed as such — not trusted to a green suite.

27 scopes across 6 models flip public → protected (PatternDetection, UserHostingPermission, AbuseIncident, Account, BfmWhitelistEntry, Domain). The "Attributes" half of the rule found nothing; the diff is scopes only.

Why protected is safe here — three verified axes

  1. Zero direct calls. ->scopeX( / ::scopeX( grep across app/, tests/, routes/, config/, database/ (definitions excluded): 0 hits.
  2. Zero dynamic references. No 'scopeActive'-style strings anywhere.
  3. The Eloquent proxy is proven by vendor reading, not assumption. Model::callNamedScope() invokes $this->{'scope'.ucfirst($scope)}(...) from the base class of the hierarchy, so protected never blocks it. Filament consumes scopes through the builder proxy, which goes through this path. The suite (1442 tests, scopes exercised via proxy throughout) then confirmed it empirically.

This app is final, not a library — no external consumers can exist.

Shape-verified pure

54 changed lines = 27 × "-public function scope..." + 27 × "+protected function scope..."
others: 0

Gates

  • Violation probe: new model with a public scope → rc=2 naming app/ProbeScopeModel.php ✓
  • Idempotent (second pass byte-level no-op) ✓
  • composer check-full → exit 0, 1442 passed / 16 skipped, coverage 89.8% ✓

Note for future waves: the rule's FQCN is RectorLaravel\Rector\ClassMethod\... — the Class_ namespace guessed first does not exist and Rector fails with "Expected an existing class name".

…AID-540)

Enable MakeModelAttributesAndScopesProtectedRector and apply it with
cleared cache: 27 scopes across 6 models (PatternDetection,
UserHostingPermission, AbuseIncident, Account, BfmWhitelistEntry,
Domain) flip public->protected. The Attributes half of the rule found
nothing — the diff is scopes only.

This was split from AID-531 as a public-surface change and reviewed as
such rather than trusted to a green suite:
- zero direct ->scopeX()/::scopeX() calls repo-wide (app, tests, routes,
  config, database), definitions excluded
- zero dynamic string references to scope method names
- the Eloquent proxy is proven safe by vendor reading, not assumption:
  Model::callNamedScope() invokes $this->{'scope'.ucfirst($scope)}(...)
  from the base class of the hierarchy, so protected visibility never
  blocks it — Filament included, since it consumes scopes through the
  builder proxy. The suite then confirmed it empirically (scopes are
  exercised via proxy throughout).
- this app is final, not a library: no external consumers can exist

Wave checklist:
- resized with --clear-cache; correct FQCN is
  RectorLaravel\Rector\ClassMethod\... (Class_ does not exist and fails
  with "Expected an existing class name")
- diff shape-verified pure: 54 changed lines = 27 -public + 27
  +protected, zero others
- rule bites, attributably: a new model with a public scope -> exit 2
  naming app/ProbeScopeModel.php
- idempotence: second pass is a byte-level no-op
- gates: check-full green, 1442 passed / 16 skipped, coverage 89.8%,
  refactor:dry (cleared cache) exit 0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@abkrim
abkrim merged commit 5b64b9a into main Jul 17, 2026
2 checks passed
@abkrim
abkrim deleted the abdelkarim/aid-540-rector-scopes-protected branch July 17, 2026 18:48
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant