# Location-based access control — apply

    cp -R location-scope/app/*       ./app/
    cp -R location-scope/database/*  ./database/
    cp -R location-scope/resources/* ./resources/
    cp -R location-scope/tests/*     ./tests/

## 1. User model — add the relationship

    public function locations(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
    {
        return $this->belongsToMany(\App\Locations\Models\Location::class, 'location_user')->withTimestamps();
    }

## 2. Permission — add to PermissionRegistry permissions():
    ['key' => 'locations.view_all', 'label' => 'View all locations', 'domain' => 'general'],
and grant it in roleGrants() to 'owner' and 'admin'.

## 3. Routes — merge routes/locations-web.php
## 4. Sidebar — add "Locations" to the Administration group -> /admin/locations
## 5. PortfolioService — apply docs/portfolio-patch.md (constructor + units() filter)

## 6. Migrate, seed permissions, sync locations, test
    php artisan migrate --force
    php artisan db:seed --class=Database\\Seeders\\PermissionSeeder --force
    php artisan test --filter=LocationScope
    node node_modules/vite/bin/vite.js build

Then populate locations from the Rentec data already in the warehouse:
    Admin → Locations → "Sync from Rentec"   (or POST /admin/locations/sync)

## The model
- Locations mirror Rentec parent properties (14 of them).
- Users are tagged to locations; admins/owners bypass via locations.view_all.
- PortfolioService filters units by the caller's locations, so EVERY report tab
  inherits the restriction automatically.
- FAILS CLOSED: an untagged non-admin sees nothing rather than everything.
