assertPathwaysEnabled($request); $this->authorizeAbility($request, 'assessments.view'); $this->authorizePatient($request, $patient); $active = $this->pathways->activeFor($patient); $history = PatientPathway::query() ->owned($this->ownerRef($request)) ->where('patient_id', $patient->id) ->with('pathway') ->orderByDesc('activated_at') ->paginate(20); $catalog = ClinicalPathway::query()->active()->orderBy('sort_order')->get(); $canManage = $this->permissions->can($this->member($request), 'pathways.manage'); return view('care.pathways.index', [ 'patient' => $patient, 'active' => $active, 'history' => $history, 'catalog' => $catalog, 'canManage' => $canManage, 'statuses' => config('care.patient_pathway_statuses'), ]); } public function store(Request $request, Patient $patient): RedirectResponse { $this->assertPathwaysEnabled($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 redirect() ->route('care.pathways.index', $patient) ->with('success', "Pathway “{$pathway->name}” activated."); } public function deactivate(Request $request, Patient $patient, PatientPathway $patientPathway): RedirectResponse { $this->assertPathwaysEnabled($request); $this->authorizeAbility($request, 'pathways.manage'); $this->authorizePatient($request, $patient); abort_unless($patientPathway->patient_id === $patient->id, 404); $this->authorizeOwner($request, $patientPathway); $this->pathways->deactivate( $patientPathway, $this->ownerRef($request), $this->member($request), $this->ownerRef($request), ); return back()->with('success', 'Pathway deactivated.'); } public function suggestions(Request $request, Consultation $consultation): JsonResponse|RedirectResponse { $this->assertPathwaysEnabled($request); $this->authorizeAbility($request, 'consultations.view'); $this->authorizeConsultation($request, $consultation); $consultation->loadMissing(['diagnoses', 'patient']); $suggestions = $this->pathways->suggest($consultation->patient, $consultation->diagnoses); $payload = [ '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(), ]; if ($request->wantsJson() || $request->ajax()) { return response()->json($payload); } // HTML fallthrough not used — consultation show embeds suggestions server-side. return back()->with('pathway_suggestions', $payload['data']); } protected function assertPathwaysEnabled(Request $request): void { $org = $this->organization($request); // Pathways require assessments engine; suggestions flag is optional UX. abort_unless( $this->features->enabled($org, 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); } } }