Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Feature ID: PF-73
Status: ✅ Complete (Phase 1 + Phase 2 + Phase 3) — 2026-03-14
Spec Reference: PF-73-workflow-builder-swim-lane-visualization.md
Last Updated: 2026-03-14
Last Verified: 2026-03-14

Overview

PF-73 extends the Platform Workflow layer (@/platform/workflow) with swim lane diagram capabilities: horizontal/vertical lanes, node-in-lane placement, manual builder UI, policy/procedure-based generation (GR-01, GR-11), and AI-assisted generation (PF-27). Diagrams are stored in pf_swim_lane_diagrams and consumed by GR, FW, HR, and other cores for process documentation—visualization only, not workflow execution (FW-06 remains the execution engine).

Quick Reference

ItemValue
Platform layer@/platform/workflow (extended by PF-73)
Core tablepf_swim_lane_diagrams
Key dependenciesPF-01, PF-02, PF-11, PF-27, PF-30, GR-01, GR-11, FW-06
Consumed byGR (procedures/policies), FW (documentation views), HR (onboarding/process docs)
Permissionspf.swim-lane-diagrams.view, .create, .update, .delete, .export
SECURITY DEFINERpf_has_org_access(organization_id, auth.uid()) (or equivalent)

Integration Points (from Spec)

ConsumerUsagePhase Available
GRGenerate diagrams from GR-11 procedures and GR-01 policies; embed in procedure/policy docsPhase 3
FWUse swim lane component for workflow documentation views (optional)Phase 4+
HRUse swim lane component for onboarding/process documentation (optional)Phase 4+
PlatformManual builder UI under platform routes; export to PF-11 documentsPhase 2–4

API / Data Contracts

Swim Lane Canvas & Types

Import: import { SwimLaneCanvas, useSwimLaneDiagram, useSwimLaneDiagramList, useSwimLaneDiagramMutation } from '@/platform/workflow'; Types (PF-73):
TypeDescription
LaneDefinition{ id: string; label: string; role?: string; department?: string; orientation: 'horizontal' | 'vertical'; order: number; color?: string }
SwimLaneDiagramState{ lanes: LaneDefinition[]; nodes: Node[]; edges: Edge[]; viewport?: { x: number; y: number; zoom: number } }
Node parentNodeIdWhen set, node is placed in the lane with that id; drag-between-lane updates this.
Hooks:
HookPurpose
useSwimLaneDiagramList(organizationId, filters?)List diagrams; .eq('organization_id', organizationId); staleTime/gcTime 5min/10min
useSwimLaneDiagram(id)Single diagram; require orgId in query key
useSwimLaneDiagramMutation()Insert/update/delete with .eq('organization_id', orgId) on all mutations
Component:
  • SwimLaneCanvas — Lane-aware canvas (group nodes or custom panels); lane CRUD, node palette, drag-between-lane, edges. Used by builder page and read-only view.

Generation (Phase 3)

  • From procedure (GR-11): Pass procedure id; platform reads gr_procedures and steps via allowed integration; returns diagram state with lanes derived from responsible_role. No direct core-to-core import; use platform or documented API.
  • From policy (GR-01) / AI: Pass policy id or pasted text; PHI validation required before calling PF-27/PF-62; AI returns suggested lanes/steps; user confirms; diagram created with source_type='policy' or 'procedure'.

Export

  • PDF/PNG: Use existing platform export utilities (e.g. @/platform/forms or document export). Permission: pf.swim-lane-diagrams.export.
  • Save as document: Optional upload to PF-11 with title/folder; org-scoped.

RLS Architecture

TableScopeSELECTINSERTUPDATEDELETE
pf_swim_lane_diagramsorganization_idSECURITY DEFINER helperWITH CHECK (org)USING + WITH CHECK (org unchanged)SECURITY DEFINER helper
UPDATE policy: MUST include WITH CHECK so organization_id cannot be changed (constitution §5.2.4). No RLS policy may query RLS-protected tables directly; use SECURITY DEFINER helpers only (§5.7).

Realtime (Phase 2.2) — Channel and auth

Phase 2.2 collaborative realtime is planned (not yet implemented). The channel contract, presence/subscribe/broadcast semantics, and multi-tenant verification rules are documented in EVENT_CONTRACTS.md#pf-73-realtime-channel. When implemented, Supabase Realtime (broadcast/presence) MUST use the org-scoped channel and authorization-at-subscription-time rules defined there. See also PF-73 Phase 2 Expansion Integration Points for the full contract.

Security and Tenant Isolation

  • All access filtered by organization_id; RLS enforces org isolation.
  • Mutations MUST include .eq('organization_id', orgId) (defense-in-depth).
  • No PHI in diagram content or AI prompts; policy text sent to PF-27/PF-62 must pass pre-flight PHI validation.
  • Permission keys: pf.swim-lane-diagrams.view, .create, .update, .delete, .export. All UI gated by these keys.

Settings

SettingTableDefaultDescription
swim_lane_builder_enabledpf_module_settingstrueEnable/disable swim lane builder for the organization
Migration must include CHECK (if applicable) and COMMENT ON COLUMN per constitution §5.2.5.

Phase 2 API Contracts (added 2026-03-14)

Version History (Phase 2.1)

Import: import { useSwimLaneDiagramVersions, useCreateDiagramVersion } from '@/platform/workflow';
HookPurpose
useSwimLaneDiagramVersions(orgId, diagramId)List version snapshots DESC; staleTime/gcTime 5min/10min
useCreateDiagramVersion()Insert new version snapshot with auto-increment
Component: DiagramVersionHistory — Sheet-based panel with version list, read-only preview, and “Restore” action.

Real-Time Collaboration (Phase 2.2)

Import: import { useDiagramPresence, useDiagramBroadcast } from '@/platform/workflow';
HookPurpose
useDiagramPresence(orgId, diagramId)Avatar stack of active users via useRealtimePresence
useDiagramBroadcast(orgId, diagramId)Broadcast/receive diagram_updated events
Channel: org:{orgId}:diagram:{diagramId} — org-scoped per PF-66 standards.

BPMN Import (Phase 2.3)

Import: import { parseBpmnToSwimLane } from '@/platform/workflow';
UtilityPurpose
parseBpmnToSwimLane(xml: string)BPMN 2.0 XML → SwimLaneDiagramState; uses bpmn-moddle
Component: ImportBpmnDialog — File picker + preview + import action.

Templates Marketplace (Phase 2.4)

Import: import { useSwimLaneTemplates } from '@/platform/workflow';
HookPurpose
useSwimLaneTemplates(orgId)List platform + org-scoped templates
Components: SwimLaneTemplateList, SwimLaneTemplatesPage.
Route: /platform/workflows/diagrams/templates (lazy-loaded, permission-gated).

Phase 3 API — ✅ Complete (2026-03-14)

Phase 3 expansion (PF-73-PHASE-3-EXPANSION.md) delivers:

Hooks

HookImportPurpose
useDiagramUndoRedo@/platform/workflow50-step in-memory undo/redo stack; 400ms debounce
useWorkflowKeyboardShortcuts@/platform/workflowCtrl+Z/Y, Ctrl+C/V, Delete, zoom, fit view; disabled in inputs

Utilities

UtilityImportPurpose
validateDiagram(nodes, edges)@/platform/workflowStructural validation: start/end events, orphan nodes, decision out-degree. Returns { errors, warnings }
serializeSwimLaneToBpmn(state)@/platform/workflowExport diagram as BPMN 2.0 XML; inverse of parseBpmnToSwimLane
getLayoutedDiagram(nodes, edges, direction)@/platform/workflowDagre-based auto-layout (TB/LR); preserves lane/group positions

Components

ComponentPurpose
ShortcutHelpPanelDialog listing all keyboard shortcuts; opened via ? or K
DiagramValidationPanelSheet showing errors/warnings with “Focus” node navigation

BPMN Export Limitations

  • Node positions are NOT preserved (no BPMNDI)
  • Lane colors, orientation, and order are lost
  • Node type information is lost on round-trip (parser assigns type: 'default')
  • Only start, end, task, decision types map to BPMN elements; others become bpmn:task

Accessibility

  • All node types have role="img" and aria-label
  • NodePalette uses role="toolbar" with aria-label
  • Canvas wrapped in role="region" with aria-label
  • Keyboard shortcuts skip inputs/textareas/selects
  • Visible focus rings on all interactive elements

Dependency

  • @dagrejs/dagre ^1.1.4 — auto-layout algorithm

Testing

  • Unit tests: tests/unit/platform/workflow/ — diagramValidation (8), serializeSwimLaneToBpmn (5), dagreLayout (5), useDiagramUndoRedo (6)
  • Integration tests: tests/integration/platform/workflow/swim-lane-phase3.test.ts — validate→export→reimport, layout→validate (4)