reviewed epic 3

This commit is contained in:
Naser Mansour
2025-12-20 21:25:58 +02:00
parent b93b9363a6
commit 8b8d9735b9
8 changed files with 2116 additions and 24 deletions
@@ -11,10 +11,11 @@ So that **I can schedule a meeting with the lawyer**.
## Story Context
### Existing System Integration
- **Integrates with:** consultations table, availability calendar, notifications
- **Technology:** Livewire Volt, form validation
- **Follows pattern:** Form submission with confirmation
- **Touch points:** Client dashboard, admin notifications
- **Integrates with:** `consultations` table, availability calendar (Story 3.3), notifications system
- **Technology:** Livewire Volt (class-based), Laravel form validation, DB transactions
- **Follows pattern:** Multi-step form submission with confirmation
- **Touch points:** Client dashboard, admin notifications, audit log
- **Component location:** `resources/views/livewire/booking/request.blade.php`
## Acceptance Criteria
@@ -282,7 +283,7 @@ new class extends Component {
### 1-Per-Day Validation Rule
```php
// Custom validation rule
// app/Rules/OneBookingPerDay.php
use Illuminate\Contracts\Validation\ValidationRule;
class OneBookingPerDay implements ValidationRule
@@ -301,6 +302,96 @@ class OneBookingPerDay implements ValidationRule
}
```
### Advanced Pattern: Race Condition Prevention
The `submit()` method uses `DB::transaction()` with `lockForUpdate()` to prevent race conditions. This is an **advanced pattern** required because:
- Multiple clients could attempt to book the same slot simultaneously
- Without locking, both requests could pass validation and create duplicate bookings
The `lockForUpdate()` acquires a row-level lock, ensuring only one transaction completes while others wait and then fail validation.
## Files to Create
| File | Purpose |
|------|---------|
| `resources/views/livewire/booking/request.blade.php` | Main Volt component for booking submission |
| `app/Rules/OneBookingPerDay.php` | Custom validation rule for 1-per-day limit |
| `app/Notifications/BookingSubmittedClient.php` | Email notification to client on submission |
| `app/Notifications/NewBookingAdmin.php` | Email notification to admin for new booking |
### Notification Classes
Create notifications using artisan:
```bash
php artisan make:notification BookingSubmittedClient
php artisan make:notification NewBookingAdmin
```
Both notifications should:
- Accept `Consultation $consultation` in constructor
- Implement `toMail()` for email delivery
- Use bilingual subjects based on user's `preferred_language`
## Translation Keys Required
Add to `lang/en/booking.php` and `lang/ar/booking.php`:
```php
// lang/en/booking.php
'request_consultation' => 'Request Consultation',
'select_date_time' => 'Select a date and time for your consultation',
'selected_time' => 'Selected Time',
'problem_summary' => 'Problem Summary',
'problem_summary_placeholder' => 'Please describe your legal issue or question in detail...',
'problem_summary_help' => 'Minimum 20 characters. This helps the lawyer prepare for your consultation.',
'continue' => 'Continue',
'confirm_booking' => 'Confirm Your Booking',
'confirm_message' => 'Please review your booking details before submitting.',
'date' => 'Date',
'time' => 'Time',
'duration' => 'Duration',
'submit_request' => 'Submit Request',
'submitted_successfully' => 'Your booking request has been submitted. You will receive an email confirmation shortly.',
'already_booked_this_day' => 'You already have a booking on this day.',
'slot_no_longer_available' => 'This time slot is no longer available. Please select another.',
'slot_taken' => 'This slot was just booked. Please select another time.',
```
## Testing Requirements
### Test File Location
`tests/Feature/Booking/BookingSubmissionTest.php`
### Required Test Scenarios
```php
// Happy path
test('authenticated client can submit booking request')
test('booking is created with pending status')
test('client receives confirmation notification')
test('admin receives new booking notification')
// Validation
test('guest cannot access booking form')
test('problem summary is required')
test('problem summary must be at least 20 characters')
test('selected date must be today or future')
// Business rules
test('client cannot book more than once per day')
test('client cannot book unavailable slot')
test('booking fails if slot taken during submission', function () {
// Test race condition prevention
// Create booking for same slot in parallel/before submission completes
})
// UI flow
test('confirmation step displays before final submission')
test('user can go back from confirmation to edit')
test('success message shown after submission')
test('redirects to consultations list after submission')
```
## Definition of Done
- [ ] Can select date from calendar
@@ -318,9 +409,13 @@ class OneBookingPerDay implements ValidationRule
## Dependencies
- **Story 3.3:** Availability calendar
- **Epic 2:** User authentication
- **Story 3.3:** Availability calendar (`docs/stories/story-3.3-availability-calendar-display.md`)
- Provides `AvailabilityService` for slot availability checking
- Provides `booking.availability-calendar` Livewire component
- **Epic 2:** User authentication (`docs/epics/epic-2-user-management.md`)
- Client must be logged in to submit bookings
- **Epic 8:** Email notifications (partial)
- Notification infrastructure for sending emails
## Risk Assessment