Limit specialty module visibility to matching desk specialists.
Deploy Ladill Care / deploy (push) Successful in 35s

GPs keep broad general/limited manage and restricted view/refer; dentists and other desk specialists only see modules that match their specialty.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-18 22:09:15 +00:00
co-authored by Cursor
parent 9ecc3ad7f0
commit d02760c527
4 changed files with 119 additions and 16 deletions
+50
View File
@@ -120,6 +120,7 @@ class CareSpecialtyAccessTest extends TestCase
'is_active' => true,
]);
$this->assertFalse($this->modules->isDeskSpecialist($this->organization, $member));
$this->assertTrue($this->modules->memberCanManage($this->organization, $member, 'emergency'));
$this->assertTrue($this->modules->memberCanManage($this->organization, $member, 'dentistry'));
$this->assertFalse($this->modules->memberCanManage($this->organization, $member, 'cardiology'));
@@ -146,6 +147,55 @@ class CareSpecialtyAccessTest extends TestCase
$this->assertTrue($this->modules->memberCanManage($this->organization, $member, 'cardiology'));
$this->assertSame('manage', $this->modules->memberAccessLevel($this->organization, $member, 'cardiology'));
// Desk specialists do not keep GP-wide general/limited manage.
$this->assertSame('none', $this->modules->memberAccessLevel($this->organization, $member, 'emergency'));
$this->assertSame('none', $this->modules->memberAccessLevel($this->organization, $member, 'dentistry'));
}
public function test_dentistry_specialist_only_sees_matching_modules(): void
{
[$doctor, $member] = $this->makeStaff('doctor', 'dentist1');
Practitioner::create([
'owner_ref' => $this->owner->public_id,
'organization_id' => $this->organization->id,
'branch_id' => $this->branch->id,
'member_id' => $member->id,
'user_ref' => $doctor->public_id,
'name' => 'Dr Dentist',
'specialty' => 'Dentistry',
'is_active' => true,
]);
$this->assertTrue($this->modules->isDeskSpecialist($this->organization, $member));
$this->assertTrue($this->modules->memberCanManage($this->organization, $member, 'dentistry'));
$this->assertSame('manage', $this->modules->memberAccessLevel($this->organization, $member, 'dentistry'));
foreach (['emergency', 'blood_bank', 'cardiology', 'infusion', 'pathology'] as $key) {
$this->assertSame(
'none',
$this->modules->memberAccessLevel($this->organization, $member, $key),
"Dentistry specialist should not see [{$key}]",
);
$this->assertFalse($this->modules->memberCanManage($this->organization, $member, $key));
$this->assertFalse($this->modules->memberCanView($this->organization, $member, $key));
$this->assertFalse($this->modules->memberCanRefer($this->organization, $member, $key));
}
$enabledKeys = collect($this->modules->enabledModulesForMember($this->organization, $member))
->pluck('key')
->all();
$this->assertContains('dentistry', $enabledKeys);
$this->assertNotContains('emergency', $enabledKeys);
$this->assertNotContains('blood_bank', $enabledKeys);
$this->assertNotContains('cardiology', $enabledKeys);
$this->actingAs($doctor)
->get(route('care.dashboard'))
->assertOk()
->assertSee('Dentistry')
->assertDontSee('Emergency')
->assertDontSee('Cardiology')
->assertDontSee('Blood Bank');
}
public function test_gp_can_refer_into_restricted_specialty_queue(): void
+10 -2
View File
@@ -302,7 +302,7 @@ class CareSpecialtyModulesTest extends TestCase
'dentistry',
),
);
// Restricted modules stay off for GPs without specialty assignment.
// Desk specialists only see matching modules — no cross-specialty refer.
$this->assertFalse(
app(SpecialtyModuleService::class)->memberCanManage(
$this->organization->fresh(),
@@ -311,13 +311,21 @@ class CareSpecialtyModulesTest extends TestCase
),
);
app(SpecialtyModuleService::class)->activate($this->organization->fresh(), $this->owner->public_id, 'cardiology');
$this->assertTrue(
$this->assertFalse(
app(SpecialtyModuleService::class)->memberCanRefer(
$this->organization->fresh(),
$member,
'cardiology',
),
);
$this->assertSame(
'none',
app(SpecialtyModuleService::class)->memberAccessLevel(
$this->organization->fresh(),
$member,
'emergency',
),
);
}
public function test_emergency_and_blood_bank_are_default_on_pro(): void