assertEngineEnabled($request); $this->authorizeAbility($request, 'assessments.view'); $pathways = ClinicalPathway::query() ->active() ->with('templates') ->orderBy('sort_order') ->get(); return response()->json(['data' => $pathways]); } public function index(Request $request, Patient $patient): JsonResponse { $this->assertEngineEnabled($request); $this->authorizeAbility($request, 'assessments.view'); $this->authorizePatient($request, $patient); $active = $this->pathways->activeFor($patient)->load('pathway.templates'); $history = PatientPathway::query() ->owned($this->ownerRef($request)) ->where('patient_id', $patient->id) ->with('pathway') ->orderByDesc('activated_at') ->limit(50) ->get(); return response()->json([ 'active' => $active->map(fn (PatientPathway $pp) => $this->serializePatientPathway($pp)), 'history' => $history->map(fn (PatientPathway $pp) => $this->serializePatientPathway($pp)), ]); } public function store(Request $request, Patient $patient): JsonResponse { $this->assertEngineEnabled($request); $this->authorizeAbility($request, 'pathways.manage'); $this->authorizePatient($request, $patient); $validated = $request->validate([ 'pathway_code' => ['required', 'string', 'max:100'], 'consultation_uuid' => ['nullable', 'uuid'], 'activation_diagnosis_text' => ['nullable', 'string', 'max:500'], ]); $pathway = ClinicalPathway::findByCode($validated['pathway_code']); abort_unless($pathway, 422, 'Unknown or inactive pathway.'); $consultation = null; if (! empty($validated['consultation_uuid'])) { $consultation = Consultation::query() ->where('uuid', $validated['consultation_uuid']) ->where('patient_id', $patient->id) ->firstOrFail(); $this->authorizeConsultation($request, $consultation); $consultation->loadMissing(['visit', 'diagnoses']); } $patientPathway = $this->pathways->activate( $patient, $pathway, $this->ownerRef($request), $this->member($request), [ 'consultation' => $consultation, 'activation_diagnosis_text' => $validated['activation_diagnosis_text'] ?? null, 'actor' => $this->ownerRef($request), ], ); return response()->json($this->serializePatientPathway($patientPathway->load(['pathway.templates', 'assessments.template'])), 201); } public function deactivate(Request $request, Patient $patient, PatientPathway $patientPathway): JsonResponse { $this->assertEngineEnabled($request); $this->authorizeAbility($request, 'pathways.manage'); $this->authorizePatient($request, $patient); abort_unless($patientPathway->patient_id === $patient->id, 404); $this->authorizeOwner($request, $patientPathway); $updated = $this->pathways->deactivate( $patientPathway, $this->ownerRef($request), $this->member($request), $this->ownerRef($request), ); return response()->json($this->serializePatientPathway($updated->load('pathway'))); } public function suggestions(Request $request, Consultation $consultation): JsonResponse { $this->assertEngineEnabled($request); $this->authorizeAbility($request, 'consultations.view'); $this->authorizeConsultation($request, $consultation); $consultation->loadMissing(['diagnoses', 'patient']); $suggestions = $this->pathways->suggest($consultation->patient, $consultation->diagnoses); return response()->json([ 'data' => $suggestions->map(fn (array $row) => [ 'pathway_code' => $row['pathway_code'], 'pathway_name' => $row['pathway_name'], 'rank' => $row['rank'], 'match_reason' => $row['match_reason'], 'already_active' => $row['already_active'], ])->values()->all(), ]); } protected function serializePatientPathway(PatientPathway $pp): array { return [ 'uuid' => $pp->uuid, 'status' => $pp->status, 'pathway_code' => $pp->pathway?->code, 'pathway_name' => $pp->pathway?->name, 'activated_at' => $pp->activated_at?->toIso8601String(), 'activation_diagnosis_text' => $pp->activation_diagnosis_text, 'resolved_at' => $pp->resolved_at?->toIso8601String(), 'assessments' => $pp->relationLoaded('assessments') ? $pp->assessments->map(fn ($a) => [ 'uuid' => $a->uuid, 'status' => $a->status, 'template_code' => $a->template?->code, ])->values()->all() : null, ]; } protected function assertEngineEnabled(Request $request): void { abort_unless( $this->features->enabled($this->organization($request), CareFeatures::ASSESSMENTS_ENGINE), 404, ); } protected function authorizePatient(Request $request, Patient $patient): void { $this->authorizeOwner($request, $patient); abort_unless($patient->organization_id === $this->organization($request)->id, 404); $branchId = app(OrganizationResolver::class)->branchScope($this->member($request)); if ($branchId !== null && $patient->branch_id !== $branchId) { abort(404); } } protected function authorizeConsultation(Request $request, Consultation $consultation): void { $this->authorizeOwner($request, $consultation); $consultation->loadMissing('visit'); abort_unless($consultation->visit->organization_id === $this->organization($request)->id, 404); $branchId = app(OrganizationResolver::class)->branchScope($this->member($request)); if ($branchId !== null && $consultation->visit->branch_id !== $branchId) { abort(404); } } }