tenant_insurances, entity_insurance_pricing and tenant_service_coverages reference their owner through a polymorphic (entity_type, entity_id) pair, so no database FK can cascade their cleanup. Hard-deleting a doctor (DoctorController) or clinic (AdminApiController) left these rows orphaned. Add TenantInsuranceCleanupService::purgeForEntity() and call it from both delete paths — removes coverage (via owning tenant_insurance ids), then tenant insurances, then pricing. Residual (separate, lower-freq paths): deleting an insurance category or a service_item still orphans rows that reference them by id — tracked under the medium-tier soft-ref findings. Regression: tests/Insurance/TenantInsuranceCleanupTest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
1.8 KiB
PHP
52 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Insurance\Service;
|
|
|
|
use App\Insurance\Entity\EntityInsurancePricing;
|
|
use App\Insurance\Entity\TenantInsurance;
|
|
use App\Insurance\Entity\TenantServiceCoverage;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
|
|
/**
|
|
* Removes the insurance configuration a doctor/clinic owns when that entity is
|
|
* deleted. The owning columns (entity_type, entity_id) are polymorphic
|
|
* (doctor|clinic), so no database FK can cascade this — the cleanup is enforced
|
|
* here in the application. Coverage rows are removed via their owning
|
|
* tenant_insurance ids.
|
|
*/
|
|
final class TenantInsuranceCleanupService
|
|
{
|
|
public function __construct(private readonly EntityManagerInterface $em) {}
|
|
|
|
public function purgeForEntity(string $entityType, int $entityId): void
|
|
{
|
|
$tenantInsuranceIds = $this->em->createQuery(
|
|
'SELECT t.id FROM ' . TenantInsurance::class . ' t
|
|
WHERE t.entityType = :type AND t.entityId = :id'
|
|
)->setParameter('type', $entityType)
|
|
->setParameter('id', $entityId)
|
|
->getSingleColumnResult();
|
|
|
|
if ($tenantInsuranceIds !== []) {
|
|
$this->em->createQuery(
|
|
'DELETE ' . TenantServiceCoverage::class . ' c
|
|
WHERE c.tenantInsuranceId IN (:ids)'
|
|
)->setParameter('ids', $tenantInsuranceIds)->execute();
|
|
}
|
|
|
|
$this->em->createQuery(
|
|
'DELETE ' . TenantInsurance::class . ' t
|
|
WHERE t.entityType = :type AND t.entityId = :id'
|
|
)->setParameter('type', $entityType)
|
|
->setParameter('id', $entityId)
|
|
->execute();
|
|
|
|
$this->em->createQuery(
|
|
'DELETE ' . EntityInsurancePricing::class . ' p
|
|
WHERE p.entityType = :type AND p.entityId = :id'
|
|
)->setParameter('type', $entityType)
|
|
->setParameter('id', $entityId)
|
|
->execute();
|
|
}
|
|
}
|