feat(appointment): book with patient data, TTL lock, atomic conflict

book() now accepts for_self plus patient_* fields: for_self fills the
patient from the paying user's profile, otherwise patient_name/mobile are
required (422 if missing) and the rest are stored. Every booking starts
pending with a 15-minute expires_at. Persisting goes through
bookAtomically (re-check inside a transaction) so two concurrent requests
for the same slot can't both win — the loser gets 409.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-06-15 17:56:56 +03:30
co-authored by Claude Opus 4.8
parent 14ac01d597
commit aa2e46dfdb
3 changed files with 50 additions and 4 deletions
@@ -0,0 +1,7 @@
<?php
namespace App\Appointment\Repository;
class SlotTakenException extends \RuntimeException
{
}