From 42994522eb21051b332250201e3584e104815e0d Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Wed, 6 May 2026 12:43:48 +0200 Subject: [PATCH] refactor: drop ActorType::VOLUNTEER pending volunteer role introduction VOLUNTEER was reserved-but-unused. Resolver mapped non-admin authenticated users to ORG_MEMBER because Crewli has no dedicated volunteer Spatie role; volunteer-ness is behaviour (shift assignments), not identity. Dead enum cases are YAGNI violations under zero-compromise: a future developer could use the case without realising no resolution path leads to it, producing a silent no-op. Re-introduce alongside a real volunteer role split when that lands (BACKLOG OBS-1). ActorType keeps ORGANIZER_ADMIN, SUPER_ADMIN, PORTAL_TOKEN, ORG_MEMBER, UNAUTHENTICATED. Tests at 1537, Larastan clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- api/app/Enums/Observability/ActorType.php | 11 +++++------ .../Feature/Observability/BindSentryContextTest.php | 5 ++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/api/app/Enums/Observability/ActorType.php b/api/app/Enums/Observability/ActorType.php index 1fd6c7ac..95804b05 100644 --- a/api/app/Enums/Observability/ActorType.php +++ b/api/app/Enums/Observability/ActorType.php @@ -15,20 +15,19 @@ use Illuminate\Http\Request; * 1. Portal-token request → PORTAL_TOKEN * 2. Authenticated super_admin → SUPER_ADMIN * 3. Authenticated org_admin → ORGANIZER_ADMIN - * 4. Other authenticated user → ORG_MEMBER (covers volunteers — Crewli has - * no `volunteer` Spatie role today; volunteers join an organisation as - * org_member with org-pivot semantics. Promote to a dedicated case once - * the role model differentiates them at the user level.) + * 4. Other authenticated user → ORG_MEMBER * 5. None of the above → UNAUTHENTICATED * - * The VOLUNTEER case is reserved for that future split. + * Crewli has no dedicated `volunteer` Spatie role today; volunteer-ness is + * behaviour (a user has shift assignments) rather than identity. A + * dedicated VOLUNTEER actor_type case will land alongside that role split + * if/when it is introduced (BACKLOG OBS-1). */ enum ActorType: string { case ORGANIZER_ADMIN = 'organizer_admin'; case SUPER_ADMIN = 'super_admin'; case PORTAL_TOKEN = 'portal_token'; - case VOLUNTEER = 'volunteer'; case ORG_MEMBER = 'org_member'; case UNAUTHENTICATED = 'unauthenticated'; diff --git a/api/tests/Feature/Observability/BindSentryContextTest.php b/api/tests/Feature/Observability/BindSentryContextTest.php index c9c201c2..ecda8981 100644 --- a/api/tests/Feature/Observability/BindSentryContextTest.php +++ b/api/tests/Feature/Observability/BindSentryContextTest.php @@ -140,9 +140,8 @@ final class BindSentryContextTest extends TestCase public function test_org_member_authenticated_user_tags_actor_type_org_member(): void { - // Crewli has no `volunteer` Spatie role today; volunteers fall into - // org_member. The VOLUNTEER ActorType case is reserved for a future - // split — see ActorType::resolve() docblock. + // Volunteer-ness is behaviour in Crewli (shift assignments), not + // identity — non-admin authenticated users resolve to ORG_MEMBER. $user = User::factory()->create(); $user->assignRole('org_member');