Add per-store managers for Woo Business accounts.
Deploy Ladill Woo Manager / deploy (push) Successful in 39s

Agencies can invite store-scoped managers via Identity, with access limited to one WooCommerce store while owners retain full multi-store control.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-08 07:51:08 +00:00
co-authored by Cursor
parent 1b0831b176
commit 09359ca86a
26 changed files with 921 additions and 28 deletions
@@ -0,0 +1,69 @@
<?php
namespace App\Services\Woo;
use App\Models\User;
use App\Models\WooStoreMember;
use Illuminate\Support\Collection;
class WooStoreMemberResolver
{
public function isAccountOwner(User $actor, string $ownerRef): bool
{
return $actor->public_id === $ownerRef;
}
public function memberFor(User $actor, string $ownerRef): ?WooStoreMember
{
if ($this->isAccountOwner($actor, $ownerRef)) {
return null;
}
return WooStoreMember::query()
->where('owner_ref', $ownerRef)
->where('user_ref', $actor->public_id)
->first();
}
/** @return list<int> */
public function accessibleStoreIds(User $actor, string $ownerRef): ?array
{
if ($this->isAccountOwner($actor, $ownerRef)) {
return null;
}
$ids = WooStoreMember::query()
->where('owner_ref', $ownerRef)
->where('user_ref', $actor->public_id)
->pluck('woo_store_id')
->map(fn ($id) => (int) $id)
->unique()
->values()
->all();
abort_if($ids === [], 403, 'You do not have access to this Woo Manager account.');
return $ids;
}
public function canAccessStore(User $actor, string $ownerRef, int $storeId): bool
{
$scope = $this->accessibleStoreIds($actor, $ownerRef);
return $scope === null || in_array($storeId, $scope, true);
}
public function canManageStoreTeam(?WooStoreMember $member, string $ownerRef, User $actor): bool
{
return $this->isAccountOwner($actor, $ownerRef);
}
/** @return Collection<int, WooStoreMember> */
public function membershipsFor(User $actor): Collection
{
return WooStoreMember::query()
->where('user_ref', $actor->public_id)
->with('store')
->get();
}
}