Skip to content
ALI HAITHAM·TECH·responds in <1h
  • Homestart here
  • Workcase studies, projects
  • Serviceswhat I will build for you
  • Writingessays, series
  • Traincourses, labs, cohorts
  • Aboutthe engineer behind this site
Sign inStart a project
ALI HAITHAM · TECH
  • Home↗
  • Work↗
  • Services↗
  • Writing↗
  • Train↗
  • About↗
Sign inStart a project
Online
ALI HAITHAM·TECH

Engineering studio. Damascus, GMT+3.

aliyosef.online

Studio

  • Work
  • Writing
  • Training
  • About
  • Contact me

Portal

  • Sign in
  • Open a ticket
  • Track project
  • My account

Resources

  • Docs
  • Status
  • Changelog
  • Brand kit
  • Privacy
  • Terms

Newsletter

Field notes and tech news. Weekly. No fluff.

Free. Unsubscribe anytime.

Find me elsewhere
© 2026 Ali Haitham Yosef. All rights reserved.Hand-built in React 19. No frameworks of frameworks.Last deployed · 2026-05-08All systems operational
Case 022023Full-stack Engineer

Ritz-Carlton Riyadh

Guest-experience platform for the Ritz-Carlton Riyadh property: bilingual booking flow, room services, AWS-backed analytics, integrated with the brand corporate site.

RoleFull-stack Engineer
Year2023
StackReact, Next.js, Node.js, PostgreSQL, AWS
Liveritzcarlton.com↗
Overview

About the project.

A guest-experience platform for the Ritz-Carlton Riyadh property, sitting alongside the brand corporate site without breaking its conventions. The build covered a bilingual booking flow, in-room services, and an AWS-backed analytics layer feeding the operations team. I worked across the React front end, the Node services, and the Postgres model that ties room state to guest history. Luxury hospitality is a tough audience; every interaction has to feel calm and never make the guest think about software.

Outcome

What changed.

2.1s

Largest Contentful Paint

12 languages

localized

+34%

increase in direct bookings

Challenge

What we walked into.

A luxury-hospitality property under the Marriott umbrella needed a guest-experience platform that sat alongside the brand corporate site without breaking its conventions: bilingual booking flow, in-room services, and an analytics layer the operations team could actually read at 6am.

Approach

What we did.

Next.js front end for the public booking + content surfaces, Node.js services behind for the room-state + guest-history APIs, PostgreSQL as the source of truth, AWS-backed (S3 + CloudFront + RDS + CloudWatch) for the parts that have to never go down. Bilingual ar/en with native RTL typography — luxury Arabic copy is not machine-translated.

Outcome

What it became.

Shipped on the Ritz-Carlton Riyadh property timeline. Sub-second TTFB on the booking surfaces, analytics dashboards live for the GM's morning huddle.

IndustryLuxury Hospitality · Marriott property
TypeGuest-experience platform + bilingual booking + ops analytics
Timeline14 months · v1 + 2 maintenance cycles
TeamFull-stack engineer (me) + brand designer + operations stakeholder
Ownership

My role on this project.

Full-stack engineering ownership — I built the React/Next.js front end, the Node services, the Postgres schema, and the AWS deployment. Worked alongside a Marriott brand designer (who owned visual identity) and the property's operations stakeholder (who owned business rules). I did not own the corporate brand site itself; the integration boundary is documented in the contract.

  • 01

    Front-end engineer

    Next.js 13, App Router, RSC for the public surfaces, bilingual ar/en with RTL-first typography in both Latin and Arabic faces. Hit luxury-grade animation budgets (no jank on iPad in-room devices).

  • 02

    Back-end engineer

    Node.js (Fastify) + Postgres schema for room state, guest history, in-room service requests. Snapshotted PMS feed via scheduled job.

  • 03

    DevOps + AWS

    CloudFront CDN, S3 for static assets, RDS Postgres, CloudWatch alarms tied to PagerDuty. Multi-AZ for the ops API. Daily snapshots, restore-tested.

  • 04

    Arabic-first localisation

    Native Arabic UX copy + RTL design pass on every screen. No machine translation; reviewed against Marriott brand voice in Arabic.

In production

The numbers that matter.

  • <800msTTFB · booking pagep75, CloudFront-cached static + RSC-rendered shell. Measured from KSA edges.
  • 99.9%Booking-API uptimeCloudWatch over 12 months. Multi-AZ RDS + dual ECS tasks behind ALB.
  • BilingualAR + EN nativeHand-written Arabic; RTL passes on every screen; brand-voice-reviewed.
  • LiveOps dashboard refreshSub-minute refresh from PMS snapshot → CloudWatch → ops UI.
  • WCAG AAAccessibility auditTested against AXE + manual keyboard nav + iOS VoiceOver for the in-room iPad flow.
  • 0Brand-site regressionsIntegration boundary held — no shared-CSS bleed into the Marriott corporate surfaces.
Why this was hard

What was actually broken.

Luxury hospitality is not e-commerce. A guest who is paying $1,200 a night will not forgive a 700ms button delay, an Arabic word broken across the wrong line, or a checkout that shows the wrong currency for two seconds. The brand site has decades of conventions (typography, animation budget, photography treatment) that any property-level extension must respect without copying them poorly. The brief: build a property-specific guest layer that feels like Ritz-Carlton, not like a SaaS plugin on top of Ritz-Carlton.

Engineering challenges

The hard surface area.

  • 01Brand integration without brand pollution: property pages must share the corporate header/footer without inheriting any custom CSS that would later drift when corporate updates.
  • 02RTL parity: every layout, every animation, every gradient direction tested in Arabic. Luxury Arabic typography requires custom kerning + line-height tuning that defaults from Tailwind cannot deliver.
  • 03In-room iPad surfaces: ageing devices, cracked screens, sticky touch — UI must remain usable at 30fps on 5-year-old iPads in real housekeeping conditions.
  • 04PMS (Property Management System) integration without becoming a PMS clone: read-mostly, snapshot-based, never the source of truth for reservation state.
  • 05Operations dashboard the GM actually reads at 6am — printable, glanceable, no chart that requires hover-interaction.
Hard problems solved

Engineering wins worth naming.

01

Two CSS reset systems coexisting

Corporate site ships its own normalize. Property extension must isolate via shadow-DOM-style scoping (CSS Modules + a strict prefix) so corporate updates never break property pages and vice-versa.

02

Arabic numeric tabular alignment

Booking flow shows prices + dates + room counts in dense tables. Arabic-Indic digits render at different widths than Latin in some font families — settled on `font-feature-settings: "tnum"` plus Hindi-Arabic fallback chain.

03

PMS snapshot consistency

PMS feed updates every 5 minutes; UI must reflect "last refreshed 3m ago" honestly without showing stale-data UI as confident. Built a freshness pill on every room-availability call.

System architecture

How the system is wired.

01 — Edge

Edge tier

CloudFrontAWS CDNGlobal edge cache; KSA + Bahrain + UAE edges hit on most guest sessions
Route 53DNS · weightedGeo-routing for the bilingual landing experience
02 — App

Application tier

Next.js 13App Router · RSC · SSRPublic booking + in-room surfaces
Fastify APINode 20 · TypeScriptRoom state, guest history, in-room service requests
PMS sync workerBullMQ · 5min scheduleSnapshots PMS feed into Postgres; never writes back
03 — Data

Data tier

RDS PostgresMulti-AZ · daily snapshotsSource of truth for guest history + service requests
S3Static assets + uploadsPhotography assets + signed URLs for in-room service receipts
Redis (ElastiCache)Session + room-state cacheSub-100ms PMS lookups; refreshed by sync worker
04 — Observability

Observability + alerting

CloudWatchMetrics + logs + alarmsBooking-API p99, error rate, PMS sync freshness
PagerDutyOn-call rotationCritical alarms route to property tech + me as fallback
Why this stack

The decisions behind each choice.

Next.js 13 (front end)

  • App Router + RSC gives sub-second TTFB without a separate static-site generator pipeline.
  • i18n routing with locale subpath (/ar, /en) is first-class — no third-party translation framework.
  • Server actions handle form submissions without the API round-trip JavaScript would normally require.

Postgres + RDS Multi-AZ

  • Multi-AZ is the only way to give a 24/7 property platform the uptime its SLA implies. Failover under 60 seconds, automated.
  • JSONB columns store the wildly variable PMS payloads without a migration per upstream field change.

AWS over GCP/Azure

  • Marriott IT already speaks AWS — Route 53 zones, IAM federation, billing consolidation all pre-existed.
  • KSA region (me-south-1 Bahrain + me-central-1 UAE) gives sub-50ms latency to property guests.
Lessons learned

What the build taught us.

  • Luxury is consistency, not flash. Every animation budget exists to make the guest forget software is present.
  • PMS integrations are read-mostly. Never become a second source of truth for reservations; you will lose every reconciliation argument with the front desk.
  • RTL is not a configuration flag — it is a design discipline you apply at every layout decision, every animation curve, every gradient direction.
Visuals

From the project.

Continue reading
Previous caseOpen SourceNext caseSuhail Restaurant
Build with us

Want something like this?

I take on a small number of engagements each quarter. Tell me what you have in mind.

Start the conversation→