Skip to main content

AI_INTEGRATION — reservation-service

Sibling: DOMAIN_MODEL · APPLICATION_LOGIC · SECURITY_MODEL · EVENT_SCHEMAS

Strategic anchors: 02 §11 AI Architecture · 08 AI Architecture

reservation-service does not call any model directly. Every AI capability goes through the platform ai-orchestrator-service via the AIClient port declared in APPLICATION_LOGIC §1. The orchestrator routes to Vertex AI (cloud) or ONNX Runtime (Electron edge) per task, attaches policy guards, and returns an AIProvenance block we persist alongside any AI-derived field. Irreversible AI verdicts always go through a Human-in-the-Loop (HITL) gate.


1. AI capabilities used by this service

CapabilityUse case callerRoutingHITL?
Suspicious-booking anomaly detectionHoldReservationUseCase, WalkInBookingUseCaseVertex AI (cloud) — gradient-boosted classifier + LLM rationaleyes (auto-block requires staff confirmation)
Special-request parsing (multi-lingual free text → tags + structured)AddSpecialRequestUseCase, HoldReservationUseCaseVertex AI Gemini Flash for cloud; ONNX small-LM on desktop for offlineno (revisable label)
Guest-name transliteration (Pashto/Persian/Arabic/Cyrillic ↔ Latin)HoldReservationUseCase, WalkInBookingUseCaseVertex AI Translate / Gemini Flash for cloud; ONNX transliterator on desktopno (suggestion; staff can edit)
Upsell suggestions at booking confirmConfirmReservationUseCase (post-confirm async)Vertex AI rec-sys with property catalog + guest historyno (suggestions only; not auto-applied)

We do not use AI to authorize state transitions, compute money, or override policy. Every monetary value remains computed by pricing-service or billing-service.


2. Provenance — the AIProvenance envelope

Every AI-touched field is persisted with the canonical AIProvenance block (02 §11):

interface AIProvenance {
modelRef: string; // e.g. 'vertex-ai/gemini-1.5-flash@2026-04-01'
promptHash: string; // sha256 of the templated prompt
inputDigest: string; // sha256 of the input payload (post-redaction)
outputDigest: string; // sha256 of the model output
confidence: number; // 0..1
routedBy: 'cloud' | 'edge';
policyVersion: string; // ai-orchestrator policy bundle version
decidedAt: string; // RFC3339
reviewer?: { actorType: 'staff' | 'gm' | 'owner'; actorId: string; reviewedAt: string };
}

Stored on special_requests.ai_provenance, in the modification audit before/after snapshot for AI-derived guest-name transliterations, and in the upsell-suggestion event as metadata.aiProvenance.


3. Capability details

3.1 Suspicious-booking anomaly detection

Trigger: every HoldReservationUseCase and WalkInBookingUseCase invocation, after the domain validates the request but before persisting held state.

Inputs (post-redaction):

  • Reservation channel, property, stay window, party size
  • Guest signal hashes: email_hash, phone_hash, device_id (if available), prior-stays count, prior cancellation count
  • Behavioral: time-since-quote, payment method, IP-country vs guest-locale, booking velocity per device/IP in the last 1 h / 24 h
  • Property baseline: average booking pattern, current occupancy

Output:

interface AnomalyVerdict {
riskScore: number; // 0..1
band: 'low' | 'medium' | 'high';
signals: Array<{ name: string; weight: number }>;
rationale: string; // short LLM-generated explanation, locale-agnostic
recommendedAction: 'allow' | 'flag_for_review' | 'auto_block';
}

HITL flow:

  • band == 'low' → proceed silently.
  • band == 'medium' → reservation is held, but a RESERVATION_FLAGGED_FOR_REVIEW row is added to the staff inbox with the rationale; staff can clear or cancel.
  • band == 'high' and recommendedAction == 'auto_block' → reservation is not placed; instead a quote.created.v1 is held with requiresStaffApproval=true; the response to the booking BFF is a 202 with an opaque reviewToken; staff confirmation via backoffice resolves it within 15 minutes or it auto-rejects with MELMASTOON.RESERVATION.SUSPECTED_FRAUD_HOLD.

The verdict is persisted as a ReservationModification with type='manual_state_override' only when staff override; otherwise it lives in the audit trail of audit-service keyed by reservation id.

3.2 Special-request parsing

Trigger: any AddSpecialRequestUseCase or HoldReservationUseCase invocation that includes freeText without explicit tags.

Prompt template (cloud):

You are a hotel-booking assistant. Map the following guest request, written in {{locale}},
to one or more of these tags: {{tagTaxonomy | join(', ')}}.
Return JSON: { tags: string[], structured?: object }.
Be conservative; only emit tags you're confident about.

Guest text:
"""
{{freeText}}
"""

Edge fallback: an ONNX-quantized intent classifier ships with the desktop and runs without network. Its output is mapped to the same tag taxonomy with a confidence floor of 0.6; below that the desktop persists tags=['other'] and lets the cloud reprocess on next sync.

Storage: special_requests.tags, special_requests.ai_provenance, plus source='ai_parser'.

3.3 Guest-name transliteration

Trigger: HoldReservationUseCase / WalkInBookingUseCase when the guest's scriptHint != 'latin' and the staff did not supply latinTranslit manually.

Prompt template:

Transliterate the following name from {{sourceScript}} to Latin script for international booking systems.
Preserve the family/given distinction; do not translate or change order.
Return JSON: { given: string, family: string, confidence: number }.

Given: {{given}}
Family: {{family}}

Output: Guest.fullName.latinTranslit is filled in. Staff may correct it on check-in; the correction is captured as a guest_profile_update modification, and the AI provenance is preserved alongside the staff correction.

Edge fallback: a deterministic transliteration table (Pashto/Persian/Arabic/Cyrillic) ships with the desktop for offline mode; confidence is fixed at 0.75 for table hits.

3.4 Upsell suggestions

Trigger: asynchronously after ConfirmReservationUseCase succeeds. Fires off a ai-orchestrator-service request whose result is published as a melmastoon.notification.upsell_suggested.v1 event consumed by notification-service.

Inputs (post-redaction):

  • Reservation summary (channel, party size, stay length, room type, rate plan)
  • Guest preferences (sticky tags) and prior stays at this property/tenant
  • Property catalog of upsell items (room upgrades, breakfast packages, late check-out, airport pickup) with price, availability hint
  • Tenant-level upsell policy (max 3 suggestions; opt-out tenants receive an empty list)

Output: zero to three UpsellSuggestions with copy in the guest's locale. None are auto-applied; the guest accepts via the booking-confirmation surface.


4. Cost & budget controls

  • The AIClient port enforces per-tenant monthly budgets configured by ai-orchestrator-service. When a tenant exceeds budget, AIClient returns a typed AI_BUDGET_EXCEEDED error; our use cases degrade gracefully:
    • Anomaly detection → defaults to band='low' and logs a downgrade warning.
    • Special-request parsing → stores tags=['other'] and the raw text.
    • Transliteration → leaves latinTranslit null.
    • Upsell → no suggestion event emitted.
  • Every AI call carries a traceId so we can attribute spend to a reservation in the FinOps dashboard.

5. Privacy and redaction

  • Inputs sent to the AI orchestrator are redacted at the application layer before crossing the port: emails and phones become hashes; document numbers become last4 + issuer; full names are sent only when transliteration explicitly needs them.
  • ai-orchestrator-service adds another redaction pass and refuses any payload that fails its DLP scan.
  • For Iran-tenant residency, AI routing is restricted to in-region Vertex AI endpoints; fallback to ONNX-edge when no compliant endpoint is available.

6. Audit trail

Every AI-derived persisted value records:

  1. The AIProvenance block (§2) on the row that holds the value.
  2. An entry in the platform-level audit-service event stream with subjectKind='reservation' and subjectId='rsv_…'.
  3. A ReservationModification row only when the AI decision changed an aggregate field (e.g., transliteration filling latinTranslit); pure-suggestion outputs (upsell) do not create modifications until accepted.

7. Failure & degradation

FailureBehavior
ai-orchestrator-service unavailableAll capabilities degrade to no-op; reservation is still placed/created
Anomaly model returns timeoutDefault band low; flagged in observability as ai.fallback.anomaly
Edge ONNX model not loaded (first-launch desktop)Defer to cloud or skip (transliteration leaves field empty)
Output fails JSON-schema validationTreat as null output; log; do not block the use case

8. Cross-references