feat(appointment): log cancellation events and show them in a Timeline
Introduce the first per-appointment event system. On cancel (via the status
or general update endpoints) an AppointmentEvent (type=cancelled, «نوبت لغو
شد») is recorded with the actor, cancel time, and an optional cancel_reason,
plus a warning-level app_log entry. New GET /appointment/{uuid}/events
returns the ordered event list. The admin appointment detail page renders a
Timeline section and the cancel dialog now collects an optional reason.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Appointment\Repository;
|
||||
|
||||
use App\Appointment\Entity\AppointmentEvent;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
class AppointmentEventRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry) { parent::__construct($registry, AppointmentEvent::class); }
|
||||
|
||||
public function save(AppointmentEvent $e, bool $flush = true): void
|
||||
{
|
||||
$this->getEntityManager()->persist($e);
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/** رویدادهای یک نوبت بهترتیب زمان (قدیمی → جدید)، بهصورت آرایه. */
|
||||
public function findByAppointmentUuid(string $appointmentUuid): array
|
||||
{
|
||||
return $this->createQueryBuilder('e')
|
||||
->select('e.type AS type', 'e.title AS title', 'e.actorName AS actor_name', 'e.reason AS reason', 'e.createdAt AS created_at')
|
||||
->join('e.appointment', 'a')
|
||||
->where('a.uuid = :uuid')->setParameter('uuid', $appointmentUuid)
|
||||
->orderBy('e.createdAt', 'ASC')
|
||||
->getQuery()->getArrayResult();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user