Files
studiobeve.no/CLAUDE.md
T
2026-05-09 12:42:26 +00:00

121 lines
5.8 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project overview
Online booking platform for Studio Beve (barber + beauty salon, Norway). Guests browse services, book appointments, and receive email confirmations. Admins manage services, workers, bookings, and schedules via an admin portal. Multilingual: Norwegian (`no`), English (`en`), Hungarian (`hu`).
## Stack
- **Framework**: CodeIgniter 3 (PHP MVC), entry point `index.php`
- **Database**: MySQL — credentials in `application/config/database.php`
- **Email**: PHPMailer 6 via `vendor/autoload.php`
- **Google Calendar**: `google/apiclient:^2.0`, service account key at `application/config/service-account-key.json`
- **Frontend**: jQuery, jQuery UI datepicker, moment.js, Font Awesome, Google reCAPTCHA
- **Dependencies**: managed via Composer (`composer.json`)
## Development commands
```bash
# Install/update PHP dependencies
composer install
composer update
# No build step — PHP files are served directly by the web server
# No test runner is configured (composer.json has a test:coverage script but no tests exist)
```
Deployment is file-based: copy changed files to the live server. Database migrations must be run separately on the live MySQL instance.
## Architecture
### MVC layout
| Layer | Location | Key files |
|-------|----------|-----------|
| Controllers | `application/controllers/` | `Pages.php` (public + booking), `Admin.php` (admin portal), `Login.php`, `UserManagement.php` |
| Models | `application/models/` | `Service_model.php` (services, workers, bookings, schedules), `User_model.php` (users, `sendEmail()`), `Log_model.php` |
| Views | `application/views/` | `pages/` (public), `admin/` (admin portal), `includes/` (shared skeletons) |
| Libraries | `application/libraries/` | `GoogleCalendar.php` (createEvent, updateEvent, deleteEvent — failures never break booking flow) |
| Config | `application/config/` | `routes.php`, `database.php`, `google_calendar.php` |
### Public booking flow
1. Guest selects services → worker → date/time → contact info (multi-step form)
2. POST to `booking-process` → validates → saves to DB → sends email → redirects to `booking-finished`
3. Confirmation email contains a unique manage link: `SITEURL + lang + /manage-booking/ + manage_token`
### Guest self-management
- Token in `bookings.manage_token` (VARCHAR 64, UNIQUE), generated via `bin2hex(random_bytes(16))`
- Routes: `(:any)/manage-booking/(:any)`, `manage-booking-process`, `manage-booking-cancel`
- 24h cutoff: modifications/cancellations blocked if appointment is less than 24h away
- Emails sent to guest + CC evelin@studiobeve.no on modify/cancel
### AJAX endpoint
`Pages::ajax()` handles all async requests: `getAvailableTimes`, `getAvailableWorkers`, etc.
`getAvailableTimes($worker_id, $date, $servicelength)` excludes already-booked slots, enforces closing time (18:00), max 3-month booking window, and floating lunch breaks.
### Worker scheduling
- Regular hours in `worker_schedule` table
- Day-off/absence overrides in `worker_schedule_overrides` (`absence_type`: `vacation`, `sick`, `custom`, `other`; NULL = plain day-off)
- Floating lunch: `workers.lunch_window_start` / `lunch_window_end` — first free 30-min slot in window
### Google Calendar
Workers and Evelin get calendar events on new/modify/cancel bookings. Worker calendar IDs stored in `workers.google_calendar_id`. Booking event IDs stored in `bookings.gcal_event_id_worker` and `bookings.gcal_event_id_owner`.
### Admin portal
`Admin.php` handles all CRUD for services, workers, bookings, users, and the visual worker calendar (`workers/worker-calendar`).
## View conventions
- Pages use skeleton includes: `barber-skeleton-top/bottom.php` or `beauty-skeleton-top/bottom.php`
- Shared CSS: `assets/css/style.css` (booking UI), `assets/css/barber.css` / `beauty.css` (page-specific + responsive)
- Responsive breakpoint at **736px**: booking layout switches to stacked
- `.bookingButtonContainer` is `position: absolute; bottom: 10px` — must be inside a `position: relative` parent (`.BookingStepContainer`)
- `.workerTable` has `height: 85px` — override with `height: auto` when pre-rendering multiple workers statically
- `.bookingCalendar` and `.bookingResultsWrapper` use `float: left` — contain them with `overflow: auto` on the parent and `<div style="clear:both;">` before following elements
## File encoding
Source files use **CRLF (`\r\n`)** line endings. When editing large blocks, prefer Python (`open(..., newline='')`) or `sed` over the Edit tool to avoid line-ending corruption.
## Passwords & sessions
- Passwords hashed with SHA-256
- Admin session key: `$_SESSION['username']`
## Git remote
```bash
git push https://Zoli:Belepes06@gl-fraudshield.com/Zoli/studiobeve.no.git
```
## Database migrations (reference)
These have already been applied to test; must be run on live when deploying the relevant features:
```sql
-- Guest manage-booking token (2026-02-28)
ALTER TABLE bookings ADD COLUMN manage_token VARCHAR(64) UNIQUE DEFAULT NULL;
-- Google Calendar event IDs (2026-03-01)
ALTER TABLE workers ADD COLUMN google_calendar_id VARCHAR(255) NULL DEFAULT NULL;
ALTER TABLE bookings ADD COLUMN gcal_event_id_worker VARCHAR(255) NULL DEFAULT NULL;
ALTER TABLE bookings ADD COLUMN gcal_event_id_owner VARCHAR(255) NULL DEFAULT NULL;
-- Floating lunch break (2026-03-04)
ALTER TABLE workers ADD COLUMN lunch_window_start TIME NULL DEFAULT NULL, ADD COLUMN lunch_window_end TIME NULL DEFAULT NULL;
-- Visual worker calendar absence types (2026-03-04)
ALTER TABLE worker_schedule_overrides
ADD COLUMN absence_type VARCHAR(20) NULL DEFAULT NULL,
ADD COLUMN note TEXT NULL DEFAULT NULL;
```