Implements the complete ShiftAssignment lifecycle: - ShiftAssignmentStatus enum with allowed transitions - ShiftAssignmentService with claim/assign/approve/reject/cancel/bulkApprove - ShiftAssignmentController with event-scoped endpoints - ShiftAssignmentPolicy (organizer + volunteer self-cancel) - VolunteerAvailability model, controller, and sync endpoint - Refactored ShiftController to delegate to service layer - 31 workflow tests covering all paths and multi-tenancy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67 lines
1.7 KiB
PHP
67 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Policies;
|
|
|
|
use App\Models\Event;
|
|
use App\Models\ShiftAssignment;
|
|
use App\Models\User;
|
|
|
|
final class ShiftAssignmentPolicy
|
|
{
|
|
public function viewAny(User $user, Event $event): bool
|
|
{
|
|
return $user->hasRole('super_admin')
|
|
|| $event->organisation->users()->where('user_id', $user->id)->exists();
|
|
}
|
|
|
|
public function approve(User $user, ShiftAssignment $assignment, Event $event): bool
|
|
{
|
|
return $this->canManageEvent($user, $event);
|
|
}
|
|
|
|
public function reject(User $user, ShiftAssignment $assignment, Event $event): bool
|
|
{
|
|
return $this->canManageEvent($user, $event);
|
|
}
|
|
|
|
public function cancel(User $user, ShiftAssignment $assignment, Event $event): bool
|
|
{
|
|
if ($this->canManageEvent($user, $event)) {
|
|
return true;
|
|
}
|
|
|
|
// Volunteers can cancel their own assignments
|
|
$person = $assignment->person;
|
|
|
|
return $person->user_id !== null && $person->user_id === $user->id;
|
|
}
|
|
|
|
public function bulkApprove(User $user, Event $event): bool
|
|
{
|
|
return $this->canManageEvent($user, $event);
|
|
}
|
|
|
|
private function canManageEvent(User $user, Event $event): bool
|
|
{
|
|
if ($user->hasRole('super_admin')) {
|
|
return true;
|
|
}
|
|
|
|
$isOrgAdmin = $event->organisation->users()
|
|
->where('user_id', $user->id)
|
|
->wherePivot('role', 'org_admin')
|
|
->exists();
|
|
|
|
if ($isOrgAdmin) {
|
|
return true;
|
|
}
|
|
|
|
return $event->users()
|
|
->where('user_id', $user->id)
|
|
->wherePivot('role', 'event_manager')
|
|
->exists();
|
|
}
|
|
}
|