openova/package.json
e3mrah 2c6595a378
feat(openova-flow): npm workspaces + FlowPage canvas real-adapter rewire (Agent #5) (#1399)
Lands the OpenovaFlow Foundation end-to-end so the catalyst-ui FlowPage
consumes the new openova-flow-server's merged multi-region SSE stream
(`GET /api/v1/flows/{deploymentId}/stream`) and renders the per-region
adapter-flux emissions directly via @openova/flow-canvas. Closes the
revert from PR #1394 and unblocks the prov #34 multi-region 2-bubble
demo (fsn1 + hel1 each install bp-gateway-api → two bubbles).

# What ships

## A. npm workspaces at repo root

  • New `package.json` declares `openova-monorepo` private root with
    three workspaces: products/openova-flow/{core,canvas} +
    products/catalyst/bootstrap/ui.
  • Root `package-lock.json` resolves @openova/flow-* as workspace
    symlinks into the hoisted node_modules tree.
  • react / react-dom / d3-* are now hoisted into the monorepo's root
    node_modules, so flow-canvas's bare `import 'react'` resolves via
    standard upward-walking node_modules — no per-package sibling
    node_modules required (the root cause of PR #1389's build break).

## B. Catalyst-ui consumes @openova/flow-* via file: deps

  • catalyst-ui's `package.json` adds `@openova/flow-core` and
    `@openova/flow-canvas` as `file:../../../openova-flow/{core,canvas}`
    deps so `npm ci` from within catalyst-ui (today's CI path) keeps
    working without needing root-level `npm ci -ws`.
  • Vite `resolve.alias` + tsconfig `paths` bind `@openova/flow-core`
    and `@openova/flow-canvas` to the source-only `./src/index.ts`
    entry points. `dedupe: ['react', 'react-dom']` guards against
    double-instancing.
  • `tsconfig.app.json` `include` adds the two flow-package src trees
    so tsc covers them with catalyst-ui's strict settings (instead of
    each package's standalone `tsc -p tsconfig.json`, which lacks the
    React/d3 node_modules siblings).

## C. New SSE consumer + bridge

  • `src/lib/openflow-adapter-sse.ts` — `useFlowStream` React hook +
    pure `reduceFlowMessage` reducer. Consumes the contract verbatim
    (snapshot / upsert-flow / upsert-nodes / upsert-rels / delete-nodes
    / delete-rels). Owns the EventSource lifecycle, GET /snapshot
    pre-paint, capped exponential reconnect.
  • `src/lib/flow-bridge.ts` — catalyst-specific glue:
    `CATALYST_STATUS_PALETTE` (mirrors `--bubble-*` CSS tokens onto
    `StatusTone`), `flowStateToArrays` (Map→Array materialiser),
    `regionDescriptorsFromFlow` (derives FlowCanvas regions from live
    region tags + optional wizard-store augmentation), and
    `rollupFlowStatus` (provisioning-status rollup on the new
    contract).
  • NOT a Job-shape bridge — the legacy Job adapter from PR #1389
    is gone. catalyst-ui never goes through Catalyst's legacy Job model
    again; the SSE stream IS the source of truth.

## D. FlowPage.tsx rewired

  • Drives `FlowCanvas` from `@openova/flow-canvas` directly off the
    new hook.
  • Multi-region support comes for free: per-region adapter-flux tags
    every emitted FlowNode with `region: '<location-code>'`; the
    canvas's swimlane layout buckets by `region`. Single-region
    provisions render identically to before via a synthetic
    fallback descriptor.
  • Embedded mode preserved for JobDetail.

## E. Containerfile preserves CI build

  • COPY products/openova-flow/{core,canvas}/{package.json,src/}
    BEFORE `npm ci` so `file:` deps validate. Subsequent
    `COPY products/` layers the rest (CONTRACT.md etc.) in.

# Tests

  • 23 new tests, 0 regressions on adjacent areas:
    - `openflow-adapter-sse.test.ts` (6) — reducer covers all 6
      FlowMessage variants including delete-nodes' rel-prune cascade
      AND a multi-region merge case (fsn1 + hel1 both install
      bp-gateway-api).
    - `flow-bridge.test.ts` (10) — palette completeness, Map→Array
      ordering, region descriptor derivation/fallback, status rollup
      including group-exclusion and terminal-failure detection.
    - `FlowPage.test.tsx` (7) — empty-state mount, StatusStrip, no
      legacy mode toggle, embedded variant.
  • flow-core: 20/20 passing; flow-canvas: 9/9 passing.
  • Vitest full suite: 1130 pass / 87 fail (87 fails are pre-existing
    on main and unrelated — PinInput6, ProvisionPage, etc.). Baseline
    on main is 1052 pass / 88 fail / 27 failed files; this PR brings
    78 new passing tests and lowers failing files from 27 → 18.

# Constraints honoured (Rule 7)

  • NO `vite build` / `next build` / `npm run build` / `npx playwright
    test` / `npx playwright install`. Only `tsc --noEmit` + `vitest
    run` + `npm install --package-lock-only`.
  • NO `kubectl apply` / chart manifests touched (Rule 11).
  • NO hardcoded URLs / regions / k3s flags. Endpoint composed from
    `API_BASE`; regions derived from live FlowNode tags; deploymentId
    from `useParams` (Rule 18).
  • Two-repo discipline: openova-io/openova only (Rule 21).
  • Conventional commit + Claude co-author footer (Rule 20).
  • isolation:"worktree" — work landed in a dedicated worktree.

# Canonical-seam citations (ARCHITECT-FIRST)

  1. PR #1389's `flow-bridge.ts` — reference for the shape of a
     catalyst-ui→@openova/flow contract layer. NOT conflated: that
     bridge translated legacy Catalyst Jobs into FlowNodes; this one
     consumes the new SSE FlowMessage stream directly with no Job
     intermediary.
  2. `useDeploymentEvents.ts` (line 526+, `openStream` + `onerror`
     reconnect + capped retry) — canonical SSE consumer pattern in
     this codebase. `useFlowStream` mirrors it (capped exponential
     backoff, idempotent reducer over replayed buffered events).

# Definition of Done — post-merge verification plan

  1. CI green (catalyst-build builds the new Containerfile path).
  2. `curl -k -b /tmp/cz-cookie-prov27.txt
     'https://console.openova.io/sovereign/api/v1/flows/5a175e0a88c99cec/snapshot' | jq`
     → nodes[] contains BOTH `fsn1/bp-gateway-api` AND `hel1/bp-gateway-api`.
  3. Browser test: navigate to
     `https://console.openova.io/sovereign/provision/5a175e0a88c99cec/jobs/install-gateway-api`
     → expect TWO bubbles (one per region).
  4. If snapshot is empty, inspect emitter DaemonSets:
     `kubectl --context=omantel get pods -n openova-flow`.

Co-authored-by: hatiyildiz <269457768+hatiyildiz@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 16:59:07 +04:00

12 lines
335 B
JSON

{
"name": "openova-monorepo",
"private": true,
"version": "0.0.0",
"description": "OpenOva platform monorepo — npm workspaces root for the TypeScript surfaces (catalyst-ui + @openova/flow-*).",
"workspaces": [
"products/openova-flow/core",
"products/openova-flow/canvas",
"products/catalyst/bootstrap/ui"
]
}