-
Notifications
You must be signed in to change notification settings - Fork 0
Home
This repository is the operational example of how a domain- specific single-page application is built on top of NoETL.
It is not "the travel app" in isolation. It is the worked reference for how to assemble:
- a chat-style SPA that renders structured outputs as live UI widgets,
- a set of YAML playbooks that orchestrate multi-provider third-party APIs as MCP servers,
- a thin gateway integration that handles auth, SSE, and subscriptions without touching the database,
- a deployment that targets Cloudflare Pages for the SPA and Cloud Run / GKE for the gateway and NoETL.
Fork this repository and replace the travel-specific playbooks and widgets with your own domain's, and you have an end-to-end NoETL-driven SPA without writing a Python backend.
For the underlying NoETL platform:
- Application code:
noetl/noetl - Application wiki: noetl wiki
- Operational manifests + Helm chart:
noetl/ops - Operational wiki: ops wiki
- Foundational architecture principle: Ephemeral Blueprints + Compute-Data Boundary
A NoETL SPA assembles four layers:
| Layer | In this repo | Generalized role |
|---|---|---|
| SPA shell | src/components/shell/ |
The conversational surface (chat thread, input bar, side pane). Domain-neutral. |
| Widgets |
src/components/widgets/ + playbooks/widget-contract/*.schema.json
|
The visual vocabulary the SPA can render. Each widget is a JSON schema + a React component. |
| Playbooks |
playbooks/itinerary-planner.yaml, playbooks/agent/, playbooks/widget-contract/
|
The control flow. Decides what to do with user input, calls third-party APIs through MCP servers, emits widgets. |
| Gateway integration |
src/api/noetlClient.ts, gatewaySession.ts, calendarSubscription.ts
|
The narrow contract between the SPA and the NoETL gateway: GraphQL execute, SSE callbacks, playbook-mediated live calendar refresh. |
The SPA holds zero domain logic. Every business decision (which provider to call for hotels, how to format a price, what "next step" looks like in the conversation) lives in playbooks. Swap the playbooks; the SPA shell adapts automatically through the widget contract.
| Page | What |
|---|---|
| Architecture | How the four layers fit together. What the SPA owns, what the gateway owns, what the playbooks own. |
| Widget contract | The schema-driven contract between playbook outputs and SPA UI. How to add a widget. |
| Business data via playbooks | Pattern view: how every read and write of business data flows through a playbook step, never through the SPA or the gateway. Read + write + live-update paths end-to-end. |
| Playbook: itinerary-planner | Walkthrough of the orchestrator playbook. What each step does and why. |
| Playbook: calendar/list | Read playbook for the calendar widget. Called by the SPA on mount and on calendar.event.touched signals. |
| Page | What |
|---|---|
| Gateway integration | How the SPA talks to the gateway: GraphQL executePlaybook, SSE callbacks, subscription/event, playbook/state. |
| Auth and session | Auth0 hash-token flow + gateway session model. How to bring your own identity provider. |
| Page | What |
|---|---|
| Deployment | Vite build, Docker container, nginx config, Cloudflare Pages, Wrangler. |
| Adapting for your domain | Fork-and-replace checklist for non-travel industries. |
When in doubt, the source is in the repo:
- Widget schemas:
playbooks/widget-contract/*.schema.json - Generated TypeScript types:
src/contracts/widgets.ts - Orchestrator playbook:
playbooks/itinerary-planner.yaml - Architecture deep-dives:
docs/architecture/
- noetl wiki — NoETL Python API and DSL.
- ops wiki — Kubernetes manifests, Helm chart, GKE install.
- noetl/docs — design docs and feature specs.
Travel SPA
Architecture
- Architecture
- Widget contract
- Business data via playbooks
- Playbook: itinerary-planner
- Playbook: calendar/list
Integration
Operations
See also
- noetl wiki (app)
- ops wiki (deploy)
- Ephemeral Blueprints