Domain Glossary
The legacy database mixes naming conventions from multiple eras (ps4_users, users,
shopper_group, coach_orders, DetailSagePayString). Our new codebase
enforces a single, unambiguous domain vocabulary defined in CONTEXT.md.
Customer
A person or organisation that places Orders, uniquely identified by their normalised email address across all historical purchases.
Avoid: User, shopper, client, account
Order
A confirmed purchase placed by a Customer, identified publicly by its Order Number and containing one or more Order Items.
Avoid: Transaction, purchase, basket
Order Item
A single line item within an Order representing a specific product and quantity—either a date-bound admission/event entry, physical Gift Shop merchandise, or a Lodge reservation.
Avoid: Detail, order detail, cart item
Ticket
An admission credential generated from a non-voided, date-bound Order Item, carrying a scannable barcode ({order_number}-{order_item_id}-{legacy_user_id}) that grants entry for a specific Visit Date, Visit Time, and Venue.
Avoid: E-ticket, pass, booking confirmation
Gift Voucher
A pre-paid monetary credit balance attached to a Customer with a fixed expiry date, redeemable against online Orders.
Avoid: Coupon code, discount, store credit
Gate List
A daily manifest of valid admission orders, visitor counts, and ticket barcodes exported for on-site staff to verify visitor entry at the Castle gates.
Avoid: Scanner export, attendance sheet, manifest
Coach Company
A commercial tour or group operator (identified by a ContactID) that organises group visits to the Castle under the Group Booking Policy.
Avoid: Coach user, group user, tour operator
Coach Booking
A group visit reservation (GroupID) requested by a Coach Company for a specific arrival time slot and visitor breakdown, progressing through Request, Staff Confirmation, Deposit Payment, Final Numbers & Balance Payment, and optional Extra Visitor Payment.
Avoid: Coach order, group order
Legacy Quirks Neutralised by Our Clean Schema
During our audit of oldFiles/live_files_backup_1Oct2026 and
castle_2026-10-01_10-29-32.sql, we identified the following technical traps that the ETL pipeline
cleans up before data ever reaches the new PostgreSQL database:
| Legacy Location | Legacy Behaviour / Bug | New Clean Architecture Resolution |
|---|---|---|
Customers_model::getUserLogin() | Compares users.password in plaintext; uses LIMIT 1 on non-unique email column. | Passwords dropped completely; customers deduplicated by normalised email; authentication via Postmark Email OTP + Single-Order Lookup. |
users, orders, order_item | ENGINE=MyISAM with no foreign keys, no ACID transactions, and mixed Unix INT timestamps (cdate) alongside 0000-00-00 dates. | PostgreSQL tables with strict foreign keys, ACID transactions, and normalised TIMESTAMPTZ / DATE columns. |
Ticket_print.php & order_notification_nopdf.php | Hardcodes ProductID < 500000 and a 12-element if-statement of promotional book/tea-towel SKUs (178011–181170) to decide whether to draw a barcode; writes temporary .gd2 and .png files into public webroot on every view. | ETL computes a clean boolean is_scannable_ticket and barcode_value on order_items; tickets render stateless inline Code 128B SVGs. |
Customers::orderdetails() vs Orders_model | Inconsistent void checks: some queries check void_tickets IS NULL while PHP views check void_tickets == ''. | ETL normalises void_tickets IS NOT NULL AND TRIM(void_tickets) != '' into a single boolean is_voided column. |
Coachvisits::_calculate_penalty() (line 2257) | Contains if ($order_id = 3649) { $penalty = 0; } (assignment instead of comparison), zeroing out all coach cancellation penalties. | Replaced in Component 2 with unit-tested domain function in src/domain/coach-pricing.ts. |
coach_orders & coach_companies | 10 hardcoded reminder boolean columns (seventy_day_reminder_sent, etc.) and annual cloned columns (group_info_read_next). | Replaced in Component 2 with relational coach_policy_acceptances and coach_notification_logs tables. |