Commit graph

58 commits

Author SHA1 Message Date
131477b7f3
Make error messages more descriptive
- Added specific slot time and date to availability error message
- Added appointment ID and context to 'not found' errors
- Added formatted appointment time to past appointment cancellation errors
- Added date context to slot overlap error messages
- All errors now provide actionable information to users
2025-12-21 17:59:08 +01:00
4d5673f181
Standardize timezone usage to timezone.utc
- Replaced all UTC imports with timezone imports
- Changed all datetime.now(UTC) to datetime.now(timezone.utc)
- Consistent with booking.py and more explicit about timezone usage
- Updated models.py, routes/auth.py, and routes/invites.py
2025-12-21 17:58:43 +01:00
1a478f7583
Make copy operation atomic with explicit transaction handling
- Wrapped copy operation in try/except with explicit rollback
- Added comments explaining atomicity
- Ensures all-or-nothing behavior for copying to multiple dates
2025-12-21 17:57:42 +01:00
c24597edb4
Be explicit about eager loading in queries
- Added explicit joinedload(Appointment.user) to admin appointment queries
- Makes the eager loading intention clear and explicit
- Replaced comment-based documentation with actual query options
2025-12-21 17:57:23 +01:00
64eeaadd28
Extract weekend detection logic to shared utility
- Created isWeekend() function in utils/date.ts
- Replaced inline weekend detection logic in availability page
- More reusable and testable
2025-12-21 17:57:06 +01:00
1497a81cd5
Add backend validation for note length using constant
- Updated BookingRequest validator to use NOTE_MAX_LENGTH constant
- Replaced hardcoded 144 with constant for consistency
- Error message now includes the actual max length value
2025-12-21 17:56:38 +01:00
3c13270bc0
Standardize time formatting and avoid string slicing
- Created formatTimeString() utility to properly parse time strings
- Replaced all .slice(0, 5) calls with proper time formatting
- Handles both 'HH:MM:SS' and 'HH:MM' formats safely
- More robust than string slicing
2025-12-21 17:56:20 +01:00
a25e84e197
Fix copy button symbol to use more standard Unicode character
- Replaced ⎘ (U+2398) with 📋 (clipboard emoji) for better cross-platform compatibility
- More recognizable and widely supported symbol
2025-12-21 17:55:06 +01:00
5c396e62ec
Extract duplicate date range helpers to shared utility
- Created getDateRange() function in utils/date.ts
- Replaced getBookableDates() and getDateRange() duplicates
- Both booking and availability pages now use shared function
- Function accepts minAdvanceDays and maxAdvanceDays as parameters
2025-12-21 17:54:49 +01:00
208278bddb
Use MIN_ADVANCE_DAYS constant globally instead of hardcoded value
- Updated availability.py to use MIN_ADVANCE_DAYS constant instead of hardcoded timedelta(days=1)
- Ensures consistency between booking and availability date ranges
- Both now use the same constant from shared_constants
2025-12-21 17:53:47 +01:00
a14405a998
Derive slot validation from config instead of hardcoded values
- Created _get_valid_minute_boundaries() helper that derives valid minutes from SLOT_DURATION_MINUTES
- Replaced hardcoded (0, 15, 30, 45) with dynamic calculation
- Error message now includes valid minute values for better clarity
2025-12-21 17:53:35 +01:00
40b193238e
Move TIME_OPTIONS outside component
- TIME_OPTIONS is now computed at module level, not inside component
- generateTimeOptions now accepts slotDurationMinutes as parameter
- Prevents unnecessary recomputation on every render
2025-12-21 17:53:17 +01:00
02212ba478
Make error handling consistent across frontend
- Standardized all error handling to use ternary pattern
- Changed if/else blocks to ternary operators for consistency
- Updated booking, appointments, and admin appointments pages
2025-12-21 17:50:52 +01:00
8cc2cfa2e4
Extract duplicate status display logic to shared utility
- Created frontend/app/utils/appointment.ts with getStatusDisplay()
- Supports context-aware text (isOwnView parameter)
- Updated both appointments pages to use shared utility
2025-12-21 17:50:24 +01:00
d24acfd322
Extract duplicate AppointmentResponse construction to helper
- Created _to_appointment_response() helper function
- Replaced 5 duplicate AppointmentResponse constructions with helper calls
- Helper handles both explicit user_email and eager-loaded user relationship cases
2025-12-21 17:49:37 +01:00
6ff3c0a133
Extract duplicate date formatting functions to shared utilities
- Created frontend/app/utils/date.ts with formatDate, formatTime, formatDateTime, formatDisplayDate
- Created frontend/e2e/helpers/date.ts with formatDateLocal, getTomorrowDateStr
- Updated all frontend pages and e2e tests to use shared utilities
- Removed duplicate date formatting code from 6 files
2025-12-21 17:48:17 +01:00
eefdfd714f
Fix: useCallback dependency array in availability page
Compute dates inside fetchAvailability callback to avoid
dependency on external variable that changes on every render.
2025-12-21 17:32:55 +01:00
77e7f98e1e
Fix: Add pagination to admin appointments endpoint
- Added pagination with page/per_page query params
- Fixed N+1 query by using eager-loaded user relationship
- Removed unused _get_user_email helper function
- Updated frontend to handle paginated response
- Regenerated API types
2025-12-21 17:32:25 +01:00
1cd60b4bbc
Fix: Load booking constants from shared/constants.json
Created shared_constants.py module that loads constants from the
shared JSON file. Updated availability.py and booking.py to import
from this module instead of hardcoding values.

This ensures backend and frontend stay in sync with the same source
of truth for booking configuration.
2025-12-21 17:29:39 +01:00
19c313767c
Fix: Validate source_date in copy availability endpoint
Added validation to ensure source_date is within the allowed range
(tomorrow to +30 days) for consistency with target_dates validation.
2025-12-21 17:28:21 +01:00
63cf46c230
Fix: Prevent cancellation of past appointments
Add check to both user and admin cancel endpoints to reject
cancellation of appointments whose slot_start is in the past.
This matches the spec requirement that cancellations can only
happen 'before the appointment'.

Added tests for both user and admin cancel endpoints.

Also includes frontend styling updates.
2025-12-21 17:27:23 +01:00
89eec1e9c4
Fix flaky E2E tests with proper selectors and response waits
- Use data-testid attributes to target specific day cards in availability tests
- Wait for networkidle before interacting with page elements
- Set up PUT and GET response listeners before triggering actions
- Add retry logic for availability API in booking tests
- Fix appointments test to handle multiple 'Booked' elements with .first()
- Increase parallel workers to 12 for faster test execution
2025-12-21 01:13:10 +01:00
b3e00b0745
Phase 6: Admin appointments view and cancellation with UI and backend tests 2025-12-21 00:30:09 +01:00
5108a620e7
Phase 5: User appointments view and cancellation with UI and e2e tests 2025-12-21 00:24:16 +01:00
8ff03a8ec3
Phase 4: Booking UI for regular users with date selection, slot booking, and e2e tests 2025-12-21 00:15:29 +01:00
06817875f7
Phase 3: Appointment model & booking API with timezone fix 2025-12-21 00:03:34 +01:00
f6cf093cb1
Phase 2: Admin availability UI with calendar grid, edit modal, and e2e tests 2025-12-20 23:54:34 +01:00
64d2e99d73
Phase 1: Add Availability model and API
- Create Availability model with date, start_time, end_time
- Add availability schemas with 15-minute boundary validation
- Add admin endpoints:
  - GET /api/admin/availability - query by date range
  - PUT /api/admin/availability - set slots for a date
  - POST /api/admin/availability/copy - copy to multiple days
- Add 26 tests covering permissions, CRUD, and validation
2025-12-20 23:36:11 +01:00
6c1a05d93d
Phase 0: Add booking permissions and constants
- Add AppointmentStatus enum (booked, cancelled_by_user, cancelled_by_admin)
- Add booking permissions for regular users (book_appointment, view_own_appointments, cancel_own_appointment)
- Add availability/appointments permissions for admin (manage_availability, view_all_appointments, cancel_any_appointment)
- Add booking constants to shared/constants.json (slotDurationMinutes, maxAdvanceDays, minAdvanceDays, noteMaxLength)
- Update validate_constants.py to validate new sections
2025-12-20 23:30:08 +01:00
c9b5cab0d6
revert typo 2025-12-20 23:10:05 +01:00
917ab0a584
docs and tools 2025-12-20 23:09:46 +01:00
d3638e2e69
implemented 2025-12-20 23:06:05 +01:00
a31bd8246c
reviewed 2025-12-20 22:38:39 +01:00
a56a4c076a
first implementation 2025-12-20 22:18:14 +01:00
1eb4641ed9
remove testing doc 2025-12-20 19:09:49 +01:00
eccad00513
add some cursor rules 2025-12-20 19:09:33 +01:00
820c01097c
tiny error message fix 2025-12-20 19:09:19 +01:00
92489e5e8a
final review 2025-12-20 12:11:22 +01:00
976a880312
second review 2025-12-20 11:58:35 +01:00
23049da55a
first round of review 2025-12-20 11:43:32 +01:00
870804e7b9
first implementation 2025-12-20 11:12:11 +01:00
79458bcba4
missing tests 2025-12-19 22:08:31 +01:00
75cfc6c928
some fixes and refactors 2025-12-19 11:08:19 +01:00
ead8a566d0
small validation fixes 2025-12-19 10:52:47 +01:00
bbc5625b2d
second round of review 2025-12-19 10:38:15 +01:00
7140cf6f27
first round of review 2025-12-19 10:30:23 +01:00
5908660e56
fix flaky test 2025-12-19 10:15:14 +01:00
409e0df9a6
implemented 2025-12-19 10:12:55 +01:00
40ca82bb45
finish branch 2025-12-19 00:12:43 +01:00
66bc4c5a45
review 2025-12-18 23:54:51 +01:00