Sync launcher (Merchant/Mini/Give/One) and DemoWorld Care specialty RBAC staff.
Deploy Ladill Meet / deploy (push) Successful in 1m20s

This commit is contained in:
isaacclad
2026-07-21 14:24:34 +00:00
parent f5fed2b055
commit 982537bb13
2 changed files with 139 additions and 32 deletions
+135 -32
View File
@@ -187,33 +187,52 @@ final class DemoWorld
* }>> * }>>
*/ */
/** /**
* Care specialty module doctors (Pro / Enterprise). Emails: demo-{tier}-{key}@ladill.com * Care specialty module clinicians (Pro / Enterprise).
* Emails: demo-{tier}-{key}@ladill.com
* Roles follow the Care RBAC matrix when a dedicated slug exists;
* remaining modules stay on legacy `doctor` + desk specialty keywords.
* *
* @var array<string, string> module key => display name * @var array<string, array{name: string, role: string}>
*/ */
public const SPECIALTY_DOCTORS = [ public const SPECIALTY_DOCTORS = [
'emergency' => 'Dr. Kojo Emergency', 'emergency' => ['name' => 'Dr. Kojo Emergency', 'role' => 'emergency_physician'],
'blood_bank' => 'Dr. Ama Blood Bank', 'blood_bank' => ['name' => 'Ama Blood Bank Officer', 'role' => 'blood_bank_officer'],
'dentistry' => 'Dr. Ama Dental', 'dentistry' => ['name' => 'Dr. Ama Dental', 'role' => 'dentist'],
'ophthalmology' => 'Dr. Kofi Eye', 'ophthalmology' => ['name' => 'Dr. Kofi Eye', 'role' => 'doctor'],
'physiotherapy' => 'Dr. Efua Physio', 'physiotherapy' => ['name' => 'Dr. Efua Physio', 'role' => 'physiotherapist'],
'maternity' => 'Dr. Abena Maternity', 'maternity' => ['name' => 'Abena Midwife', 'role' => 'midwife'],
'radiology' => 'Dr. Yaw Radiology', 'radiology' => ['name' => 'Dr. Yaw Radiology', 'role' => 'radiologist'],
'cardiology' => 'Dr. Kwesi Cardiology', 'cardiology' => ['name' => 'Dr. Kwesi Cardiology', 'role' => 'doctor'],
'psychiatry' => 'Dr. Adwoa Psychiatry', 'psychiatry' => ['name' => 'Dr. Adwoa Psychiatry', 'role' => 'psychiatrist'],
'pediatrics' => 'Dr. Fiifi Pediatrics', 'pediatrics' => ['name' => 'Dr. Fiifi Pediatrics', 'role' => 'pediatrician'],
'orthopedics' => 'Dr. Kojo Orthopedics', 'orthopedics' => ['name' => 'Dr. Kojo Orthopedics', 'role' => 'doctor'],
'ent' => 'Dr. Esi ENT', 'ent' => ['name' => 'Dr. Esi ENT', 'role' => 'doctor'],
'oncology' => 'Dr. Mansa Oncology', 'oncology' => ['name' => 'Dr. Mansa Oncology', 'role' => 'oncologist'],
'renal' => 'Dr. Nana Renal', 'renal' => ['name' => 'Dr. Nana Renal', 'role' => 'doctor'],
'surgery' => 'Dr. Kwadwo Surgery', 'surgery' => ['name' => 'Dr. Kwadwo Surgery', 'role' => 'surgeon'],
'vaccination' => 'Dr. Afia Vaccination', 'vaccination' => ['name' => 'Dr. Afia Vaccination', 'role' => 'doctor'],
'pathology' => 'Dr. Yaw Pathology', 'pathology' => ['name' => 'Dr. Yaw Pathology', 'role' => 'pathologist'],
'infusion' => 'Dr. Akosua Infusion', 'infusion' => ['name' => 'Dr. Akosua Infusion', 'role' => 'doctor'],
'dermatology' => 'Dr. Ama Dermatology', 'dermatology' => ['name' => 'Dr. Ama Dermatology', 'role' => 'doctor'],
'podiatry' => 'Dr. Kofi Podiatry', 'podiatry' => ['name' => 'Dr. Kofi Podiatry', 'role' => 'doctor'],
'fertility' => 'Dr. Abena Fertility', 'fertility' => ['name' => 'Dr. Abena Fertility', 'role' => 'doctor'],
'child_welfare' => 'Dr. Efua Child Welfare', 'child_welfare' => ['name' => 'Dr. Efua Child Welfare', 'role' => 'doctor'],
'ambulance' => ['name' => 'Kojo Ambulance', 'role' => 'ambulance_staff'],
];
/**
* Extra Care matrix roles (not covered by SPECIALTY_DOCTORS keys).
*
* @var list<array{key: string, name: string, role: string}>
*/
public const CARE_MATRIX_STAFF = [
['key' => 'ed-nurse', 'name' => 'Ama ED Nurse', 'role' => 'ed_nurse'],
['key' => 'theatre-nurse', 'name' => 'Efua Theatre Nurse', 'role' => 'theatre_nurse'],
['key' => 'radiographer', 'name' => 'Kofi Radiographer', 'role' => 'radiographer'],
['key' => 'dialysis-nurse', 'name' => 'Abena Dialysis Nurse', 'role' => 'dialysis_nurse'],
['key' => 'billing-officer', 'name' => 'Yaw Billing Officer', 'role' => 'billing_officer'],
['key' => 'department-manager', 'name' => 'Adwoa Department Manager', 'role' => 'department_manager'],
['key' => 'hospital-admin', 'name' => 'Kojo Hospital Admin', 'role' => 'hospital_admin'],
]; ];
public const STAFF = [ public const STAFF = [
@@ -242,7 +261,14 @@ final class DemoWorld
'email' => 'demo-pro-doctor@ladill.com', 'email' => 'demo-pro-doctor@ladill.com',
'name' => 'Dr. Kwame Mensah (Pro)', 'name' => 'Dr. Kwame Mensah (Pro)',
'apps' => ['care'], 'apps' => ['care'],
'roles' => ['care' => 'doctor'], 'roles' => ['care' => 'general_physician'],
],
[
'key' => 'general-physician',
'email' => 'demo-pro-general-physician@ladill.com',
'name' => 'Dr. Ama General Physician (Pro)',
'apps' => ['care'],
'roles' => ['care' => 'general_physician'],
], ],
[ [
'key' => 'nurse', 'key' => 'nurse',
@@ -282,13 +308,36 @@ final class DemoWorld
'apps' => ['care'], 'apps' => ['care'],
'roles' => ['care' => 'lab_technician'], 'roles' => ['care' => 'lab_technician'],
], ],
[
'key' => 'lab_manager',
'email' => 'demo-pro-lab-manager@ladill.com',
'name' => 'Ama Lab Manager (Pro)',
'apps' => ['care'],
'roles' => ['care' => 'lab_manager'],
],
[
'key' => 'blood_bank_manager',
'email' => 'demo-pro-blood-bank-manager@ladill.com',
'name' => 'Kofi Blood Bank Manager (Pro)',
'apps' => ['care'],
'roles' => ['care' => 'blood_bank_manager'],
],
[ [
'key' => 'cashier', 'key' => 'cashier',
'email' => 'demo-pro-cashier@ladill.com', 'email' => 'demo-pro-cashier@ladill.com',
'name' => 'Kojo Cashier (Pro)', 'name' => 'Kojo Cashier (Pro)',
'apps' => ['care', 'pos'], // Care cashiers collect via Billing — not Ladill POS.
'apps' => ['care'],
'roles' => [ 'roles' => [
'care' => 'cashier', 'care' => 'cashier',
],
],
[
'key' => 'pos_cashier',
'email' => 'demo-pro-pos-cashier@ladill.com',
'name' => 'Kofi POS Cashier (Pro)',
'apps' => ['pos'],
'roles' => [
'pos' => 'cashier', 'pos' => 'cashier',
], ],
], ],
@@ -321,7 +370,14 @@ final class DemoWorld
'email' => 'demo-enterprise-doctor@ladill.com', 'email' => 'demo-enterprise-doctor@ladill.com',
'name' => 'Dr. Kwame Mensah', 'name' => 'Dr. Kwame Mensah',
'apps' => ['care'], 'apps' => ['care'],
'roles' => ['care' => 'doctor'], 'roles' => ['care' => 'general_physician'],
],
[
'key' => 'general-physician',
'email' => 'demo-enterprise-general-physician@ladill.com',
'name' => 'Dr. Ama General Physician',
'apps' => ['care'],
'roles' => ['care' => 'general_physician'],
], ],
[ [
'key' => 'nurse', 'key' => 'nurse',
@@ -361,13 +417,36 @@ final class DemoWorld
'apps' => ['care'], 'apps' => ['care'],
'roles' => ['care' => 'lab_technician'], 'roles' => ['care' => 'lab_technician'],
], ],
[
'key' => 'lab_manager',
'email' => 'demo-enterprise-lab-manager@ladill.com',
'name' => 'Ama Lab Manager',
'apps' => ['care'],
'roles' => ['care' => 'lab_manager'],
],
[
'key' => 'blood_bank_manager',
'email' => 'demo-enterprise-blood-bank-manager@ladill.com',
'name' => 'Kofi Blood Bank Manager',
'apps' => ['care'],
'roles' => ['care' => 'blood_bank_manager'],
],
[ [
'key' => 'cashier', 'key' => 'cashier',
'email' => 'demo-enterprise-cashier@ladill.com', 'email' => 'demo-enterprise-cashier@ladill.com',
'name' => 'Kojo Cashier', 'name' => 'Kojo Cashier',
'apps' => ['care', 'pos'], // Care cashiers collect via Billing — not Ladill POS.
'apps' => ['care'],
'roles' => [ 'roles' => [
'care' => 'cashier', 'care' => 'cashier',
],
],
[
'key' => 'pos_cashier',
'email' => 'demo-enterprise-pos-cashier@ladill.com',
'name' => 'Kofi POS Cashier',
'apps' => ['pos'],
'roles' => [
'pos' => 'cashier', 'pos' => 'cashier',
], ],
], ],
@@ -525,7 +604,7 @@ final class DemoWorld
return $roster; return $roster;
} }
foreach (self::SPECIALTY_DOCTORS as $key => $name) { foreach (self::SPECIALTY_DOCTORS as $key => $meta) {
$email = sprintf('demo-%s-%s@ladill.com', $tier, $key); $email = sprintf('demo-%s-%s@ladill.com', $tier, $key);
$already = false; $already = false;
foreach ($roster as $row) { foreach ($roster as $row) {
@@ -537,13 +616,37 @@ final class DemoWorld
if ($already) { if ($already) {
continue; continue;
} }
$name = is_array($meta) ? (string) ($meta['name'] ?? $key) : (string) $meta;
$role = is_array($meta) ? (string) ($meta['role'] ?? 'doctor') : 'doctor';
$suffix = $tier === 'pro' ? ' (Pro)' : '';
$roster[] = [
'key' => $key,
'email' => $email,
'name' => $name.$suffix,
'apps' => ['care'],
'roles' => ['care' => $role],
];
}
foreach (self::CARE_MATRIX_STAFF as $extra) {
$email = sprintf('demo-%s-%s@ladill.com', $tier, $extra['key']);
$already = false;
foreach ($roster as $row) {
if (strtolower((string) ($row['email'] ?? '')) === $email) {
$already = true;
break;
}
}
if ($already) {
continue;
}
$suffix = $tier === 'pro' ? ' (Pro)' : ''; $suffix = $tier === 'pro' ? ' (Pro)' : '';
$roster[] = [ $roster[] = [
'key' => $key, 'key' => $extra['key'],
'email' => $email, 'email' => $email,
'name' => $name.$suffix, 'name' => $extra['name'].$suffix,
'apps' => ['care'], 'apps' => ['care'],
'roles' => ['care' => 'doctor'], 'roles' => ['care' => $extra['role']],
]; ];
} }
+4
View File
@@ -18,7 +18,10 @@ $root = config('app.platform_domain', 'ladill.com');
return [ return [
'apps' => [ 'apps' => [
['name' => 'Merchant', 'url' => 'https://merchant.'.$root.'/sso/connect?redirect='.urlencode('https://merchant.'.$root.'/dashboard'), 'icon' => 'merchant.svg'],
['name' => 'POS', 'url' => 'https://pos.'.$root.'/sso/connect?redirect='.urlencode('https://pos.'.$root.'/dashboard'), 'icon' => 'pos.svg'], ['name' => 'POS', 'url' => 'https://pos.'.$root.'/sso/connect?redirect='.urlencode('https://pos.'.$root.'/dashboard'), 'icon' => 'pos.svg'],
['name' => 'Mini', 'url' => 'https://mini.'.$root.'/sso/connect?redirect='.urlencode('https://mini.'.$root.'/dashboard'), 'icon' => 'mini.svg'],
['name' => 'Give', 'url' => 'https://give.'.$root.'/sso/connect?redirect='.urlencode('https://give.'.$root.'/dashboard'), 'icon' => 'give.svg'],
['name' => 'Woo Manager', 'url' => 'https://woo.'.$root.'/sso/connect?redirect='.urlencode('https://woo.'.$root.'/dashboard'), 'icon' => 'woomanager.svg'], ['name' => 'Woo Manager', 'url' => 'https://woo.'.$root.'/sso/connect?redirect='.urlencode('https://woo.'.$root.'/dashboard'), 'icon' => 'woomanager.svg'],
['name' => 'Transfer', 'url' => 'https://transfer.'.$root.'/sso/connect?redirect='.urlencode('https://transfer.'.$root.'/dashboard'), 'icon' => 'transfer.svg'], ['name' => 'Transfer', 'url' => 'https://transfer.'.$root.'/sso/connect?redirect='.urlencode('https://transfer.'.$root.'/dashboard'), 'icon' => 'transfer.svg'],
['name' => 'Accounting', 'url' => 'https://accounting.'.$root.'/sso/connect?redirect='.urlencode('https://accounting.'.$root.'/dashboard'), 'icon' => 'accounting.svg'], ['name' => 'Accounting', 'url' => 'https://accounting.'.$root.'/sso/connect?redirect='.urlencode('https://accounting.'.$root.'/dashboard'), 'icon' => 'accounting.svg'],
@@ -29,6 +32,7 @@ return [
['name' => 'Link', 'url' => 'https://link.'.$root.'/sso/connect?redirect='.urlencode('https://link.'.$root.'/dashboard'), 'icon' => 'link.svg'], ['name' => 'Link', 'url' => 'https://link.'.$root.'/sso/connect?redirect='.urlencode('https://link.'.$root.'/dashboard'), 'icon' => 'link.svg'],
['name' => 'Frontdesk', 'url' => 'https://frontdesk.'.$root.'/sso/connect?redirect='.urlencode('https://frontdesk.'.$root.'/dashboard'), 'icon' => 'frontdesk.svg'], ['name' => 'Frontdesk', 'url' => 'https://frontdesk.'.$root.'/sso/connect?redirect='.urlencode('https://frontdesk.'.$root.'/dashboard'), 'icon' => 'frontdesk.svg'],
['name' => 'Care', 'url' => 'https://care.'.$root.'/sso/connect?redirect='.urlencode('https://care.'.$root.'/dashboard'), 'icon' => 'care.svg'], ['name' => 'Care', 'url' => 'https://care.'.$root.'/sso/connect?redirect='.urlencode('https://care.'.$root.'/dashboard'), 'icon' => 'care.svg'],
['name' => 'One', 'url' => 'https://one.'.$root.'/sso/connect?redirect='.urlencode('https://one.'.$root.'/dashboard'), 'icon' => 'one.svg'],
['name' => 'Queue', 'url' => 'https://queue.'.$root.'/sso/connect?redirect='.urlencode('https://queue.'.$root.'/dashboard'), 'icon' => 'queue.svg'], ['name' => 'Queue', 'url' => 'https://queue.'.$root.'/sso/connect?redirect='.urlencode('https://queue.'.$root.'/dashboard'), 'icon' => 'queue.svg'],
['name' => 'SMS', 'url' => 'https://sms.'.$root, 'icon' => 'sms.svg'], ['name' => 'SMS', 'url' => 'https://sms.'.$root, 'icon' => 'sms.svg'],
['name' => 'Bird', 'url' => 'https://bird.'.$root, 'icon' => 'bird.svg'], ['name' => 'Bird', 'url' => 'https://bird.'.$root, 'icon' => 'bird.svg'],