Skip to content

Core UI (Cockpit)

The Core UI is Lukeflow's operator cockpit — a Camunda-Cockpit-style operations console for the Core Engine (the FluxNova / Camunda-7 process engine). It is where platform operators watch and act on the running engine: process definitions and instances, human tasks, incidents, jobs, DMN decisions, deployments, history, business calendars, external-task topics, runtime health, and user/group/tenant administration.

Partial · deployed

Repository: luke-core-ui · Type: Application (operator cockpit) · Stack: React 19 / Vite / TailAdmin

Overview

Lukeflow has two front ends, and they serve different people:

Consumer UICore UI (this page)
AudienceTenants — the businesses using LukeflowOperators — the team running the platform
Repositoryluke-consumer-uiluke-core-ui
AuthWorkOS session via Auth EngineHTTP Basic straight to the engine
Mental modelProduct surface (forms, email, signatures, workflows)Engine ops console (Cockpit + Admin + Tasklist)
TenancyScoped to the signed-in tenantPer-tenant, deliberately isolated (see below)

Where Consumer UI is the polished product tenants log into, the Core UI is the low-level cockpit that operators use to observe and intervene in the engine directly. It talks to the engine's REST API without going through the WorkOS auth gateway — operators authenticate with HTTP Basic credentials, which are injected into every request from a single client interceptor.

Tenant isolation is deliberate

The cockpit is tenant-aware and enforces isolation in the UI: there is no cross-tenant "list all tenants" surface for a scoped operator, and a tenantGuard utility keeps queries pinned to the active tenant. See Multi-Tenancy for the platform-wide model.

Architecture

The app is feature-sliced: src/features/<area>/ each own their pages/, components/, api/, and hooks, sitting on a shared kernel in src/shared/ (an axios api/ client, layout/ shell, ui/ primitives, bpmn/ viewer, stores/, hooks/, utils/). Routing lives in src/app/App.tsx, with lazy-loaded routes behind an AuthGuard; admin routes sit behind an extra RequireOperator gate.

16 feature areas, ~30 pages:

Feature areaPages
dashboardOperator landing dashboard
processesDefinition list, definition detail, instance detail
tasksTask list, task detail (human/Tasklist)
incidentsIncident list
jobsJob list (job executor)
historyHistoric activity / audit
deploymentsDeployment list, deployment detail
decisionsDMN decision list, decision detail
calendarsCalendar dashboard, calendar detail
external-tasksExternal tasks, topic registry, register topic, workflow builder
runtimeMonitor, logs, metrics, health dashboard
adminUsers, groups, tenancy dashboard (operator-gated)
tenancyTenancy dashboard
settingsSettings
setupFirst-run setup (pre-auth)
authLogin (pre-auth)

Diagram viewers. Process definitions and instances render live BPMN via bpmn-js (wrapped in src/shared/bpmn/); DMN decisions render and evaluate via dmn-js. Raw payloads, variables, and configuration are edited/inspected in the Monaco editor, and runtime metrics are charted with recharts. The external-task workflow builder uses a node graph (@xyflow/react).

Authentication. A single interceptor is the only place credentials live:

ts
// src/shared/api/client.ts
export function injectBasicAuth(config): void {
  // reads username/password from the auth store, then:
  config.headers.set('Authorization', `Basic ${btoa(`${username}:${password}`)}`);
}

There is no token exchange and no server session — the browser holds Basic credentials and sends them to the engine on every call. VITE_API_BASE_URL (baked in at build time) points the axios client at the deployed engine; left empty in local dev so requests stay same-origin and hit the Vite proxy.

Key features

  • Process operations — browse definitions, drill into a definition (versions, statistics) and into a single instance, with the live BPMN diagram and per-activity state.
  • Tasklist — list and act on human tasks, including an attachments tab.
  • Incident & job triage — inspect incidents (with stack-trace modals) and the job executor's queue.
  • Decisions — list DMN tables and open a decision detail that renders/evaluates the table via dmn-js.
  • Deployments & history — review what's deployed and query historic activity.
  • External tasks & topics — an external-task view plus a topic registry (register topics) and a visual workflow builder.
  • Runtime observability — a monitor plus dedicated health, logs, and metrics dashboards (recharts).
  • Admin — users, groups, and a tenancy dashboard, gated behind RequireOperator.
  • Command palette — a ⌘K Topbar palette navigates to any area the operator is allowed to reach (it mirrors the sidebar's visibility rules), alongside a user-settings dropdown. Both were added recently.
  • Shared UI kit — ~30 primitives in src/shared/ui/ (DataTable, DetailPanel, Drawer, Modal, StatusBadge, JsonViewer, CopyId, Pagination, ErrorBoundary, Skeleton, …) keep the pages consistent.

Technology

ConcernChoice
FrameworkReact 19 + TypeScript
Build / devVite 8 (@vitejs/plugin-react)
UI baseTailAdmin template on Tailwind CSS v4
Routingreact-router-dom v6 (lazy routes)
Server stateTanStack Query (@tanstack/react-query)
Client stateZustand
ValidationZod + react-hook-form (@hookform/resolvers)
TablesTanStack Table
HTTPaxios (single Basic-auth interceptor)
BPMN / DMNbpmn-js 18, dmn-js 17
Code editor@monaco-editor/react
Chartsrecharts 3
Node graph@xyflow/react
Errors / UX@sentry/react, sonner toasts
TestingVitest + Testing Library (unit); Playwright (e2e)
DeployRender static-site blueprint (render.yaml)

Local development

bash
npm install        # install dependencies
npm run dev        # Vite dev server (proxies /engine-rest, /api to the engine)
npm run build      # tsc -b && vite build  (what CI type-checks)
npm test           # Vitest unit tests
npm run test:e2e   # Playwright e2e (hermetic — specs stub all engine calls)
npm run lint       # ESLint (currently non-gating in CI)

Copy .env.example to .env.local. For local dev leave VITE_API_BASE_URL empty so calls stay same-origin through the Vite proxy; VITE_CAMUNDA_BASE_URL (default http://localhost:8080) sets the proxy target.

Build-time API URL

Vite inlines VITE_* variables at build time — they are not read at runtime. The deployed engine URL must be set before npm run build, and the engine's ALLOWED_ORIGINS must include this site's URL or browser calls are blocked by CORS.

Deployment

Deployed as a static site on Render via the render.yaml blueprint from the main branch: npm ci && npm run build, publishing ./dist behind a CDN with an SPA rewrite so deep links (e.g. /processes/:id) don't 404. There is no Node server at runtime — every call goes directly to the engine. The blueprint also ships security headers (X-Frame-Options: DENY, nosniff, HSTS, referrer policy) and a report-only CSP staged ahead of enforcement (it still needs the engine origin in connect-src and validation against Monaco's blob workers before it can block).

CI runs on GitHub Actions: a build-and-test job (Node 22 type-check + build + unit tests), a separate hermetic Playwright E2E job, plus CodeQL and a Semgrep/gitleaks/Trivy security scan.

Status & gaps

Deployed and functional, but a few things keep it at Partial rather than production-hardened:

  • TailAdmin re-skin is mid-polish. The shell, shared primitives, and the detail pages are largely migrated to the TailAdmin look, but roughly two dozen list and runtime feature files still carry inline var(--…) CSS styling from the earlier design — a cosmetic-consistency debt, not a functional one.
  • Thin test coverage. ~17 unit test files (mostly shared utils/primitives and a handful of feature APIs) and a single login e2e spec. The breadth of pages far outruns the tests.
  • Lint is non-gating. The CI lint step runs continue-on-error: true ("informational for now"), so lint regressions don't fail a PR.
  • CSP is report-only. Security headers are enforced, but the Content-Security-Policy is still Content-Security-Policy-Report-Only pending validation.

For how this app scores against the broader platform readiness checklist, see the Completeness Scorecard.

Lukeflow Manual · documentation snapshot July 2026