# Implementation Summary: Timezone Fix + Per-Space Settings ## Overview Fixed timezone display issues and added per-space scheduling settings to the space booking system. ## Changes Implemented ### Part A: Frontend Timezone Fix ✅ **File: `frontend/src/utils/datetime.ts`** - Added `ensureUTC()` function to handle naive datetime strings from backend - Applied `ensureUTC()` to all `new Date()` calls in: - `formatDateTime()` - `formatTime()` - `formatDateTimeWithTZ()` - `isoToLocalDateTime()` **File: `frontend/src/views/Dashboard.vue`** - Imported `ensureUTC` from utils - Applied to booking date comparisons in `upcomingBookings` computed property **Impact:** MyBookings now correctly shows times in user's timezone (e.g., 10:00-17:00 Bucharest instead of 08:00-15:00 UTC). --- ### Part B: Per-Space Scheduling Settings (Database) ✅ **File: `backend/app/models/space.py`** - Added 4 nullable columns: - `working_hours_start` (Integer) - `working_hours_end` (Integer) - `min_duration_minutes` (Integer) - `max_duration_minutes` (Integer) **File: `backend/app/schemas/space.py`** - Added 4 optional fields to `SpaceBase` and `SpaceResponse` **File: `backend/migrations/004_add_per_space_settings.sql`** - Created migration (already applied to database) **Impact:** Spaces can now override global settings. NULL = use global default. --- ### Part C: Timezone-Aware Validation ✅ **File: `backend/app/services/booking_service.py`** - Imported `Space` model and timezone utilities - Added `user_timezone` parameter to `validate_booking_rules()` - Load per-space settings with fallback to global - Convert UTC times to user timezone for working hours validation - Fix max bookings per day to use local date boundaries **File: `backend/app/api/bookings.py`** Updated 6 endpoints to pass `user_timezone`: 1. **POST /bookings (create)** - Line ~251 2. **POST /bookings/recurring** - Line ~376 - Also fixed: Now converts local times to UTC before storage 3. **PUT /bookings/{id} (update)** - Line ~503 4. **PUT /admin/.../approve** - Line ~682 - Uses booking owner's timezone 5. **PUT /admin/.../update** - Line ~865 - Uses booking owner's timezone 6. **PUT /admin/.../reschedule** - Line ~1013 - Uses booking owner's timezone **Impact:** - Working hours validation now uses user's local time (9:00 Bucharest is valid, not rejected as 7:00 UTC) - Per-space settings are respected - Recurring bookings now store correct UTC times --- ### Part D: Admin UI for Per-Space Settings ✅ **File: `frontend/src/views/Admin.vue`** - Added form section "Per-Space Scheduling Settings" - Added 4 input fields with placeholders indicating global defaults - Updated `formData` reactive object - Updated `startEdit()` to load space settings - Updated `resetForm()` to clear settings - Added CSS for form-section-header, form-row, and help-text **File: `frontend/src/types/index.ts`** - Extended `Space` interface with 4 optional fields **Impact:** Admins can now configure per-space scheduling rules via UI. --- ## Testing Checklist ### Timezone Display - [ ] User with `Europe/Bucharest` timezone sees correct local times in MyBookings - [ ] Booking created at 09:00 Bucharest shows as 09:00 (not 07:00) ### Working Hours Validation - [ ] Booking at 09:00 Bucharest (07:00 UTC) is accepted (not rejected by 8-20 rule) - [ ] User sees error message with correct timezone-aware hours ### Per-Space Settings - [ ] Create space with custom working hours (e.g., 10-18) - [ ] Booking outside custom hours is rejected - [ ] Space without settings uses global defaults - [ ] Admin UI displays and saves per-space settings correctly ### Recurring Bookings - [ ] Recurring bookings now store correct UTC times - [ ] Bookings created for multiple occurrences have consistent timezone handling --- ## Files Modified | # | File | Changes | |---|------|---------| | 1 | `frontend/src/utils/datetime.ts` | Added `ensureUTC()` + applied to 4 functions | | 2 | `frontend/src/views/Dashboard.vue` | Import and use `ensureUTC` | | 3 | `backend/app/models/space.py` | Added 4 nullable columns | | 4 | `backend/app/schemas/space.py` | Added 4 optional fields | | 5 | `backend/migrations/004_add_per_space_settings.sql` | DB migration (applied) | | 6 | `backend/app/services/booking_service.py` | Timezone-aware validation | | 7 | `backend/app/api/bookings.py` | Updated 6 callers + recurring fix | | 8 | `frontend/src/views/Admin.vue` | Admin UI for per-space settings | | 9 | `frontend/src/types/index.ts` | Extended Space interface | --- ## Known Limitations 1. **SQLite**: COMMENT ON COLUMN not supported (documented in migration file) 2. **Backward Compatibility**: Existing bookings created before fix may have incorrect times (data migration not included) --- ## Next Steps 1. Run frontend ESLint: `cd frontend && npx eslint src/utils/datetime.ts src/views/Dashboard.vue src/views/Admin.vue` 2. Run backend tests: `cd backend && pytest` (if tests exist) 3. Manual testing per checklist above 4. Consider data migration for existing bookings if needed