One vertical slice at a time.
Zero split-brain data.
Each component is designed so that customer-facing views, staff back-office workflows, and the underlying database remain consistent at every step. This page tracks the scope, data ownership, and workflow improvements for every stage of the rebuild.
Network Isolation & Clean PostgreSQL Pipeline
Before writing new customer features, we sever public access to the vulnerable PHP 7.4 environment while keeping office staff operational over NetBird VPN.
Infrastructure Checklist
- Remove public ingress/NAT rules pointing to the legacy PHP 7.4 server.
- Verify office staff can reach legacy
/adminover NetBird VPN. - Audit and disable unnecessary legacy cron jobs on the isolated VM; restrict outbound firewall rules.
- Provision clean PostgreSQL instance and Node.js runtime container on Proxmox/Debian.
Data & ETL Foundation
- Initialise Drizzle ORM schema (
src/db/schema.ts) with transactional migrations. -
Build idempotent ETL script (
npm run db:sync-legacy) readingusers,orders,order_item,order_user_info, anduser_vouchersfrom legacy MariaDB into PostgreSQL viaON CONFLICT DO UPDATE. - Schedule ETL sync every 1–2 minutes so staff edits in legacy
/adminpropagate automatically.
Customer Portal & Ticket Retrieval
Gets Highclere Castle's public web presence back online immediately with a reassuring, heritage-styled status page and full self-service access for every customer holding existing tickets or orders.
Deliverables
- Public Holding & Maintenance Landing Page: Explains temporary maintenance for new bookings while providing prominent buttons to retrieve existing tickets.
- Passwordless Email OTP / Magic Link Login: Powered by Postmark API. Eliminates plaintext password risk and automatically consolidates duplicate legacy accounts sharing an email.
- Gate-Side Quick Order Lookup: Allows visitors at the Castle gates to pull up a single order
using
Order Number + Email + Billing Postcodewithout waiting for an email. - Dynamic SVG Code 128B Tickets & VAT Invoices: Renders crisp vector barcodes
(
{order_number}-{order_item_id}-{legacy_user_id}) optimised for mobile screens and@media print. - Legacy URL Compatibility: Preserves/redirects
/customers/*links from old confirmation emails and routes/categories/*and/coachvisits/*to the holding view.
Explicitly Deferred from Component 1
- Billing / delivery address book editing (read-only until Component 3 checkout launches).
- Static PDF file generation on disk (replaced by superior inline SVG barcode + print stylesheet).
- New ticket basket or payment processing.
Coach Visits Portal & Staff Coach Admin (Vertical Slice)
Because coach_companies, coach_orders, coach_times, and
coach_payments form an isolated database context in the legacy system, we cut over both the
Coach Company Portal and the Staff Coach Admin together into PostgreSQL—avoiding
any two-way sync back to MariaDB.
Coach Portal & Admin Scope
- One-time migration of all
coach_*tables into clean PostgreSQL tables. - Coach Company sign-in via Email OTP / Magic Link (retaining visible
ContactIDandGroupIDreferences for staff familiarity). - Available coach arrival date/slot requests, passenger breakdown editing (Adults, Children, Concessions, Disabled, Carers, HHA Members), and deposit/balance/extra payments.
- Staff Coach Admin view: approve a slot request (auto-rejecting competing requests for that slot), manage coach dates/times, grant expiry extensions, and export CSV manifests.
Workflow Modernisations Over Legacy
- Fix the Broken Cancellation Penalty: Replace the broken
if ($order_id = 3649)bug inCoachvisits.phpwith tested, transparent 42-day / 30-day visitor reduction penalty rules. - Eliminate Annual Column Cloning: Replace hardcoded
group_info_read_nextandmax_requests_nextcolumns with a clean per-season policy acceptance table. - Clean Notification Scheduler: Replace the 10 hardcoded boolean reminder columns on
coach_orderswith a proper scheduled notification log via Postmark.
Public Admission & Event Ticket Checkout
Replaces the 640KB legacy Tickets.php controller (which duplicated methods across dozens of seasonal
events like spring2021login, xmas20login, cegat2021login) with a single
data-driven Event & Timed-Entry Ticketing engine.
Core Capabilities
- Public Event & Admission Catalogue with date and timed-entry slot availability.
- Concurrency-safe capacity reservation in PostgreSQL (
SELECT ... FOR UPDATE). - Support for Afternoon Tea / Picnic dietary breakdowns (Standard, Vegetarian, Gluten-Free) and promotional book bundles without hardcoded SKU spaghetti.
- Online Gift Voucher balance redemption and coupon code application.
- Gateway-agnostic payment integration (Opayo / Stripe) + instant Postmark ticket confirmation email.
Bridge to Legacy Gate Scanners
If Component 3 launches before Component 4 (Staff Back-Office) is complete, newly placed orders in PostgreSQL will either include a lightweight Gate List export in the new admin or write a compatible summary record so on-site gate scanners have 100% of barcodes for each Visit Date.
Staff Back-Office (/admin) & Legacy Decommission
Migrates the remaining daily staff workflows from the NetBird-isolated CodeIgniter admin into the new application:
- Unified Order & Customer Search.
- Visit Date & Time Slot transfers with audit history.
- Full or partial Order Item / Ticket voiding and refund recording.
- One-click Gate List and catering/menu reports for Castle operations.
- Decommission Milestone: Turn off the MariaDB ETL sync and power down the legacy PHP 7.4 server permanently.
Gift Shop Merchandise & Lodge Bookings
Physical retail products and overnight accommodation (London Lodge & Grotto Lodge) represent a small fraction of online revenue and have high shipping/tax edge-case complexity:
- Physical merchandise catalogue, stock levels, and UK/EU/Rest-of-World shipping zone calculations.
- London Lodge & Grotto Lodge multi-night availability calendar and deposit/balance workflows.
- Can be built cleanly in the new app or evaluated for a dedicated retail platform once Components 1–4 are complete.