JJijibora
Docs & Product Guide
On this page (13 sections)

Integrations for Hotels — External System Mediation

Status: Integration Architecture
Sources: Integration Matrix & System Adapters Specification, Apache Camel Compliance Gateway (compliance-camel, :8181), Jijibora Architecture — Design Thesis in Developer Terms, AGENTS.md — Sovereign OS / Cosmic Circuit mandates 6 & 7


1. Canonical Mediation Model

External systems never connect directly to each other or mutate SurrealDB schema. All peers participate as mediated peers through Apache Camel (:8181) → NATS JetStream (:4222) → SurrealDB canonical primitives:

  • Hotel PMS / POS / OTAs
  • ERPNext (finance/procurement)
  • OpenMAINT / CMDBuild (CMMS)
  • Plane.io (task & project management)
  • Synapse / Matrix (staff chat)
  • Fleetbase (logistics & dispatch)
  • MinIO (object storage)
  • Gotenberg (PDF generation)
  • Keycloak (identity & access)
  • Solver Gateway :3070 (optimisation)

The State of Record (SoR) boundary is split: Sovereign OS owns operational state and approvals; each external peer owns its domain of fiscal/technical authority.


2. PMS (Property Management System) — System of Engagement

Role: Guest-facing reservations, check-in/check-out, room rates, channel manager (OTAs). The PMS remains the guest system of engagement; Sovereign OS is the headless state of record.

Mediation: PMS webhooks → Camel → cns://claim/type/hotel/reservation claim; room occupancy bound via truth_edge lease; folio lines mirrored to ERPNext for fiscal.

SoR boundary: PMS owns fiscal reservation details (rates, taxes, channel commissions); Sovereign owns operational state (occupancy, housekeeping, maintenance links, PoCE audit).

Conflict rule: Sovereign wins on approval/operational state; PMS wins on fiscal reservation details.


3. ERPNext — Finance & Procurement SoR

Endpoint: http://localhost:8000/api/resource (ERPNext API)

Role: Vendor ledger, fiscal Purchase Orders, stock intake, general ledger, accounts payable.

Adapter logic (H-4 / Process 1):

  1. Requisition claim transitions to APPROVED via PoCE session
  2. Camel executes idempotent POST /api/resource/Purchase Order with header X-Idempotency-Key: {requisition_id}
  3. ERPNext name (e.g., PO-2026-00412) recorded in integration_entity (system: "erpnext")
  4. Goods receipt matched to PO; three-way match before payment release

SoR boundary: Sovereign owns requisition assembly, budget threshold routing, dual-custody approvals, delivery compliance. ERPNext owns fiscal GL, tax computation (VAT/GST), accounts payable disbursement.

Conflict rule: Sovereign wins on approval state; ERPNext wins on fiscal ledger.

Fail closed: If ERPNext returns 5xx or times out, Camel aborts with HTTP 502 Bad Gateway. No synthetic PO IDs (dummy_po_123).


4. OpenMAINT / CMDBuild — Facilities & Maintenance (CMMS)

Endpoint: http://localhost:8080/rest/v3

Role: Physical asset catalog, room/asset bookings, maintenance work order generation.

Adapter logic (H-3 / Process 8):

  1. Fault incident claim → Camel → OpenMAINT openmaint.v1.cmd.workorder.create
  2. Returned WO id stored in integration_entity (system: "openmaint")
  3. OpenMAINT schedules technician; updates sync back over NATS JetStream to the task claim
  4. On completion, technician submits photo evidence; PoCE finalizes work order; payroll claim released

SoR boundary: Sovereign owns operational allocation, user reservation, purpose, sign-off. OpenMAINT owns asset spec, serial number, depreciated value, maintenance history.

Conflict rule: Sovereign wins on booking availability; OpenMAINT wins on asset spec.


5. Plane.io — Task & Project Management

Endpoint: http://localhost:8091/v1

Role: Engineering task boards, capex project tracking, renovation work tracking.

Adapter logic:

  1. Task claim (cns://workflow/task) → Camel → Plane issue creation
  2. Plane issue_id linked in integration_entity (system: "plane")
  3. Plane webhooks (issue.updated) → Camel → update task claim status in SurrealDB (bi-directional sync)

SoR boundary: Sovereign owns checklist completion, evidentiary hashes, sign-offs. Plane owns state column (Todo/Done), board lane, estimate points.

Conflict rule: Last-write-wins mediated by PoCE revision timestamps.


6. Synapse (Matrix) — Staff Communication

Endpoint: http://localhost:8008/_matrix/client/r0

Role: Real-time E2E-encrypted discussion rooms for staff collaboration (Process 5) and meeting notes (Process 4).

Adapter logic:

  1. Discussion thread claim created → Camel → POST /_matrix/client/r0/createRoom with alias #thread_{id}:hotel.local
  2. room_id stored in integration_entity (system: "synapse")
  3. Inbound Matrix events via Synapse Application Service → NATS subject ingress.v1.synapse.message
  4. Camel listens, mirrors verified messages as cns://collaboration/discussion_comment claims

SoR boundary: Synapse is real-time transport/ciphertext stream; Sovereign is authoritative record (governance promotion, consensus record, thread parent).


7. Fleetbase — Logistics & Dispatch

Endpoint: http://localhost:9002/v1

Role: Multi-stop vehicle dispatch, delivery routing (linens, F&B supplies, laundry, amenities).

Adapter logic: Confirmed purchase orders requiring transport dispatch a routing job to Fleetbase via Camel; returns delivery tracking waypoints.


8. MinIO — Object Storage (Evidence & Assets)

Endpoint: :9000 / :9001

Role: Storage of evidentiary attachments (housekeeping photos, maintenance photos, incident evidence), mood board assets, exported PDFs.

Integrity rule: All media in MinIO must have SHA-256 hash recorded in the Sovereign claim.evidence array or truth_node.attributes. No hash, no valid evidence.


9. Gotenberg — PDF Generation

Endpoint: :3094

Role: Immutable, signed PDF documents for folios, invoices, BEOs, mood board decks, insurance packets, compliance packets.

Routes: /services/playbook/moodboard/{board_id}/export-pdf; folio/invoice export on check-out.


10. Keycloak — Identity & Access

Endpoint: :8081

Role: Staff and guest identity realms, OIDC/OAuth2, BBS+ credential anchoring, APF role resolution.

Integration: X-Sovereign-DID-Proof header (Ed25519 or BBS+ signature) on cross-tenant API calls. APF (s230) resolve_effective(user, app, scope) answers "what may this principal do in this property scope".


11. Solver Gateway — Optimisation (:3070)

Endpoint: POST /v1/decisions (decision-request-v1 → decision-result-v1); NATS svc.solver.v1.<capability>.<version>.solve

Hotel use cases:

  • procurement.basket_split@1 (branch_and_bound 1.4.0): split F&B basket across vendors for least cost — proposes only; buyer disposes
  • Housekeeping route optimization: attendant route sequencing — proposes; housekeeping supervisor confirms
  • Maintenance crew routing: technician dispatch sequencing — proposes; engineering lead confirms

Fail closed: If solver-gateway is down/unreachable → 503 invent_refuse. Never return synthetic OPTIMAL, fill plans, or routes (D-09 — Optimization Capability (developer) failure catalog F1).


12. NATS JetStream — Event Spine

Endpoint: :4222

All hotel playbook events ride the criteria fan-out subjects (platform.criteria.v1.*). Subjects are declared in NATS KV lookups (canonical_subject, canonical_event_type, pipeline_id) — never invented in code. Outbox persistence via nats_outbox (s150) is the durable delivery anchor; the DB is SoR; NATS is the bus.


13. Error Handling & Fail-Closed Behavior

ScenarioResponse
ERPNext / OpenMAINT / Plane / PMS 5xx or timeoutHTTP 502 Bad Gateway, RFC 7807 problem details; queued in nats_outbox for exponential retry
Solver-gateway down503 invent_refuse; no synthetic OPTIMAL/plan
NATS / Kestra down502/503; no fill invented; LIVE flag unmet → refuse
External sync succeeds but DB write succeedsOutbox retry up to 5 times, then operator alert via Prometheus/Grafana
No matching lookup band / missing registrationRefuse; never fill gap with plausible substitute

Zero synthetic adapter payloads: No dummy coordinates, dummy suppliers, hardcoded org IDs, or Array.from() fake routes to satisfy a downstream contract. Return HTTP 400 if the caller's request does not match the real service contract (docs/schemas/decision-request-v1.json).