withoutMiddleware(EnsurePlatformSession::class); $this->owner = User::create([ 'public_id' => 'clinical-owner', 'name' => 'Owner', 'email' => 'clinical@example.com', ]); $this->organization = Organization::create([ 'owner_ref' => $this->owner->public_id, 'name' => 'Clinical Clinic', 'slug' => 'clinical-clinic', 'settings' => [ 'onboarded' => true, 'facility_type' => 'clinic', 'plan' => 'pro', 'plan_expires_at' => now()->addMonth()->toIso8601String(), 'queue_integration_enabled' => true, ], ]); Member::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'user_ref' => $this->owner->public_id, 'role' => 'hospital_admin', ]); $this->branch = Branch::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'name' => 'Main', 'is_active' => true, ]); } /** * @return array{0: Visit, 1: Department} */ protected function activateWithVisit(string $module, string $departmentType): array { app(SpecialtyModuleService::class)->activate( $this->organization, $this->owner->public_id, $module, ); $department = Department::query() ->where('branch_id', $this->branch->id) ->where('type', $departmentType) ->firstOrFail(); $patient = Patient::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_number' => 'P-CL-1', 'first_name' => 'Kofi', 'last_name' => 'Asante', 'gender' => 'male', 'date_of_birth' => '1985-03-01', ]); $visit = Visit::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $patient->id, 'status' => Visit::STATUS_OPEN, 'checked_in_at' => now(), ]); Appointment::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $patient->id, 'department_id' => $department->id, 'visit_id' => $visit->id, 'type' => Appointment::TYPE_WALK_IN, 'status' => Appointment::STATUS_WAITING, 'scheduled_at' => now(), 'waiting_at' => now(), ]); return [$visit, $department]; } public function test_emergency_triage_form_saves_structured_record_and_alerts(): void { [$visit] = $this->activateWithVisit('emergency', 'emergency'); $this->actingAs($this->owner) ->get(route('care.specialty.workspace', ['module' => 'emergency', 'visit' => $visit, 'tab' => 'triage'])) ->assertOk() ->assertSee('Triage acuity') ->assertSee('Chief complaint'); $this->actingAs($this->owner) ->post(route('care.specialty.clinical.save', ['module' => 'emergency', 'visit' => $visit]), [ 'tab' => 'triage', 'stage_code' => 'arrival', 'status' => 'active', 'payload' => [ 'acuity' => '1 - Resuscitation', 'chief_complaint' => 'Chest pain', 'airway_ok' => '0', 'breathing_ok' => '1', 'circulation_ok' => '1', 'pain_score' => '9', 'mode_of_arrival' => 'Ambulance', 'disposition_intent' => 'Resus', 'notes' => 'Immediate attention', ], ]) ->assertRedirect(); $record = SpecialtyClinicalRecord::query() ->where('visit_id', $visit->id) ->where('record_type', 'triage') ->first(); $this->assertNotNull($record); $this->assertSame('Chest pain', $record->payload['chief_complaint'] ?? null); $this->assertFalse((bool) ($record->payload['airway_ok'] ?? true)); $this->assertNotEmpty($record->alerts); $this->assertTrue(collect($record->alerts)->contains(fn ($a) => ($a['code'] ?? '') === 'er.high_acuity')); $this->assertTrue(collect($record->alerts)->contains(fn ($a) => ($a['code'] ?? '') === 'er.abc_compromise')); $this->actingAs($this->owner) ->get(route('care.specialty.workspace', ['module' => 'emergency', 'visit' => $visit, 'tab' => 'triage'])) ->assertOk() ->assertSee('High-acuity triage') ->assertSee('ABC compromise'); } public function test_blood_bank_request_and_dentistry_odontogram_save(): void { [$bbVisit] = $this->activateWithVisit('blood_bank', 'blood_bank'); $this->actingAs($this->owner) ->post(route('care.specialty.clinical.save', ['module' => 'blood_bank', 'visit' => $bbVisit]), [ 'tab' => 'requests', 'payload' => [ 'product' => 'Packed RBC', 'units' => '2', 'urgency' => 'Emergency / massive', 'patient_blood_group' => 'O+', 'indication' => 'Trauma bleed', 'crossmatch_status' => 'Not started', ], ]) ->assertRedirect(); $this->assertDatabaseHas('care_specialty_clinical_records', [ 'visit_id' => $bbVisit->id, 'module_key' => 'blood_bank', 'record_type' => 'blood_request', ]); app(SpecialtyModuleService::class)->activate( $this->organization->fresh(), $this->owner->public_id, 'dentistry', ); $dentalDept = Department::query() ->where('branch_id', $this->branch->id) ->where('type', 'dental') ->firstOrFail(); $patient = Patient::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_number' => 'P-CL-2', 'first_name' => 'Ama', 'last_name' => 'Boateng', 'gender' => 'female', 'date_of_birth' => '1990-01-01', ]); $denVisit = Visit::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $patient->id, 'status' => Visit::STATUS_OPEN, 'checked_in_at' => now(), ]); Appointment::create([ 'owner_ref' => $this->owner->public_id, 'organization_id' => $this->organization->id, 'branch_id' => $this->branch->id, 'patient_id' => $patient->id, 'department_id' => $dentalDept->id, 'visit_id' => $denVisit->id, 'type' => Appointment::TYPE_WALK_IN, 'status' => Appointment::STATUS_WAITING, 'scheduled_at' => now(), 'waiting_at' => now(), ]); $this->actingAs($this->owner) ->post(route('care.specialty.clinical.save', ['module' => 'dentistry', 'visit' => $denVisit]), [ 'tab' => 'odontogram', 'payload' => [ 'teeth_affected' => '16, 26', 'findings' => 'Caries on occlusal surfaces', 'planned_procedures' => 'Fillings', 'anesthesia' => 'Local', ], ]) ->assertRedirect(); $this->assertDatabaseHas('care_specialty_clinical_records', [ 'visit_id' => $denVisit->id, 'module_key' => 'dentistry', 'record_type' => 'odontogram', ]); } }