# Pipeline Network Diagram Editor — Implementation Plan A desktop diagram editor for designing pipeline networks (water, power, gas …), built with **Tauri v2 + React + TypeScript + Vite**, using **JointJS (`@joint/core`, MPL-2.0)** as the diagramming engine. ## Why JointJS Chosen over React Flow / Rete / GoJS after research because it uniquely covers every hard requirement out of the box: - Framework-agnostic SVG canvas with **custom SVG markup** for nodes → matches "nodes are defined by an SVG set with port configuration". - First-class **port model** with port groups + `validateConnection` → relation-based connectability & color schemes. - Built-in **grid/orthogonal routers** (`manhattan`, `orthogonal`) and a **`jumpover` connector with `jump: 'arc'`** → "lines drawn along rectangular grids" and the configurable "arc on intersection of lines". - Rich **link markup / markers** → arrow / circle / diamond heads and tails. - SVG attrs animation → animated flow direction & volume for the mock solver. ## Architecture ``` src/ model/ domain types: node & edge type defs, port types, relations, property schema, catalogues, color schemes (pure, unit-tested) canvas/ JointJS shapes, paper/graph setup, routing, selection, tools calc/ mock flow-distribution solver + animation controller (unit-tested) store/ Zustand app store (selection, config, catalogues, document) panels/ React UI: NodePalette, PropertiesPanel, Toolbar, ConfigPanel io/ serialize / deserialize document, export PNG/SVG, Tauri fs bridge test/ vitest setup src-tauri/ Tauri v2 Rust shell (file dialogs, fs plugin) ``` --- ## Milestones & Tasks ### M0 — Project setup & tooling - [x] Research & select diagramming library (JointJS) - [x] Scaffold Tauri v2 + Vite + React + TS - [x] Install deps (@joint/core, zustand, vitest, testing-library, tauri plugins) - [x] Configure Vite (port 1420) + Vitest (jsdom, coverage) - [x] Write this plan - [x] Base app shell layout (palette | canvas | properties, top toolbar) - [x] CI-style scripts: `test`, `test:run`, `lint`, `typecheck` ### M1 — Domain model (pure, tested) - [x] Port types & **relation registry** (which port types may connect) - [x] Connection validation function (`canConnect(source, target, relations)`) - [x] **Color schemes** mapping port/relation types → colors (multiple presets) - [x] Property schema types: `string,int,float,enum,catalogueItem,catalogueItems,color,list` - [x] Property groups (presentation / identity / physics) - [x] Catalogue model (named collections of catalogue items) - [x] Node type definitions with SVG markup + port layout (pump, valve, tank, junction, source, sink, …) - [x] Edge style definitions (line styles + source/target markers) - [x] Default property values & validation/coercion per type ### M2 — Canvas engine (JointJS) - [x] Paper + graph init, background grid, snap-to-grid - [x] Custom `PipelineNode` element (renders node-type SVG + ports) - [x] Custom `PipelineLink` with configurable markers & line styles - [x] Port rendering; show ports only when node focused/hovered - [x] Draw edge from a port; live validation highlight (valid/invalid) - [x] Grid routing (`manhattan`) + **config toggle for `jumpover` arc connector** - [x] Selection (single + multi via shift-click) & focus highlighting - [ ] Rubber-band marquee selection (not yet implemented) - [x] Element tools: remove, boundary; link tools: vertices, segments, arrowheads, remove (element resize is done via the Geometry properties, not a drag handle) ### M3 — Node palette - [x] Grouped, collapsible stencil of node types (vector previews) - [x] Search/filter - [x] Drag-and-drop node from palette to canvas (drop at cursor, snap) ### M4 — Properties panel - [x] Reflects current selection (node or edge), empty state otherwise - [x] Grouped property editors, one per property type - [x] Editors: string, int, float, enum(select), color(picker), catalogueItem(select), catalogueItems(multi), list(add/remove rows) - [x] Two-way binding: edits write back to element & update canvas presentation - [x] Geometry props (position/size/rotation) & title reflected live ### M5 — Editing UX (the "typical scenarios" often missed) - [x] Undo / redo (command stack) - [x] Delete, copy / cut / paste, duplicate - [x] Keyboard shortcuts (Del, Ctrl+Z/Y, Ctrl+C/V/X/D, Ctrl+A, Esc) - [x] Zoom (buttons + ctrl-wheel), pan (blank-area drag), fit-to-content, reset - [x] Grid + snap toggles, background config - [ ] Context menu on nodes/edges/canvas (not yet implemented — actions available via toolbar, tools & keyboard shortcuts) - [x] Rename via properties title (reflected live on canvas) ### M6 — Configuration - [x] Config panel: color scheme, arc-on-intersection, grid size/visibility, snap, router type, animation speed - [x] Persist config; live-apply to paper & links ### M7 — Persistence & export - [x] Serialize document (graph + metadata + config) to JSON - [x] Save / Open via Tauri dialog + fs (graceful fallback to browser download / file-picker) - [x] New document - [x] Export canvas to SVG and PNG ### M8 — Mock calculation & flow animation - [x] Build network graph from nodes/edges (respect port direction) - [x] Assign supplies/demands from node physics props - [x] **Flow-distribution solver** (conservation at junctions, proportional split) - [x] Map per-edge flow → direction (sign) + volume (magnitude) - [x] Animate flow along edges (dash animation; speed ∝ volume, dir ∝ sign) - [x] Color/width edges by flow volume; run / stop / reset controls - [x] Report unbalanced nodes / disconnected components ### M9 — Testing - [x] Unit: relation validation & color schemes - [x] Unit: property schema coercion/validation & catalogue resolution - [x] Unit: flow-distribution solver (linear, split, merge, cycle, unbalanced) - [x] Unit: document serialize/deserialize round-trip - [x] Component: palette renders/filters groups; config panel drives store; properties panel empty-state + grouped/typed fields for a selection - [x] Integration (graphOps): add node, connect w/ validation, build network, annotate flow, JSON round-trip (port medium survives) - [x] `npm run test:run` green (47 tests); typecheck & lint clean ### M10 — Polish & docs - [x] Seed demo network on first launch - [x] README with run/test instructions & feature list - [x] App icon / window sizing --- ## Definition of done - `npm run test:run` passes; `npm run typecheck` clean. - `npm run dev` shows a working editor: drag nodes, connect ports with validation, edit grouped properties, toggle arc routing & color schemes, run the mock solver with animated flow, save/open/export. - Conventional atomic commits throughout.