Deploy Ladill Care / deploy (push) Successful in 1m26s
Add a template-driven assessment system with universal intake, clinical pathways, disease instruments (stroke MVP + extended, diabetes, and ten specialty packs), scoring, patient outcome trends, REST/API + FHIR export, and Enterprise org-level assessment analytics. Seed packs and design/licensing docs ship for deploy and pre-GA review.
132 lines
4.7 KiB
PHP
132 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Models\AssessmentQuestion;
|
|
use App\Models\AssessmentTemplate;
|
|
use Illuminate\Database\Seeder;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\File;
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* Loads platform assessment content packs from database/data/assessments/*.json.
|
|
* Upserts by (code, version); replaces questions for that template version.
|
|
*/
|
|
class AssessmentTemplateSeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
$dir = database_path('data/assessments');
|
|
if (! is_dir($dir)) {
|
|
$this->command?->warn("No assessment packs directory at {$dir}");
|
|
|
|
return;
|
|
}
|
|
|
|
$files = collect(File::files($dir))
|
|
->filter(fn ($file) => str_ends_with(strtolower($file->getFilename()), '.json'))
|
|
->sortBy(fn ($file) => $file->getFilename())
|
|
->values();
|
|
|
|
if ($files->isEmpty()) {
|
|
$this->command?->warn('No assessment JSON packs found.');
|
|
|
|
return;
|
|
}
|
|
|
|
foreach ($files as $file) {
|
|
$this->seedPack($file->getPathname());
|
|
}
|
|
}
|
|
|
|
public function seedPack(string $path): AssessmentTemplate
|
|
{
|
|
$raw = File::get($path);
|
|
$data = json_decode($raw, true);
|
|
if (! is_array($data) || ! isset($data['template'], $data['questions'])) {
|
|
throw new RuntimeException("Invalid assessment pack: {$path}");
|
|
}
|
|
|
|
$t = $data['template'];
|
|
foreach (['code', 'name', 'category', 'version'] as $required) {
|
|
if (! array_key_exists($required, $t)) {
|
|
throw new RuntimeException("Assessment pack missing template.{$required}: {$path}");
|
|
}
|
|
}
|
|
|
|
return DB::transaction(function () use ($t, $data, $path) {
|
|
$template = AssessmentTemplate::withTrashed()
|
|
->whereNull('organization_id')
|
|
->where('code', $t['code'])
|
|
->where('version', (int) $t['version'])
|
|
->first();
|
|
|
|
$attributes = [
|
|
'organization_id' => null,
|
|
'code' => $t['code'],
|
|
'name' => $t['name'],
|
|
'category' => $t['category'],
|
|
'description' => $t['description'] ?? null,
|
|
'version' => (int) $t['version'],
|
|
'is_current' => (bool) ($t['is_current'] ?? true),
|
|
'is_active' => (bool) ($t['is_active'] ?? true),
|
|
'scoring_strategy' => $t['scoring_strategy'] ?? null,
|
|
'meta' => $t['meta'] ?? null,
|
|
'deleted_at' => null,
|
|
];
|
|
|
|
if ($template) {
|
|
if ($template->trashed()) {
|
|
$template->restore();
|
|
}
|
|
$template->fill(collect($attributes)->except('deleted_at')->all())->save();
|
|
} else {
|
|
$template = AssessmentTemplate::create(collect($attributes)->except('deleted_at')->all());
|
|
}
|
|
|
|
if ($template->is_current) {
|
|
AssessmentTemplate::query()
|
|
->whereNull('organization_id')
|
|
->where('code', $template->code)
|
|
->where('id', '!=', $template->id)
|
|
->where('is_current', true)
|
|
->update(['is_current' => false]);
|
|
}
|
|
|
|
// Replace questions for this template version (stable codes within version).
|
|
AssessmentQuestion::query()->where('template_id', $template->id)->delete();
|
|
|
|
$sort = 0;
|
|
foreach ($data['questions'] as $q) {
|
|
if (empty($q['code']) || empty($q['label']) || empty($q['answer_type'])) {
|
|
throw new RuntimeException("Invalid question in pack {$path}");
|
|
}
|
|
$sort++;
|
|
AssessmentQuestion::create([
|
|
'template_id' => $template->id,
|
|
'code' => $q['code'],
|
|
'section' => $q['section'] ?? null,
|
|
'label' => $q['label'],
|
|
'help_text' => $q['help_text'] ?? null,
|
|
'answer_type' => $q['answer_type'],
|
|
'options' => $q['options'] ?? null,
|
|
'is_required' => (bool) ($q['is_required'] ?? false),
|
|
'sort_order' => (int) ($q['sort_order'] ?? $sort),
|
|
'score_key' => $q['score_key'] ?? null,
|
|
'validation' => $q['validation'] ?? null,
|
|
]);
|
|
}
|
|
|
|
$this->command?->info(sprintf(
|
|
'Seeded assessment pack %s v%d (%d questions)',
|
|
$template->code,
|
|
$template->version,
|
|
count($data['questions']),
|
|
));
|
|
|
|
return $template->fresh('questions');
|
|
});
|
|
}
|
|
}
|