From 58026b248631998a04cfe70fd95e9bc8a3d14f6f Mon Sep 17 00:00:00 2001 From: canvas-bot Date: Mon, 15 Jun 2026 01:08:28 +0400 Subject: [PATCH] feat(canvas): strip demo data, EA2 is the only source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove src/data/synthetic.ts + its test (AR refund, HCM onboarding, GL close, Service Ops blueprints were hand-modelled fakes). - Remove DataMode='snapshot'; the store now boots straight into live EA2 with no fallback. EA2 errors surface as toasts, not fake data. - Topbar / Settings / CommandBar wording: 'SNAPSHOT'/'LIVE' becomes the unambiguous 'EA2' badge. No more user-facing mode switch. - package.json name flowmaster-mission-control-demo → flowmaster-canvas. - README rewritten — no longer calls the product a demo. - store.test: drop the two tests that relied on synthetic scenarios always being present; add one asserting an EA2-empty response leaves the store cleanly empty (no error-stuck state). All 23 vitest tests pass. tsc + vite build green. Bundle dropped from ~238 kB gz → ~234 kB gz. --- README.md | 173 ++++------------- package.json | 2 +- src/App.tsx | 18 +- src/components/CommandBar.tsx | 8 +- src/data/scenarios.ts | 15 +- src/data/synthetic.test.ts | 32 ---- src/data/synthetic.ts | 340 ---------------------------------- src/scenes/Settings.tsx | 19 +- src/state/store.test.ts | 38 +--- src/state/store.ts | 40 ++-- 10 files changed, 79 insertions(+), 606 deletions(-) delete mode 100644 src/data/synthetic.test.ts delete mode 100644 src/data/synthetic.ts diff --git a/README.md b/README.md index e152443..52660ab 100644 --- a/README.md +++ b/README.md @@ -1,168 +1,61 @@ -# FlowMaster — Mission Control +# FlowMaster — Canvas -**Live at https://canvas.flow-master.ai** · [source on Gitea](https://gitea.flow-master.ai/shad/flowmaster-mission-control-demo) +**Live at https://canvas.flow-master.ai** · operations cockpit for every process the company runs. -The proper FlowMaster frontend: an operations cockpit for every process the -company runs. Industrial-blueprint doctrine — paper canvas, navy frame, -amber accent, 1px hairlines, square edges, monospace operational density. +Canvas is the FlowMaster operator surface. Industrial-blueprint doctrine: +paper canvas, navy frame, amber accent, 1px hairlines, square edges, +monospace operational density. People, Finance, Procurement, and IT in +one frame. -## What this is (and isn't) +## What it is -**Is:** - -- A single-page React 19 app (Vite + ReactFlow + cmdk + framer-motion + zustand - + dagre). -- Polished command-center for any FlowMaster process: graph, queue, inspector, - tour, command palette, live-mode toggle, run history. -- Two data modes: - - **SNAPSHOT** (default): bundled `src/scenarios.json`, captured from - `demo.flow-master.ai`. Fast, offline, deterministic. - - **LIVE**: in-browser fetch from the same backend via the API client at - `src/lib/api.ts` (dev-login → bearer → `/api/ea2/work-items` → - `/api/ea2/process-definitions/{k}/graph` → `/api/runtime/transactions/{id}`). - Loading and error states are wired through `src/scenes/MissionControl.tsx`. - -**Isn't:** - -- Not a replacement for the existing demo at https://demo.flow-master.ai - (Next.js fm-shell). This is a separate command-center experience. -- Not multi-tenant. No auth UI, no tenancy switcher, no settings. -- Not wired to actually mutate state. Every action button (start runtime, - dispatch agent, approve, decline, confirm) is **preview-only** and fires a - toast naming the endpoint that would make it real. - -## Scenarios in the catalog - -| id | mode | source | -|-------------|-----------|-------------------------------------------------------------------| -| procurement | live | Purchase Requisition → PO (`pr_to_po_def` on demo.flow-master.ai) | -| extra-1 | live | Atlas F1 Fresh (procurement variant) | -| extra-2 | live | Atlas F1 Fresh (procurement variant) | -| ar | blueprint | AR · Customer Refund Approval | -| hcm | blueprint | HCM · New Hire Onboarding | -| gl | blueprint | GL · Period-End Close | -| service | blueprint | Service Ops · Customer Incident | - -**Live** = backed by a real EA2 process definition currently in the demo -backend, with real runtime transactions and a real work-item queue. - -**Blueprint** = hand-modelled in the same typed format. Identical UI surface; -the backend just doesn't have a runnable definition for it yet. Internal -metadata carries `isSynthetic: true` for provenance audits. - -## How honesty is enforced in this code - -This pass came out of an Oracle review that called out theatrical bits in the -prior version. Safeguards now in place: - -- **No invented numbers.** `src/components/Telemetry.tsx` derives every value - from the active scenarios (`SLA = 1 - errored / cases`, agent acceptance = - fraction of agent runs not in `proposed`). The throughput sparkline plots - the actual `running` rollup over time, not a sine wave. The "ui tick" dot - is labelled as a UI heartbeat and tooltip-named as such. -- **No fake buttons.** Every preview-only action fires a toast that names the - endpoint that would make it real, and carries a `preview` marker. -- **No misleading tour copy.** Blueprint tours frame the scenario as an - industry blueprint, not "we don't have this yet". -- **Mode is always visible.** Topbar has a `SNAPSHOT`/`LIVE` pill, last-fetch - age, and a refresh button when live. - -## Live-mode mechanics (the CORS gotcha) - -`demo.flow-master.ai` does not advertise CORS headers for arbitrary origins. -`src/lib/api.ts` therefore uses an **empty `baseUrl` everywhere** (both dev -and prod). All `/api/*` requests are same-origin from the browser's -perspective; whatever is serving the page is responsible for proxying them -to the backend. - -- **Dev** (`pnpm dev`): `vite.config.ts` proxies `/api/*` to - `${VITE_FM_BASE:-https://demo.flow-master.ai}`. -- **Prod** (Docker image): the bundled `nginx.conf` reverse-proxies `/api/*` - to `https://demo.flow-master.ai`. The image is intended to sit behind the - `canvas.flow-master.ai` ingress (see `FM06/flowmaster-ops` overlay). -- **Anywhere else**: set `VITE_FM_BASE=https://your-backend` at build time - and accept that browsers will reject the cross-origin call. Live mode then - fails gracefully — `setMode("live")` catches the error, raises an - `mc-banner-err` banner + error toast, and falls back to snapshot. +- React 19 single-page app (Vite + ReactFlow + cmdk + framer-motion + + zustand + dagre). +- Connected directly to EA2 in the browser via the API client at + `src/lib/api.ts`. There is one data source: live EA2. No bundled + snapshot, no synthetic blueprints. +- Scenes: Landing, Mission Control, Run History, Process Studio, Hubs, + Agent, Settings, Login, SSO callback. +- Agent scene has a chat surface with per-tenant local memory (`src/lib/agentMemory.ts`) + and three intents: navigate, retain a fact, start a process draft. +- Hubs surface departmental lenses (People, Finance, Procurement, IT). +- Three view-as personas (CEO, Head of People, Head of IT) re-sign in + under the persona's email so the operator UI reflects the seat. ## Run, test, build ```bash pnpm install -# refresh the bundled snapshot from demo.flow-master.ai -pnpm fetch:scenarios - # dev (with backend proxy for live mode) pnpm dev # → http://127.0.0.1:5173 # tests -pnpm test # vitest, 22 tests across api, live, - # synthetic, layout, store +pnpm test # vitest # build -pnpm build # tsc + vite, single chunk ~225 KB gz - -# end-to-end smoke + screenshots -pnpm qa:smoke # playwright headless, 28 assertions - -# DOM layout audit -pnpm qa:layout -``` - -## File map - -``` -src/ -├── data/ # ProcessScenario domain + snapshot + blueprint catalog -├── lib/ # API client + live-scenario builder (+ tests) -├── state/store.ts # zustand: scene, mode, scenario, tour, recents, toasts -├── graph/layout.ts # dagre LR auto-layout (+ tests) -├── components/ # ProcessGraph, Inspector, LeftRail, CommandBar, Tour, -│ # Telemetry, Toaster, icons -├── scenes/ # Landing, MissionControl, RunHistory -├── App.tsx # shell: topbar (mode pill / refresh / tour / ⌘K) -├── index.css # design system (~700 lines) -├── main.tsx -└── scenarios.json # cached snapshot of demo.flow-master.ai - -qa/ -├── smoke.mjs # Playwright e2e + 9 screenshots -└── layout_audit.mjs # programmatic clipping/overlap check - -vite.config.ts # /api → demo.flow-master.ai proxy for dev -fetch_scenarios.mjs # Node script to refresh src/scenarios.json +pnpm build # tsc + vite, single chunk ~234 KB gz ``` ## Deploy -Production deployment is tracked in -[FM06/flowmaster-ops PR #1164](https://gitea.flow-master.ai/FM06/flowmaster-ops/pulls/1164) -(merged), which added three resources to `manifests/overlays/demo/`: +Deployment is tracked in `FM06/flowmaster-ops`, overlay +`manifests/overlays/demo/`: -- `mc-deployment.yaml` — 2-replica nginx Deployment in the `demo` namespace +- `mc-deployment.yaml` — replicated nginx Deployment - `mc-service.yaml` — ClusterIP service on port 80 -- `mc-ingress.yaml` — Traefik ingress at `canvas.flow-master.ai` with cert-manager DNS-01 cert +- `mc-ingress.yaml` — Traefik ingress at `canvas.flow-master.ai` with + cert-manager DNS-01 cert -Cloudflare A record `canvas.flow-master.ai → 65.21.71.186` was added at the -same time. The cluster certifies with cert-manager (Let's Encrypt DNS-01) -and Traefik fronts the nginx pods. nginx reverse-proxies `/api/*` to -`https://demo.flow-master.ai` so the SPA is same-origin (no CORS). +nginx in the image reverse-proxies `/api/*` to `https://demo.flow-master.ai` +so the SPA is same-origin (no CORS). ```bash -pnpm build # builds dist/ -docker build -t gitea.flow-master.ai/shad/mission-control-demo:sha- . +pnpm build +docker buildx build --platform linux/amd64 \ + -f Dockerfile.runtime \ + -t gitea.flow-master.ai/shad/mission-control-demo:sha- \ + --load . docker push gitea.flow-master.ai/shad/mission-control-demo:sha- # Then bump the image pin in manifests/overlays/demo/mc-deployment.yaml. ``` - -## What's intentionally not here - -- Authentication UI (dev-login is used because this is a demo lane). -- Mutation endpoints (every action is preview-only and the toast names the - endpoint). -- Mobile layout (1440px-and-up demo surface). -- Route persistence / deep linking (scene + scenario live in memory). -- i18n (English only). - -Small, well-scoped follow-ups — not architectural changes. diff --git a/package.json b/package.json index de83eaf..301f92a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "flowmaster-mission-control-demo", + "name": "flowmaster-canvas", "private": true, "version": "1.0.0", "type": "module", diff --git a/src/App.tsx b/src/App.tsx index 5e1a1ee..d7b63e0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -118,21 +118,17 @@ export default function App() { + - {mode === "live" && ( - - )} + - {mode === "live" && ( - - )}