Add consultation-nested assessment create and show routes.
Deploy Ladill Care / deploy (push) Successful in 32s
Deploy Ladill Care / deploy (push) Successful in 32s
Index alone still left /consultations/{uuid}/assessments/create and
/consultations/{uuid}/assessments/{uuid} unmatched (404). Wire those
paths, redirect store into the nested show, and cover the doctor form
open flow with feature tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -75,6 +75,42 @@ class AssessmentController extends Controller
|
|||||||
return $this->index($request, $consultation->patient);
|
return $this->index($request, $consultation->patient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start-form picker under a consultation (parity with prescriptions create).
|
||||||
|
* GET /consultations/{uuid}/assessments/create
|
||||||
|
*/
|
||||||
|
public function createForConsultation(Request $request, Consultation $consultation): View
|
||||||
|
{
|
||||||
|
$this->authorizeConsultation($request, $consultation);
|
||||||
|
$consultation->loadMissing(['patient', 'visit']);
|
||||||
|
|
||||||
|
$return = app(ConsultationReturnContext::class);
|
||||||
|
$return->remember($consultation);
|
||||||
|
$request->query->set('consultation_uuid', $consultation->uuid);
|
||||||
|
if ($consultation->visit?->uuid) {
|
||||||
|
$request->query->set('visit_uuid', $consultation->visit->uuid);
|
||||||
|
}
|
||||||
|
$request->query->set(ConsultationReturnContext::QUERY_KEY, $consultation->uuid);
|
||||||
|
|
||||||
|
return $this->create($request, $consultation->patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open an assessment while staying on the consultation URL tree.
|
||||||
|
* GET /consultations/{uuid}/assessments/{assessment}
|
||||||
|
*/
|
||||||
|
public function showForConsultation(Request $request, Consultation $consultation, Assessment $assessment): View
|
||||||
|
{
|
||||||
|
$this->authorizeConsultation($request, $consultation);
|
||||||
|
abort_unless((int) $assessment->patient_id === (int) $consultation->patient_id, 404);
|
||||||
|
|
||||||
|
$return = app(ConsultationReturnContext::class);
|
||||||
|
$return->remember($consultation);
|
||||||
|
$request->query->set(ConsultationReturnContext::QUERY_KEY, $consultation->uuid);
|
||||||
|
|
||||||
|
return $this->show($request, $assessment);
|
||||||
|
}
|
||||||
|
|
||||||
public function create(Request $request, Patient $patient): View
|
public function create(Request $request, Patient $patient): View
|
||||||
{
|
{
|
||||||
$this->assertEngineEnabled($request);
|
$this->assertEngineEnabled($request);
|
||||||
@@ -99,15 +135,19 @@ class AssessmentController extends Controller
|
|||||||
}
|
}
|
||||||
})->values();
|
})->values();
|
||||||
|
|
||||||
|
$returnConsultation = app(ConsultationReturnContext::class)
|
||||||
|
->resolve($request, (int) $patient->id);
|
||||||
|
$returnConsultation?->loadMissing('visit');
|
||||||
|
|
||||||
return view('care.assessments.create', [
|
return view('care.assessments.create', [
|
||||||
'patient' => $patient,
|
'patient' => $patient,
|
||||||
'templates' => $capturable,
|
'templates' => $capturable,
|
||||||
'categories' => config('care.assessment_template_categories'),
|
'categories' => config('care.assessment_template_categories'),
|
||||||
'consultationUuid' => $request->query('consultation_uuid'),
|
'consultationUuid' => $request->query('consultation_uuid') ?? $returnConsultation?->uuid,
|
||||||
'visitUuid' => $request->query('visit_uuid'),
|
'visitUuid' => $request->query('visit_uuid') ?? $returnConsultation?->visit?->uuid,
|
||||||
|
'returnConsultation' => $returnConsultation,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(Request $request, Patient $patient): RedirectResponse
|
public function store(Request $request, Patient $patient): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->assertEngineEnabled($request);
|
$this->assertEngineEnabled($request);
|
||||||
@@ -130,6 +170,16 @@ class AssessmentController extends Controller
|
|||||||
);
|
);
|
||||||
|
|
||||||
$return = app(ConsultationReturnContext::class);
|
$return = app(ConsultationReturnContext::class);
|
||||||
|
if (! empty($context['consultation'])) {
|
||||||
|
$return->remember($context['consultation']);
|
||||||
|
|
||||||
|
return redirect()
|
||||||
|
->route('care.consultations.assessments.show', [
|
||||||
|
'consultation' => $context['consultation'],
|
||||||
|
'assessment' => $assessment,
|
||||||
|
])
|
||||||
|
->with('success', 'Assessment started.');
|
||||||
|
}
|
||||||
|
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('care.assessments.show', array_filter([
|
->route('care.assessments.show', array_filter([
|
||||||
@@ -168,10 +218,10 @@ class AssessmentController extends Controller
|
|||||||
$return->remember($consultation);
|
$return->remember($consultation);
|
||||||
|
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('care.assessments.show', array_filter([
|
->route('care.consultations.assessments.show', [
|
||||||
|
'consultation' => $consultation,
|
||||||
'assessment' => $assessment,
|
'assessment' => $assessment,
|
||||||
...$return->query($consultation),
|
])
|
||||||
]))
|
|
||||||
->with('success', 'Assessment started.');
|
->with('success', 'Assessment started.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,11 +290,7 @@ class AssessmentController extends Controller
|
|||||||
|
|
||||||
$return = app(ConsultationReturnContext::class);
|
$return = app(ConsultationReturnContext::class);
|
||||||
|
|
||||||
return redirect()
|
return $this->redirectToAssessmentShow($request, $assessment, $return)
|
||||||
->route('care.assessments.show', array_filter([
|
|
||||||
'assessment' => $assessment,
|
|
||||||
...$return->routeQuery($request),
|
|
||||||
]))
|
|
||||||
->with('success', 'Assessment saved.');
|
->with('success', 'Assessment saved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,11 +326,7 @@ class AssessmentController extends Controller
|
|||||||
|
|
||||||
$return = app(ConsultationReturnContext::class);
|
$return = app(ConsultationReturnContext::class);
|
||||||
|
|
||||||
return redirect()
|
return $this->redirectToAssessmentShow($request, $assessment, $return)
|
||||||
->route('care.assessments.show', array_filter([
|
|
||||||
'assessment' => $assessment,
|
|
||||||
...$return->routeQuery($request),
|
|
||||||
]))
|
|
||||||
->with('success', 'Assessment completed.');
|
->with('success', 'Assessment completed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,11 +343,41 @@ class AssessmentController extends Controller
|
|||||||
$this->ownerRef($request),
|
$this->ownerRef($request),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$return = app(ConsultationReturnContext::class);
|
||||||
|
$consultation = $return->resolve($request, (int) $assessment->patient_id);
|
||||||
|
|
||||||
|
if ($consultation) {
|
||||||
|
return redirect()
|
||||||
|
->route('care.consultations.assessments.index', $consultation)
|
||||||
|
->with('success', 'Assessment cancelled.');
|
||||||
|
}
|
||||||
|
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('care.assessments.index', $assessment->patient)
|
->route('care.assessments.index', $assessment->patient)
|
||||||
->with('success', 'Assessment cancelled.');
|
->with('success', 'Assessment cancelled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefer consultation-nested show when the doctor is mid-consult.
|
||||||
|
*/
|
||||||
|
protected function redirectToAssessmentShow(
|
||||||
|
Request $request,
|
||||||
|
Assessment $assessment,
|
||||||
|
ConsultationReturnContext $return,
|
||||||
|
): RedirectResponse {
|
||||||
|
$consultation = $return->resolve($request, (int) $assessment->patient_id)
|
||||||
|
?? $return->resolveLinked($request, $assessment->consultation);
|
||||||
|
|
||||||
|
if ($consultation) {
|
||||||
|
return redirect()->route('care.consultations.assessments.show', [
|
||||||
|
'consultation' => $consultation,
|
||||||
|
'assessment' => $assessment,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->route('care.assessments.show', $assessment);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FHIR R4 Bundle (Questionnaire + QuestionnaireResponse) download.
|
* FHIR R4 Bundle (Questionnaire + QuestionnaireResponse) download.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<x-app-layout :title="'Start assessment · '.$patient->fullName()">
|
<x-app-layout :title="'Start assessment · '.$patient->fullName()">
|
||||||
|
<x-care.consultation-return :consultation="$returnConsultation ?? null" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-medium uppercase tracking-wide text-slate-500">Start assessment</p>
|
<p class="text-xs font-medium uppercase tracking-wide text-slate-500">Start assessment</p>
|
||||||
<h1 class="text-2xl font-semibold text-slate-900">{{ $patient->fullName() }}</h1>
|
<h1 class="text-2xl font-semibold text-slate-900">{{ $patient->fullName() }}</h1>
|
||||||
@@ -11,7 +13,9 @@
|
|||||||
@if ($templates->isEmpty())
|
@if ($templates->isEmpty())
|
||||||
<p class="text-sm text-slate-500">No forms are available for your role right now. Ask an administrator to confirm clinical forms are enabled in Settings.</p>
|
<p class="text-sm text-slate-500">No forms are available for your role right now. Ask an administrator to confirm clinical forms are enabled in Settings.</p>
|
||||||
@else
|
@else
|
||||||
<form method="POST" action="{{ route('care.assessments.store', $patient) }}" class="space-y-4">
|
<form method="POST" action="{{ ($returnConsultation ?? null)
|
||||||
|
? route('care.consultations.assessments.store', $returnConsultation)
|
||||||
|
: route('care.assessments.store', $patient) }}" class="space-y-4">
|
||||||
@csrf
|
@csrf
|
||||||
@if ($consultationUuid)
|
@if ($consultationUuid)
|
||||||
<input type="hidden" name="consultation_uuid" value="{{ $consultationUuid }}">
|
<input type="hidden" name="consultation_uuid" value="{{ $consultationUuid }}">
|
||||||
@@ -19,6 +23,9 @@
|
|||||||
@if ($visitUuid)
|
@if ($visitUuid)
|
||||||
<input type="hidden" name="visit_uuid" value="{{ $visitUuid }}">
|
<input type="hidden" name="visit_uuid" value="{{ $visitUuid }}">
|
||||||
@endif
|
@endif
|
||||||
|
@if (($returnConsultation ?? null)?->uuid)
|
||||||
|
<input type="hidden" name="from_consultation" value="{{ $returnConsultation->uuid }}">
|
||||||
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium text-slate-700">Template</label>
|
<label class="block text-sm font-medium text-slate-700">Template</label>
|
||||||
@@ -38,7 +45,9 @@
|
|||||||
|
|
||||||
<div class="flex gap-3">
|
<div class="flex gap-3">
|
||||||
<button type="submit" class="btn-primary">Start</button>
|
<button type="submit" class="btn-primary">Start</button>
|
||||||
<a href="{{ route('care.assessments.index', $patient) }}" class="rounded-lg border border-slate-200 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">Cancel</a>
|
<a href="{{ ($returnConsultation ?? null)
|
||||||
|
? route('care.consultations.assessments.index', $returnConsultation)
|
||||||
|
: route('care.assessments.index', $patient) }}" class="rounded-lg border border-slate-200 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -10,7 +10,11 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@if ($canCapture)
|
@if ($canCapture)
|
||||||
<a href="{{ route('care.assessments.create', $patient) }}" class="btn-primary">Start assessment</a>
|
@if ($returnConsultation ?? null)
|
||||||
|
<a href="{{ route('care.consultations.assessments.create', $returnConsultation) }}" class="btn-primary">Start assessment</a>
|
||||||
|
@else
|
||||||
|
<a href="{{ route('care.assessments.create', $patient) }}" class="btn-primary">Start assessment</a>
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -53,7 +57,11 @@
|
|||||||
{{ $assessment->assessed_at?->format('d M Y H:i') ?? $assessment->created_at?->format('d M Y H:i') ?? '—' }}
|
{{ $assessment->assessed_at?->format('d M Y H:i') ?? $assessment->created_at?->format('d M Y H:i') ?? '—' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
<a href="{{ route('care.assessments.show', $assessment) }}" class="text-sky-600 hover:text-sky-700">Open</a>
|
@if ($returnConsultation ?? null)
|
||||||
|
<a href="{{ route('care.consultations.assessments.show', [$returnConsultation, $assessment]) }}" class="text-sky-600 hover:text-sky-700">Open</a>
|
||||||
|
@else
|
||||||
|
<a href="{{ route('care.assessments.show', $assessment) }}" class="text-sky-600 hover:text-sky-700">Open</a>
|
||||||
|
@endif
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
<a href="{{ route('care.assessments.fhir', $assessment) }}?download=1" class="rounded-lg border border-slate-200 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Export FHIR</a>
|
<a href="{{ route('care.assessments.fhir', $assessment) }}?download=1" class="rounded-lg border border-slate-200 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Export FHIR</a>
|
||||||
<a href="{{ route('care.assessments.index', $assessment->patient) }}" class="rounded-lg border border-slate-200 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">All assessments</a>
|
<a href="{{ ($returnConsultation ?? null)
|
||||||
|
? route('care.consultations.assessments.index', $returnConsultation)
|
||||||
|
: route('care.assessments.index', $assessment->patient) }}" class="rounded-lg border border-slate-200 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">All assessments</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@if ($universalAssessment)
|
@if ($universalAssessment)
|
||||||
<a href="{{ route('care.assessments.show', [$universalAssessment, 'from_consultation' => $consultation->uuid]) }}" class="rounded-lg bg-sky-600 px-3 py-2 text-sm font-medium text-white hover:bg-sky-700">
|
<a href="{{ route('care.consultations.assessments.show', [$consultation, $universalAssessment]) }}" class="rounded-lg bg-sky-600 px-3 py-2 text-sm font-medium text-white hover:bg-sky-700">
|
||||||
{{ $universalAssessment->isDraft() ? 'Continue form' : 'View form' }}
|
{{ $universalAssessment->isDraft() ? 'Continue form' : 'View form' }}
|
||||||
</a>
|
</a>
|
||||||
@elseif (($canCaptureUniversal ?? false) && ! $isCompleted)
|
@elseif (($canCaptureUniversal ?? false) && ! $isCompleted)
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
<span class="text-xs text-amber-600">Form not available yet</span>
|
<span class="text-xs text-amber-600">Form not available yet</span>
|
||||||
@elseif ($instrument['assessment'])
|
@elseif ($instrument['assessment'])
|
||||||
<span class="text-xs text-slate-500">{{ $assessmentStatuses[$instrument['assessment']->status] ?? $instrument['assessment']->status }}</span>
|
<span class="text-xs text-slate-500">{{ $assessmentStatuses[$instrument['assessment']->status] ?? $instrument['assessment']->status }}</span>
|
||||||
<a href="{{ route('care.assessments.show', [$instrument['assessment'], 'from_consultation' => $consultation->uuid]) }}" class="text-sky-600 hover:text-sky-700">
|
<a href="{{ route('care.consultations.assessments.show', [$consultation, $instrument['assessment']]) }}" class="text-sky-600 hover:text-sky-700">
|
||||||
{{ $instrument['assessment']->isDraft() ? 'Continue' : 'View' }}
|
{{ $instrument['assessment']->isDraft() ? 'Continue' : 'View' }}
|
||||||
</a>
|
</a>
|
||||||
@elseif (($canCaptureAssessment ?? false) && ! $isCompleted)
|
@elseif (($canCaptureAssessment ?? false) && ! $isCompleted)
|
||||||
@@ -209,7 +209,7 @@
|
|||||||
<ul class="mt-4 space-y-2 text-sm">
|
<ul class="mt-4 space-y-2 text-sm">
|
||||||
@foreach ($consultationAssessments as $item)
|
@foreach ($consultationAssessments as $item)
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ route('care.assessments.show', [$item, 'from_consultation' => $consultation->uuid]) }}" class="text-sky-600 hover:text-sky-700">
|
<a href="{{ route('care.consultations.assessments.show', [$consultation, $item]) }}" class="text-sky-600 hover:text-sky-700">
|
||||||
{{ $item->template->name }}
|
{{ $item->template->name }}
|
||||||
</a>
|
</a>
|
||||||
· {{ ($assessmentStatuses[$item->status] ?? $item->status) }}
|
· {{ ($assessmentStatuses[$item->status] ?? $item->status) }}
|
||||||
@@ -390,7 +390,7 @@
|
|||||||
<section class="rounded-2xl border border-sky-100 bg-white p-6">
|
<section class="rounded-2xl border border-sky-100 bg-white p-6">
|
||||||
<div class="flex items-center justify-between gap-2">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500">Patient history form</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500">Patient history form</h2>
|
||||||
<a href="{{ route('care.assessments.show', [$universalAssessment, 'from_consultation' => $consultation->uuid]) }}" class="text-sm text-sky-600 hover:text-sky-700">Open</a>
|
<a href="{{ route('care.consultations.assessments.show', [$consultation, $universalAssessment]) }}" class="text-sm text-sky-600 hover:text-sky-700">Open</a>
|
||||||
</div>
|
</div>
|
||||||
<dl class="mt-4 space-y-2 text-sm">
|
<dl class="mt-4 space-y-2 text-sm">
|
||||||
@foreach ($universalAssessment->answers->sortBy(fn ($a) => $a->question?->sort_order ?? 0) as $answer)
|
@foreach ($universalAssessment->answers->sortBy(fn ($a) => $a->question?->sort_order ?? 0) as $answer)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
'name' => 'Clinical forms',
|
'name' => 'Clinical forms',
|
||||||
'route' => route('care.patients.index', ['focus' => 'assessments']),
|
'route' => route('care.patients.index', ['focus' => 'assessments']),
|
||||||
'active' => request()->routeIs('care.assessments.*')
|
'active' => request()->routeIs('care.assessments.*')
|
||||||
|
|| request()->routeIs('care.consultations.assessments.*')
|
||||||
|| request()->routeIs('care.pathways.*')
|
|| request()->routeIs('care.pathways.*')
|
||||||
|| request()->routeIs('care.outcomes.*'),
|
|| request()->routeIs('care.outcomes.*'),
|
||||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z" />',
|
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z" />',
|
||||||
|
|||||||
@@ -219,8 +219,11 @@ Route::middleware(['auth', 'platform.session'])->group(function () {
|
|||||||
Route::get('/patients/{patient}/assessments', [AssessmentController::class, 'index'])->name('care.assessments.index');
|
Route::get('/patients/{patient}/assessments', [AssessmentController::class, 'index'])->name('care.assessments.index');
|
||||||
Route::get('/patients/{patient}/assessments/create', [AssessmentController::class, 'create'])->name('care.assessments.create');
|
Route::get('/patients/{patient}/assessments/create', [AssessmentController::class, 'create'])->name('care.assessments.create');
|
||||||
Route::post('/patients/{patient}/assessments', [AssessmentController::class, 'store'])->name('care.assessments.store');
|
Route::post('/patients/{patient}/assessments', [AssessmentController::class, 'store'])->name('care.assessments.store');
|
||||||
|
// Consultation-scoped: index / create / show (create before {assessment} so "create" is not bound as uuid)
|
||||||
Route::get('/consultations/{consultation}/assessments', [AssessmentController::class, 'indexForConsultation'])->name('care.consultations.assessments.index');
|
Route::get('/consultations/{consultation}/assessments', [AssessmentController::class, 'indexForConsultation'])->name('care.consultations.assessments.index');
|
||||||
|
Route::get('/consultations/{consultation}/assessments/create', [AssessmentController::class, 'createForConsultation'])->name('care.consultations.assessments.create');
|
||||||
Route::post('/consultations/{consultation}/assessments', [AssessmentController::class, 'storeForConsultation'])->name('care.consultations.assessments.store');
|
Route::post('/consultations/{consultation}/assessments', [AssessmentController::class, 'storeForConsultation'])->name('care.consultations.assessments.store');
|
||||||
|
Route::get('/consultations/{consultation}/assessments/{assessment}', [AssessmentController::class, 'showForConsultation'])->name('care.consultations.assessments.show');
|
||||||
Route::get('/assessments/{assessment}', [AssessmentController::class, 'show'])->name('care.assessments.show');
|
Route::get('/assessments/{assessment}', [AssessmentController::class, 'show'])->name('care.assessments.show');
|
||||||
Route::put('/assessments/{assessment}', [AssessmentController::class, 'update'])->name('care.assessments.update');
|
Route::put('/assessments/{assessment}', [AssessmentController::class, 'update'])->name('care.assessments.update');
|
||||||
Route::post('/assessments/{assessment}/complete', [AssessmentController::class, 'complete'])->name('care.assessments.complete');
|
Route::post('/assessments/{assessment}/complete', [AssessmentController::class, 'complete'])->name('care.assessments.complete');
|
||||||
|
|||||||
@@ -400,6 +400,76 @@ class CareAssessmentCaptureTest extends TestCase
|
|||||||
$this->assertSame($this->branch->id, $assessment->branch_id);
|
$this->assertSame($this->branch->id, $assessment->branch_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_consultation_create_show_and_store_open_forms_for_doctor(): void
|
||||||
|
{
|
||||||
|
$this->setMemberRole('doctor');
|
||||||
|
|
||||||
|
$visit = Visit::create([
|
||||||
|
'owner_ref' => $this->user->public_id,
|
||||||
|
'organization_id' => $this->organization->id,
|
||||||
|
'branch_id' => $this->branch->id,
|
||||||
|
'patient_id' => $this->patient->id,
|
||||||
|
'status' => Visit::STATUS_OPEN,
|
||||||
|
'checked_in_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$consultation = Consultation::create([
|
||||||
|
'owner_ref' => $this->user->public_id,
|
||||||
|
'visit_id' => $visit->id,
|
||||||
|
'patient_id' => $this->patient->id,
|
||||||
|
'status' => Consultation::STATUS_DRAFT,
|
||||||
|
'started_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Nested create (was unmatched → Laravel 404 before this fix)
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('care.consultations.assessments.create', $consultation))
|
||||||
|
->assertOk()
|
||||||
|
->assertSee('Start assessment')
|
||||||
|
->assertSee('Universal Intake');
|
||||||
|
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get('/consultations/'.$consultation->uuid.'/assessments/create')
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
$response = $this->actingAs($this->user)
|
||||||
|
->post(route('care.consultations.assessments.store', $consultation), [
|
||||||
|
'template_code' => 'universal_intake',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$assessment = Assessment::first();
|
||||||
|
$this->assertNotNull($assessment);
|
||||||
|
|
||||||
|
$response->assertRedirect(route('care.consultations.assessments.show', [
|
||||||
|
'consultation' => $consultation,
|
||||||
|
'assessment' => $assessment,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Nested show (was unmatched → Laravel 404)
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('care.consultations.assessments.show', [$consultation, $assessment]))
|
||||||
|
->assertOk()
|
||||||
|
->assertSee('Universal Intake')
|
||||||
|
->assertSee('Back to consultation');
|
||||||
|
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get('/consultations/'.$consultation->uuid.'/assessments/'.$assessment->uuid)
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
// Flat show still works for patient-chart / bookmarks
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('care.assessments.show', $assessment))
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
// Patient create + store with consultation_uuid also lands on nested show
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('care.assessments.create', [
|
||||||
|
'patient' => $this->patient,
|
||||||
|
'consultation_uuid' => $consultation->uuid,
|
||||||
|
]))
|
||||||
|
->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
public function test_public_bodies_use_consultation_uuid(): void
|
public function test_public_bodies_use_consultation_uuid(): void
|
||||||
{
|
{
|
||||||
$this->setMemberRole('doctor');
|
$this->setMemberRole('doctor');
|
||||||
@@ -430,6 +500,10 @@ class CareAssessmentCaptureTest extends TestCase
|
|||||||
|
|
||||||
$assessment = Assessment::first();
|
$assessment = Assessment::first();
|
||||||
$this->assertSame($consultation->id, $assessment->consultation_id);
|
$this->assertSame($consultation->id, $assessment->consultation_id);
|
||||||
|
|
||||||
|
$this->actingAs($this->user)
|
||||||
|
->get(route('care.consultations.assessments.show', [$consultation, $assessment]))
|
||||||
|
->assertOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_tenant_isolation_returns_404(): void
|
public function test_tenant_isolation_returns_404(): void
|
||||||
|
|||||||
Reference in New Issue
Block a user