Files
ladill-care/app/Services/Care/Workflow/WorkflowTemplateRegistry.php
T
isaaccladandCursor 86bfce1e17
Deploy Ladill Care / deploy (push) Failing after 45s
Add workflow-centric patient journey with financial gates.
Introduces a facility workflow engine as Care's primary configuration
object: onboarding now leads with a facility category (which modules to
enable) and a workflow template (how patients move + where money is
collected), including standard herbal hospital/clinic templates.

Templates materialize into care_facility_workflows/care_workflow_stages.
The engine tracks a visit's position via care_visit_stage_advances and,
with FinancialGateService, gates a stage's queue behind a cleared
FinancialObligation (paid/authorized/waived/deferred) for "before"
payment timing while leaving "after" (pay-at-exit) flows unblocked.
Gated behavior is opt-in behind the workflow_engine/financial_gates
rollout flags; legacy orgs keep current behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 20:47:33 +00:00

97 lines
2.6 KiB
PHP

<?php
namespace App\Services\Care\Workflow;
/**
* Read-only access to config/care_workflows.php — facility categories and
* workflow templates. Templates are materialized into care_facility_workflows
* by WorkflowTemplateInstaller.
*/
class WorkflowTemplateRegistry
{
/** @return array<string, mixed> */
public function categories(): array
{
return (array) config('care_workflows.categories', []);
}
/** @return array<string, mixed> */
public function category(?string $key): ?array
{
if ($key === null || $key === '') {
return null;
}
$category = config("care_workflows.categories.{$key}");
return is_array($category) ? $category : null;
}
/** @return array<string, string> key => label */
public function categoryOptions(): array
{
return array_map(
fn (array $category) => (string) ($category['label'] ?? ''),
$this->categories(),
);
}
/** @return array<string, mixed> */
public function templates(): array
{
return (array) config('care_workflows.templates', []);
}
/** @return array<string, mixed>|null */
public function template(?string $key): ?array
{
if ($key === null || $key === '') {
return null;
}
$template = config("care_workflows.templates.{$key}");
return is_array($template) ? $template : null;
}
public function hasTemplate(?string $key): bool
{
return $this->template($key) !== null;
}
/** @return array<string, string> key => label */
public function templateOptions(): array
{
return array_map(
fn (array $template) => (string) ($template['label'] ?? ''),
$this->templates(),
);
}
public function defaultTemplateKey(): string
{
return (string) config('care_workflows.default_template', 'legacy_clinic');
}
/** Preferred template for a facility category, falling back to the global default. */
public function defaultTemplateForCategory(?string $categoryKey): string
{
$category = $this->category($categoryKey);
$preferred = $category['default_template'] ?? null;
if (is_string($preferred) && $this->hasTemplate($preferred)) {
return $preferred;
}
return $this->defaultTemplateKey();
}
/** @return list<string> */
public function modulesForCategory(?string $categoryKey): array
{
$category = $this->category($categoryKey);
return array_values((array) ($category['modules'] ?? []));
}
}