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.shfrom 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.shfor database updates or./migrate-production.shfor schema-only migrations - Cost savings: Reduced from $400-600/month to ~$55-80/month by eliminating CodePipeline/CodeBuild complexity
- Simple SSH-based deployment: Single command
- Backend deployment (zero‑downtime):
- Local build creates
backend-deploy.tar.gzwith compiled code, dependencies, and Prisma schema - SSH deployment extracts package to
/home/ec2-user/lazylb-backendand installs production dependencies - PM2 gracefully reloads the app:
pm2 startOrReload ecosystem.config.js --env production - PM2 configuration:
ecosystem.config.jsruns the API inclustermode withinstances: 2to allow graceful reloads - Health checks:
packages/backend/health-check.shverifies PM2 online status and/healthreadiness with retries
- Local build creates
- Traffic and endpoints:
- ALB:
lazylb-api-albon ports 80/443 forwards to target grouplazylb-api-tgon 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 syncspackages/frontend/distto S3 and performs a CloudFront invalidation.
- ALB:
- Observability and ops:
- PM2 logs:
/home/ec2-user/.pm2/logs/(lazylb-backend*.log) - Health:
GET /healthserved 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.shscript for real-time backend health monitoring
- PM2 logs:
- Configuration and secrets:
- Environment variables managed in AWS Secrets Manager (
lazylb/prod/envinus-west-2) - Deployment scripts automatically fetch secrets and create
.envfile on the instance - No hardcoded secrets in codebase or deployment scripts
- Environment variables managed in AWS Secrets Manager (
- 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 athttps://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
- Deploy application:
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,
/healthendpoint, and CloudFront invalidation.