// Projects

Booking Chatbot POC — European hotel group

Mission in progress

AI conversational assistant embedded on a European multi-brand hotel group site (8 brands). Hotel search → checkout → 3DS without leaving the conversation.

  • Next.js 15
  • TypeScript
  • Claude Sonnet 4.6
  • Apollo Client
  • GraphQL
  • Express
  • SSE streaming
  • Styled Components
  • Adyen Drop-in
  • Jest

POC of a conversational chatbot embedded in the Next.js + GraphQL stack of a major European hotel group (White Label mission, 8 brands). The assistant guides the user from hotel search to Adyen 3DS payment, reusing the existing GraphQL API end-to-end — no parallel backend, no logic duplication. Brand-gated, feature-toggle-gated, bilingual FR/EN, critical-path-safe: 14,366 tests still pass, including 457 dedicated to the chatbot, and zero regression on the other brands.

The problem

On a hotel booking site, the user juggles a search bar, side filters, hotel cards, a detail page, a room selector, a payment form. Every step is a chance to drop off. The classic funnel silently loses users between the listing page and the checkout.

Business stake: open a new conversational conversion channel without duplicating the API, without touching the booking critical path already battle-tested across 8 brands, and without contaminating brands that didn't opt into AI.

The solution

A React widget mounted as a sibling of the existing Next.js app, wired to three Express /api/chat* routes added to the same custom server — no microservice, no new stack. The LLM (Claude Sonnet 4.6) orchestrates 12 server tools that call the exact same GraphQL queries and mutations as the native site: searchResortsWithFilters, availabilityRooms, bookingProcess, cancelBooking, etc.

The assistant drives the user with SSE streaming, renders rich UI bubbles (hotel cards, filter chips, room selector, checkout recap, 3DS confirmation) and falls back to the native payment page when Adyen needs to run in the browser context. Brand-gated (LHG only via ALLOWED_BRANDS) + Azure App Config feature toggle: invisible to other brands, disable-able at runtime.

Shipped

  • Hotel search by destination + dates + occupants (FR/EN)
  • Dynamic filters: price, stars, amenities, brands
  • Room + rate selection with member-rate interception
  • Inline checkout (iframe) or native redirect depending on context
  • Adyen 3DS payment with in-conversation confirmation
  • Existing booking cancellation (public getBookingDetails query)
  • HttpOnly signed HMAC-SHA256 session (24h TTL, Azure App Config secret)
  • 15 typed UI bubbles + 12 server tools + 7 front-callable actions (LLM bypass)
  • 457 chatbot-dedicated Jest tests, 0 regression across 14,366 site tests
  • Migration to MCP (Model Context Protocol) — packaging the toolswip
  • Auth-aware user bookings (cross-domain JWT limitation to lift)wip

AI process

The chatbot is driven by Claude Sonnet 4.6 via the official Anthropic SDK. Orchestration loop capped at 8 iterations, MAX_INPUT_TOKENS = 100,000, chunk-by-chunk SSE streaming to the browser. Each tool is defined as a universal JSON Schema (mappable tomorrow to OpenAI tools, Mistral tools, Gemini function_declarations) — the architecture is deliberately decoupled from the SDK: swapping to a competing LLM costs ~150-200 LOC in a single orchestrator.ts file.

Delivery process: the POC was spec'd then shipped across 7 distinct implementation plans (writing-plans → executing-plans Superpowers), inter-task reviews, Linear tracking, technical audits filed under docs/superpowers/audits/. The next strategic step is to extract the 12 tools into a shared MCP server — which would make the same capabilities consumable by the mobile app, support tooling (Claude Desktop), or any third-party LLM client.

  • Claude Sonnet 4.6 (Anthropic)
  • Claude Code (Anthropic)
  • Superpowers (Jesse Vincent)
  • MCP (Model Context Protocol)

Further reading

// Discutons

Un projet React, une stack à durcir, une équipe à outiller avec l'IA ?