Skip to content

Instantly share code, notes, and snippets.

@aelfannir
Created March 17, 2026 23:47
Show Gist options
  • Select an option

  • Save aelfannir/a5f25c5e134230a18650babcf13de712 to your computer and use it in GitHub Desktop.

Select an option

Save aelfannir/a5f25c5e134230a18650babcf13de712 to your computer and use it in GitHub Desktop.

Booking Recommendations — Required Changes

Context

We have a proper API contract for BookingRecommendation as a Hydra resource:

Currently the AI service streams recommendations directly to the frontend via SSE (POST /recommendations), returning flat objects like:

{"type": "restaurant", "identifier": "rt_f93b0058", "name": "Le Plaza", "thumbnail": null, "reason": "...", "price": null, "time": "19:00"}
{"type": "activity", "identifier": "snorkeling", "name": "Snorkeling Adventure", "thumbnail": null, "reason": "...", "price": null, "time": "10:00"}
{"type": "service", "identifier": "srv_0215f573", "name": "Airport Transfer", "thumbnail": null, "reason": "...", "price": 36000, "time": null}

Problems

  1. Frontend should not call the AI service directly — the frontend should fetch recommendations from the main API like any other resource (GET /booking-recommendations), not from the AI service.

  2. Fabricated identifiers — some identifiers like "snorkeling" and "sunset_cruise" are not real entities in the system. The AI must only recommend entities that actually exist.

  3. Flat structure doesn't match the API contract — the contract defines a proper Hydra resource (BookingRecommendation) with @id, @type, identifier, entityIdentifier, booking, reasoning, etc.

Expected Flow

┌──────────┐         POST /booking-recommendations          ┌──────────┐
│    AI    │ ─────────────────────────────────────────────► │   API    │
│ Service  │   { booking, items: [{ type, title,           │          │
│          │     description, reasoning, entityIdentifier }]│          │
└──────────┘                                                └────┬─────┘
                                                                 │
                                                                 │ persists
                                                                 ▼
┌──────────┐   GET /booking-recommendations?iri[booking]=   ┌──────────┐
│ Frontend │ ◄───────────────────────────────────────────── │    DB    │
│          │   standard Hydra collection response           │          │
└──────────┘                                                └──────────┘
  1. AI service generates recommendations and POSTs them to the API (POST /booking-recommendations) per the contract
  2. API persists them as BookingRecommendation entities
  3. Frontend fetches via standard GET /booking-recommendations?iri[booking]=/bookings/bk_xxx — no AI interaction

What needs to change

AI Service

  • Stop streaming recommendations directly to the frontend
  • Instead, POST /booking-recommendations to the main API with the payload defined in the contract:
{
  "booking": "/bookings/bk_xyz789",
  "items": [
    {
      "type": "restaurant",
      "title": "Le Plaza",
      "description": "Fine French dining with Mediterranean flavors",
      "reasoning": "You enjoyed a dinner at Le Plaza during a previous stay...",
      "entityIdentifier": "rt_f93b0058"
    },
    {
      "type": "activity",
      "title": "Snorkeling Adventure",
      "description": "Guided snorkeling exploring the coral reef",
      "reasoning": "Given your active history of booking activities...",
      "entityIdentifier": "act_a1b2c3d4"
    }
  ]
}
  • Only recommend entities that exist in the system — use real entityIdentifier values (e.g., rt_xxx, act_xxx, svc_xxx). Never fabricate identifiers like "snorkeling" or "sunset_cruise".

Frontend

  • Remove direct AI service call (NEXT_PUBLIC_AI_API_URL/recommendations)
  • Fetch from the main API: GET /booking-recommendations?iri[booking]=/bookings/bk_xxx
  • Consume as a standard Hydra collection (same pattern as every other entity)

API

  • Implement the BookingRecommendation resource as defined in the contract
  • POST replaces all existing recommendations for the booking+guest pair (C-001)
  • GET collection supports iri[booking] filter and X-Hotel header for admin access

Contract Reference

The full contract is already defined: booking-recommendations.yaml

Key schemas:

  • BookingRecommendation.info: @id, @type, identifier, type, title, description, entityIdentifier, booking
  • BookingRecommendation.read: info + reasoning, guest, createdAt
  • BookingRecommendationInput: booking (IRI) + items[] with type, title, description, reasoning, entityIdentifier
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment