feat(treatment): select treatment behaviour by practice domain, not by if-branch
Everything that differs between specialties as data is already stored as data. What is left is behaviour — when a case opens, what happens once a session ends — so it becomes a TreatmentWorkflow resolved through a tagged-service registry. The booking path calls one collaborator and never names a specialty; adding dentistry is a new class, not an edit to confirmation. A clinic that has chosen no practice domain still gets working multi-session courses: DefaultTreatmentWorkflow answers for null and for any code without a dedicated implementation, keeping "unset means behave as today, not error". LaserTreatmentWorkflow is deliberately empty beyond claiming `beauty` — it is the seam where laser-specific behaviour will land without disturbing anyone else. Session due dates are anchored to the previous session's actual finish, so a patient who comes twenty days late shifts the rest of their course instead of getting the next session while it can still do nothing. Only the next session is recomputed; later ones keep their estimate because they are anchored to nothing yet. Attachment targets the first session without an appointment rather than the first open one: a patient booking again mid-course was otherwise matched to the session that already had a booking, and the second appointment went nowhere. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Treatment;
|
||||
|
||||
use App\PracticeDomain\Entity\PracticeDomain;
|
||||
use App\Tests\ApiTestCase;
|
||||
use App\Treatment\Workflow\DefaultTreatmentWorkflow;
|
||||
use App\Treatment\Workflow\LaserTreatmentWorkflow;
|
||||
use App\Treatment\Workflow\TreatmentWorkflowRegistry;
|
||||
|
||||
class TreatmentWorkflowTest extends ApiTestCase
|
||||
{
|
||||
private TreatmentWorkflowRegistry $registry;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->registry = static::getContainer()->get(TreatmentWorkflowRegistry::class);
|
||||
}
|
||||
|
||||
public function testBeautyResolvesToTheLaserWorkflow(): void
|
||||
{
|
||||
self::assertInstanceOf(LaserTreatmentWorkflow::class, $this->registry->for('beauty'));
|
||||
}
|
||||
|
||||
/** حوزهای که هنوز پیادهسازی ندارد باید رفتار پیشفرض بگیرد، نه خطا. */
|
||||
public function testUnknownDomainFallsBackToTheDefaultWorkflow(): void
|
||||
{
|
||||
self::assertSame(
|
||||
DefaultTreatmentWorkflow::class,
|
||||
$this->registry->for('physiotherapy')::class,
|
||||
);
|
||||
}
|
||||
|
||||
/** نال یعنی «حوزه تنظیم نشده» و همان رفتار امروز، نه خطا. */
|
||||
public function testNullDomainFallsBackToTheDefaultWorkflow(): void
|
||||
{
|
||||
self::assertSame(DefaultTreatmentWorkflow::class, $this->registry->for(null)::class);
|
||||
}
|
||||
|
||||
public function testHasDedicatedWorkflowDistinguishesTheTwo(): void
|
||||
{
|
||||
self::assertTrue($this->registry->hasDedicatedWorkflow('beauty'));
|
||||
self::assertFalse($this->registry->hasDedicatedWorkflow('physiotherapy'));
|
||||
self::assertFalse($this->registry->hasDedicatedWorkflow(null));
|
||||
}
|
||||
|
||||
/** پنل ادمین باید ببیند کدام حوزه هنوز workflow ندارد. */
|
||||
public function testListExposesHasWorkflow(): void
|
||||
{
|
||||
$suffix = bin2hex(random_bytes(4));
|
||||
|
||||
foreach ([['beauty_' . $suffix, false], ['beauty', true]] as [$code, $expected]) {
|
||||
if ($this->em->getRepository(PracticeDomain::class)->findOneBy(['code' => $code]) === null) {
|
||||
$this->em->persist(new PracticeDomain($code, 'حوزهٔ آزمون'));
|
||||
}
|
||||
}
|
||||
$this->em->flush();
|
||||
|
||||
$admin = $this->createUser(['ROLE_USER', 'ROLE_ADMIN']);
|
||||
$body = $this->authJson('GET', '/api/v1/practice-domains', $admin);
|
||||
|
||||
$byCode = array_column($body['data'], 'has_workflow', 'code');
|
||||
|
||||
self::assertTrue($byCode['beauty']);
|
||||
self::assertFalse($byCode['beauty_' . $suffix]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user