Introduces /massage alongside barber and beauty: landing page, booking flow, admin support, home tile and SEO entries, in all three languages. Architecture - application/config/verticals.php + vertical_helper.php: one registry entry per vertical (branding, assets, views, behaviour flags). A fourth vertical is a config entry plus content files. - Strangler: barber and beauty keep pointing at their existing view files, so their rendered HTML is unchanged. Only massage uses the new generic pages/vertical-*.php and includes/vertical-*.php views, which collapse the four duplicated per-language nav/footer branches into one. - Pages::vertical() + one route; booking(), booking_finished(), _booking_error() and manage_booking() are now registry-driven. Worker/vertical coupling - getActiveWorkers() derives the vertical from services.service_category_id instead of the workers.is_barber / is_beauty flags, which were a hand-maintained cache of exactly that fact. Verified against production data: the derived set reproduced the stored flags for every worker, in both verticals. No schema change was needed for massage. - The legacy flags are now written through from the category so a rollback cannot strand a new worker, and the admin worker UI shows the derived verticals read-only instead of two dropdowns that controlled nothing. Bug fixes found along the way (all pre-existing) - booking_process() had no server-side category guard; cross-vertical mixing was prevented only by client-side JS. - add-service-form / add-worker-form emitted `selected` on every category option, so the newest category silently became the default. - update-service-form offered only barber/beauty, so editing a service of any other type silently rewrote it. - getWorkerScheduleByDay ignored schedule overrides while getAvailableTimes honoured them, so slots could be shown and then rejected. Added an override-aware getWorkerScheduleForDate() and used it in both guards. - Booking lists dereferenced a null service if one had been hard-deleted. - main.css: .tiles was tuned for exactly two tiles, including an absolutely-positioned .style1 at the 1280px breakpoint. Massage-specific behaviour, opt-in per vertical - strip_category_prefix: grouped service lists show "50 min" under the treatment heading rather than repeating the full name. The full name is carried in data-service-name so the totals panel stays unambiguous, and services.service_name is untouched for emails and admin. - single_service_booking: one treatment per booking, enforced in the UI and in booking_process(). Re-clicking the selection releases it. - Displayed treatment time (50/80/110 min) is in the service name; the booked slot (60/90/120 min) is service_time and covers changing and payment. service_time is never shown to the guest. DB migrations for dev/prod are in documents/ - additive only, no ALTER. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
136 lines
4.1 KiB
PHP
Executable File
136 lines
4.1 KiB
PHP
Executable File
<?php
|
|
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| AUTO-LOADER
|
|
| -------------------------------------------------------------------
|
|
| This file specifies which systems should be loaded by default.
|
|
|
|
|
| In order to keep the framework as light-weight as possible only the
|
|
| absolute minimal resources are loaded by default. For example,
|
|
| the database is not connected to automatically since no assumption
|
|
| is made regarding whether you intend to use it. This file lets
|
|
| you globally define which systems you would like loaded with every
|
|
| request.
|
|
|
|
|
| -------------------------------------------------------------------
|
|
| Instructions
|
|
| -------------------------------------------------------------------
|
|
|
|
|
| These are the things you can load automatically:
|
|
|
|
|
| 1. Packages
|
|
| 2. Libraries
|
|
| 3. Drivers
|
|
| 4. Helper files
|
|
| 5. Custom config files
|
|
| 6. Language files
|
|
| 7. Models
|
|
|
|
|
*/
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Packages
|
|
| -------------------------------------------------------------------
|
|
| Prototype:
|
|
|
|
|
| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
|
|
|
|
|
*/
|
|
$autoload['packages'] = array();
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Libraries
|
|
| -------------------------------------------------------------------
|
|
| These are the classes located in system/libraries/ or your
|
|
| application/libraries/ directory, with the addition of the
|
|
| 'database' library, which is somewhat of a special case.
|
|
|
|
|
| Prototype:
|
|
|
|
|
| $autoload['libraries'] = array('database', 'email', 'session');
|
|
|
|
|
| You can also supply an alternative library name to be assigned
|
|
| in the controller:
|
|
|
|
|
| $autoload['libraries'] = array('user_agent' => 'ua');
|
|
*/
|
|
$autoload['libraries'] = array();
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Drivers
|
|
| -------------------------------------------------------------------
|
|
| These classes are located in system/libraries/ or in your
|
|
| application/libraries/ directory, but are also placed inside their
|
|
| own subdirectory and they extend the CI_Driver_Library class. They
|
|
| offer multiple interchangeable driver options.
|
|
|
|
|
| Prototype:
|
|
|
|
|
| $autoload['drivers'] = array('cache');
|
|
|
|
|
| You can also supply an alternative property name to be assigned in
|
|
| the controller:
|
|
|
|
|
| $autoload['drivers'] = array('cache' => 'cch');
|
|
|
|
|
*/
|
|
$autoload['drivers'] = array();
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Helper Files
|
|
| -------------------------------------------------------------------
|
|
| Prototype:
|
|
|
|
|
| $autoload['helper'] = array('url', 'file');
|
|
*/
|
|
$autoload['helper'] = array('vertical');
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Config files
|
|
| -------------------------------------------------------------------
|
|
| Prototype:
|
|
|
|
|
| $autoload['config'] = array('config1', 'config2');
|
|
|
|
|
| NOTE: This item is intended for use ONLY if you have created custom
|
|
| config files. Otherwise, leave it blank.
|
|
|
|
|
*/
|
|
$autoload['config'] = array();
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Language files
|
|
| -------------------------------------------------------------------
|
|
| Prototype:
|
|
|
|
|
| $autoload['language'] = array('lang1', 'lang2');
|
|
|
|
|
| NOTE: Do not include the "_lang" part of your file. For example
|
|
| "codeigniter_lang.php" would be referenced as array('codeigniter');
|
|
|
|
|
*/
|
|
$autoload['language'] = array();
|
|
|
|
/*
|
|
| -------------------------------------------------------------------
|
|
| Auto-load Models
|
|
| -------------------------------------------------------------------
|
|
| Prototype:
|
|
|
|
|
| $autoload['model'] = array('first_model', 'second_model');
|
|
|
|
|
| You can also supply an alternative model name to be assigned
|
|
| in the controller:
|
|
|
|
|
| $autoload['model'] = array('first_model' => 'first');
|
|
*/
|
|
$autoload['model'] = array();
|