Skip to main content

Overview

System Architecture & Implementation Overview

This document summarizes the end‑to‑end architecture of the new Lazy L&B Ranch reservation platform, highlights the depth of work delivered, and clarifies what is ready for testing and launch.

Summary

  • Objective: Replace the legacy WordPress workflow with a modern, secure, fully integrated reservations platform.
  • Status: Feature-complete and deployed to AWS; connected to FluidPay sandbox; ready for client testing with migrated data.
  • Cutover plan: Perform a final data import from WordPress, switch FluidPay to production keys, and direct all users to the new system.

Feature highlights

  • Reservation lifecycle: Request → Review → Confirm → Pay deposit → Forms completion → Final payment → Check‑in.
  • Guest portal: Secure login, view reservations, complete rider forms, e‑sign liability text, boot size entry, and payment history.
  • Admin console: Reservations, guests, cabins, horses, year/season config, variable templates, email templates, boot rentals.
  • Payments (FluidPay): Deposit and final payments; production‑ready integration with sandbox keys in testing; receipts and transaction details stored.
  • Financial engine: Per‑reservation financials including daily rate, deposit required/received, final payments, credit‑card fee %, gratuity rate, airport transfer fees, surcharge, and tax fields (sales & lodging) with transaction ledger.
  • Email automation (Gmail API): Confirmation, deposit received, missing rider forms, and final‑payment reminders with date‑based scheduling and idempotency.
  • WordPress compatibility: Password verification for $wp$ bcrypt and $P$ MD5 formats to allow seamless account migration.
  • Availability and cabin assignment: Weekly availability views and per‑week cabin capacity; assignment workflows for admins.

Key modules and responsibilities

  • API Routes (packages/backend/src/routes/*): Auth, reservations, payments, guest data, admin resources.
  • Controllers (packages/backend/src/controllers/*): Business rules for reservation lifecycle, financials, and communications.
  • Services (packages/backend/src/services/*):
    • fluidPayService.ts: Transaction processing, retrieval, and search.
    • Email service using Gmail API with exponential backoff and auditing.
  • Middleware (packages/backend/src/middleware/*): JWT auth, role checks, request validation.
  • Utils (packages/backend/src/utils/*): WordPress auth compatibility, formatting helpers.

Data model (high level)

  • User (billing contact) → many Reservations; password hashes support WordPress formats and standard bcrypt.
  • Reservation → dates, status, counts, guests, cabin assignment, activities, forms, and a single aggregated ReservationFinancial record.
  • Guest → optional RiderForm, optional BootRental.
  • ReservationFinancial → rates, discounts, gratuity, credit‑card fee %, surcharges, taxes, deposit/final status, and related PaymentTransactions.
  • EmailTemplate + EmailLog → versioned, auditable communications with variable substitution.

See docs/architecture/database-schema.md for an expanded schema view.

Security and authentication

  • JWT auth for guests and admins with role checks on admin routes.
  • Password hashing: Supports WordPress $wp$ bcrypt and $P$ MD5 formats during transition; standard bcrypt for new accounts.
  • Transport security: HTTPS enforced end‑to‑end via CloudFront and the Application Load Balancer.

Integrations

  • FluidPay: Direct API integration using environment‑scoped private/public keys; sandbox used in testing; switch to production keys at go‑live.
  • Gmail API: Outbound transactional emails with daily scheduling, retry, and audit logging.

Deployment and operations

Monorepo structure

The system is a monorepo with three deployable parts: a React frontend, an Express/Node API, and a PostgreSQL database, plus integrations for payments and email.

  • Frontend (packages/frontend/): React 18 + TypeScript + Vite; component library and form system for reservations, rider forms, payments, and admin features.
  • Backend (packages/backend/): Node.js + Express + TypeScript; Prisma for data access; role‑based API; payment and email services; scheduler tasks.
  • Documentation (docs/): Role‑oriented docs (admin, guest) and technical references (API, schema, stack, email system).

High-level architecture

  • AWS footprint: CloudFront + S3 (frontend), ALB + EC2 (API), RDS/PostgreSQL, and S3 for backups.
  • Deployment:
    • Simple SSH-based deployment: Single command ./deploy.sh from local development
    • Frontend: Built locally, synced to S3 with smart diff (only changed files), CloudFront invalidation
    • Backend: Built locally, packaged as TAR, uploaded via S3, extracted and restarted on EC2 via SSH
    • Database: Separate ./push-local-db-to-aws-ssh.sh for database updates or ./migrate-production.sh for schema-only migrations
    • Cost savings: Reduced from $400-600/month to ~$55-80/month by eliminating CodePipeline/CodeBuild complexity
  • Backend deployment (zero‑downtime):
    • Local build creates backend-deploy.tar.gz with compiled code, dependencies, and Prisma schema
    • SSH deployment extracts package to /home/ec2-user/lazylb-backend and installs production dependencies
    • PM2 gracefully reloads the app: pm2 startOrReload ecosystem.config.js --env production
    • PM2 configuration: ecosystem.config.js runs the API in cluster mode with instances: 2 to allow graceful reloads
    • Health checks: packages/backend/health-check.sh verifies PM2 online status and /health readiness with retries
  • Traffic and endpoints:
    • ALB: lazylb-api-alb on ports 80/443 forwards to target group lazylb-api-tg on port 3000; health check path /health (HTTP 200).
    • Public API base URL: https://api.lazylb.com. Frontend and build now reference the ALB domain (not instance IP).
    • Frontend: Hosted in S3 (lazylb-frontend-…) behind CloudFront. Deploy syncs packages/frontend/dist to S3 and performs a CloudFront invalidation.
  • Observability and ops:
    • PM2 logs: /home/ec2-user/.pm2/logs/ (lazylb-backend*.log)
    • Health: GET /health served by the API and polled post‑deploy; ALB target health monitored in AWS
    • Access: SSH key-based access to EC2 instance for diagnostics and manual operations
    • Monitoring: ./monitor-backend.sh script for real-time backend health monitoring
  • Configuration and secrets:
    • Environment variables managed in AWS Secrets Manager (lazylb/prod/env in us-west-2)
    • Deployment scripts automatically fetch secrets and create .env file on the instance
    • No hardcoded secrets in codebase or deployment scripts
  • Operational runbooks:
    • Deploy application: ./deploy.sh (builds, uploads, and restarts backend; syncs frontend to S3)
    • Deploy database: ./push-local-db-to-aws-ssh.sh (full database replacement) or ./migrate-production.sh (schema migrations only)
    • Check status: ./status.sh (verifies all services are healthy)
    • Verify: Check ALB target health → https://api.lazylb.com/health → load the app at https://reservations.lazylb.com/
    • Instance checks (via SSH): pm2 list, pm2 logs lazylb-backend, curl http://localhost:3000/health
    • Cache: CloudFront invalidation is automatic during frontend deployment

Data migration (from WordPress)

  • Export and import scripts to transform WordPress data into the new normalized schema.
  • Historical reservations imported with adult/youth/child derivations when possible; unknowns default to adult; rider form data imported as best as possible

Go‑live checklist

  • Switch FluidPay from sandbox to production API URL and keys.
  • Perform final export from WordPress and import into the new database; archive previous test data.
  • Verify automated email schedules and templates; confirm final payment dates and rider‑form reminders.
  • Validate ALB target health, /health endpoint, and CloudFront invalidation.