# one_bpmn **Repository Path**: fwr567/one_bpmn ## Basic Information - **Project Name**: one_bpmn - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: version-15 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-07-29 - **Last Updated**: 2026-08-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ![Coverage](https://img.shields.io/badge/coverage-30%25%2B-brightgreen) # ONE BPMN (Processa) A BPMN process **modeling and execution** platform for the Frappe Framework, powered by [bpmn-js](https://bpmn.io/toolkit/bpmn-js/) and [SpiffWorkflow](https://www.spiffworkflow.org/). It provides: - A Vue.js-based BPMN modeler at **`/processa`** — multiple diagrams per process, a tabbed editing interface, a formatting toolbar, and a SpiffWorkflow properties panel. - A **SpiffWorkflow execution engine** — compile/deploy process models, run process instances, assign and complete user tasks, and automate service tasks (email, Google Chat, push notification, field updates, workflow-state transitions). - **ProsAlly**, an embedded AI assistant that generates and edits diagrams from natural language. ## Installation ### Prerequisites - Frappe Bench setup - Node.js 20.x - Yarn package manager - **`onefm_mcp` app** — required for ProsAlly (provides the AI chat settings/config DocTypes and conversation storage). The editor and execution engine work without it; the AI assistant does not. ### Install the App ```bash # Get the app bench get-app one_bpmn # Install on your site bench --site your-site.local install-app one_bpmn # Run database migrations bench --site your-site.local migrate ``` ### Build Frontend Assets ```bash # Navigate to the Vue.js frontend directory cd apps/one_bpmn/spiff # Install dependencies yarn install # Build for production yarn build # Copy assets to sites/assets cd ../../../ bench build --app one_bpmn # Clear cache bench --site your-site.local clear-cache ``` ### Development Mode ```bash cd apps/one_bpmn/spiff yarn dev --host ``` Access at `http://localhost:8080/processa` (dev server). --- ## Project Structure A high-level overview (not every file is listed): ``` one_bpmn/ # Frappe app (repo root) ├── one_bpmn/ # Python package │ ├── api/ # Whitelisted backend endpoints (domain submodules) │ ├── one_bpmn/doctype/ # DocTypes + controllers (models, instances, tasks, logs) │ ├── agents/ # ProsAlly AI agent (google_adk) │ ├── utils/ # Backend helpers (e.g. chat persistence) │ ├── www/processa/ # Frappe www route that serves the SPA │ ├── public/processa/ # Built frontend assets (generated by the Vue build) │ ├── hooks.py # Frappe hooks (doc events + scheduler) │ └── tasks.py # Scheduled timer-event processing │ └── spiff/ # Vue.js frontend source └── src/ ├── views/ # Home, Editor, Instance list/detail ├── components/ # Editor, toolbar, ProsAlly panel, instance views, dialogs ├── bpmn|renderers|rules|moddle|resize/ # bpmn-js extension modules ├── composables|utils/ # Shared logic & helpers (incl. ProsAlly auto-layout) ├── linting/ # bpmnlint configuration └── router/ # Vue Router ``` --- ## Backend API Endpoints All endpoints are `@frappe.whitelist()` methods organized into domain submodules under `one_bpmn/api/`. Below is the endpoint surface by module. ### Process Model CRUD (`process_map_api`) | Method | Endpoint | Description | | ------ | -------- | ----------- | | POST | `save_process_model` | Save or update a BPMN diagram | | POST | `import_bpmn` | Import a .bpmn file (upsert by process_id) | | POST | `rename_process_model` | Rename a diagram (fast path) | | POST | `update_diagram_order` | Reorder diagrams within a process | | GET | `get_process_model` | Get a diagram by name | | GET | `list_process_models` | List all diagrams | | GET | `list_processes` | List Process records with diagram counts | | GET | `get_process_diagrams` | Get all diagrams for a process | | GET | `resolve_process_model_by_id` | Resolve process_id to model | | GET | `validate_bpmn_readiness` | Check deploy prerequisites | | DELETE | `delete_diagram` | Delete a diagram | ### Compilation & Deployment (`compilation`) | Endpoint | Description | | -------- | ----------- | | `compile_process_model` | Compile and deploy a process model | | `disable_process_model` | Disable a deployed model | ### Process Instance Lifecycle (`instance_api`) | Endpoint | Description | | -------- | ----------- | | `start_process` | Start a new process instance | | `complete_task` | Complete a user task and advance the engine | | `send_message` | Deliver a message to a running instance | | `list_process_instances` | List instances | | `get_instance_tasks` | Active tasks for an instance | | `get_instances_for_document` | Instances bound to a context document | | `get_active_bpmn_tasks` | Active tasks across instances | ### Other modules | Module | Responsibility | Representative endpoints | | ------ | -------------- | ------------------------ | | `server_script_api` | Server-script CRUD + Logix/ProsAlly chat | `create_server_script`, `update_server_script`, `toggle_server_script`, `process_logix_message`, `run_logix_test_case`, `prosally_chat` | | `canvas_comments` | Canvas comments & element assets | `get_canvas_comments`, `post_canvas_comment`, `update_comment_status`, `delete_canvas_element_assets` | | `editability` | Cross-site editor lock / edit checks | `check_and_update_editor_lock`, `check_process_editable`, `bulk_check_processes_editable` | | `version_history` | Diagram XML version history | `get_diagram_versions`, `get_diagram_version_xml` | | `script_version_history` | Server-script version history | `get_script_version_history`, `get_script_at_version`, `restore_script_version` | | `notification_api` | In-app notification creation | `create_notification` | | `utils` | Shared lookups (roles, fields, context docs) | `get_users_by_role`, `get_doctype_fields`, `get_context_doctypes`, `get_context_documents`, … | | `workflow_state` | Apply Frappe workflow-state transitions for BPMN service tasks (internal helper, not a public endpoint) | — | --- ## DocTypes ### BPMN Process Model Stores BPMN process definitions with SpiffWorkflow engine data. Named by the `title` field. **Not submittable.** | Field | Type | Description | | ----- | ---- | ----------- | | `title` | Data (required, unique) | Diagram title (used as the document name) | | `process_id` | Data (required) | BPMN process ID; always auto-extracted from the XML | | `process_name` | Link → Process | Parent process record | | `is_active` | Check | Whether the diagram is active (only one active per process) | | `description` | Small Text | Optional description | | `bpmn_xml` | Code (XML) | BPMN XML content | | `dmn_xml` | Code (XML) | DMN decision-table XML | | `serialized_spec` | JSON | SpiffWorkflow serialized process spec | | `subprocess_specs` | JSON | SpiffWorkflow subprocess specifications | | `round_robin_state` | JSON | Round-robin assignment rotation state | | `version` | Int (required) | Version number | | `target_doctypes` | Table | DocTypes this process applies to | | `trigger_type` / `trigger_doctype` / `trigger_event` | Select / Link / Select | Auto-trigger configuration | | `start_events` | Table | Start-event configuration | | `deployed_at` / `deployed_by` | Datetime / Link → User | Deployment metadata | | `pathfinder_log` | Link → Pathfinder Log | Cross-site editability reference | **Controller logic** (`bpmn_process_model.py`), all in `validate()`: - `validate_is_editable()` — blocks edits to locked/deployed models (cross-site Pathfinder Log check); trusted callers (import/compile) bypass it. - `extract_process_id_from_xml()` — re-extracts `process_id` from the BPMN XML, which is the source of truth. - `enforce_single_active()` — ensures only one active diagram per process. **Permissions**: System Manager (full), Process Owner (full), All (read-only). ### Data model (other DocTypes) Beyond the process model, the app defines DocTypes for **execution** — `BPMN Process Instance` (a running execution), `BPMN Active Task` (waiting user-task slots / assignments), `BPMN Activity Log` (audit trail) — plus **supporting configuration** DocTypes for processes, process-to-doctype targeting, roles, start events, settings, and canvas comments. Conversation storage and AI configuration DocTypes used by ProsAlly are provided by the separate `onefm_mcp` app. --- ## Frontend Routes | Route | View | Description | | ----- | ---- | ----------- | | `/processa` | Home | List of Process records with diagram counts | | `/processa/process/:process` | Editor | Editor for a process (shows all diagrams) | | `/processa/process/:process/diagram/:diagram` | Editor | Editor with a specific diagram active | | `/processa/instances` | Instance list | Running/finished process instances | | `/processa/instances/:instance` | Instance detail | Instance history, pending actions, diagram view | --- ## Features ### Home Page (`/processa`) - Table listing Process records with per-process diagram counts - Columns: Title, Process Owner, Business Analyst, Status, Last Modified, Created - Status derived from the most recent diagram's `is_active` flag - Click a row to open the process editor ### Editor Page (`/processa/process/:process`) - Full-featured BPMN modeler powered by **bpmn-js v18** - **Tabbed interface** at the bottom for switching between diagrams - **Left sidebar** for the diagram list within the process - **Properties panel** (toggleable) with BPMN and SpiffWorkflow properties - **Formatting toolbar**: font family and size, bold/italic/underline, and text/fill/stroke color pickers - Toolbar with Undo/Redo/Delete buttons - Keyboard shortcuts: `Ctrl+Z` (undo), `Ctrl+Y` / `Ctrl+Shift+Z` (redo), `Del` / `Backspace` (delete) - Zoom controls: zoom in/out, reset, fit-to-screen - Save persists to the Frappe database; HTML entity decoding for stored XML - bpmnlint integration with inline problem reporting ### Workflow Execution Compiled process models run as **process instances** via the SpiffWorkflow engine: - Start instances manually or via configured triggers/timers - **User-task assignment** modes: specific User, DocField lookup, Round Robin, and Load Balancing — with automatic redirect to a leave reliever - **Service-task automation**: send email, Google Chat message, push notification, update document fields, and apply Frappe workflow-state transitions - Frappe ToDo assignments, an activity log, and an instance UI under `/processa/instances` ### SpiffWorkflow Integration - SpiffWorkflow properties-panel extensions via forked [`bpmn-js-spiffworkflow`](https://github.com/ks093/bpmn-js-spiffworkflow) - **Script editor** for Script Tasks and Pre/Post scripts - **Markdown editor** for User Task / Manual Task instructions - **Call Activity editor** for Call Activity elements - Event-bus handlers for SpiffWorkflow data requests (service tasks, JSON schemas, DMN files, data stores, messages) - Loop data reference fix for multi-instance activities ### Custom Text Styling - Per-element text formatting (font family, size, weight, style, decoration) - A custom moddle extension persists styles as XML attributes (`custom:fontFamily`, `custom:fontSize`, …) - A custom renderer applies styles during diagram rendering ### i18n / Translation - Custom translate module for localizing the BPMN palette, context pad, and properties-panel labels ### Create Diagram Dialog - Creates a new diagram as a blank canvas (no pre-placed elements) - Process is set to `isExecutable="false"` by default - Links the diagram to its parent Process via `process_name` --- ## Key Dependencies | Package | Version | Purpose | | ------- | ------- | ------- | | `bpmn-js` | ^18.0.0 | BPMN modeler core | | `bpmn-js-properties-panel` | ^5.48.0 | Properties panel for BPMN elements | | `bpmn-js-spiffworkflow` | forked | SpiffWorkflow extensions (ESM build) | | `@bpmn-io/properties-panel` | ^3.36.0 | Base properties-panel framework | | `bpmnlint` / `bpmn-js-bpmnlint` | ^11.12.0 / ^0.24.0 | Diagram linting engine + editor integration | | `bpmn-auto-layout` | ^0.4.0 | Auto-layout for ProsAlly-generated diagrams | | `bpmn-js-differ` | ^3.2.0 | Diagram diffing (version compare) | | `bpmn-js-color-picker` | ^0.7.2 | Color-picker integration | | `bpmn-js-touch-interaction` | ^0.1.2 | Touch interaction (mobile) | | `diagram-js-minimap` | ^5.2.0 | Minimap module (currently disabled) | | `frappe-ui` | 0.1.192 | Frappe UI components (Tooltip, TextEditor, Dialog) | | `vue` | ^3.5.13 | Vue.js framework | | `vue-router` | ^4.5.0 | Client-side routing | | `dayjs` | ^1.11.7 | Date/time formatting | | `@iconify/vue` | ^5.0.0 | Icon component (Lucide icons) | | `tailwindcss` | ^3.4.17 | Utility-first CSS (dev) | --- ## Development ### After Making Changes ```bash cd apps/one_bpmn/spiff yarn build cd ../../../ bench build --app one_bpmn bench --site your-site.local clear-cache ``` ### Adding New Features - **API endpoint**: add to the appropriate submodule in `one_bpmn/api/` with `@frappe.whitelist()` (e.g. process CRUD in `process_map_api.py`, instance logic in `instance_api.py`). - **Vue component / view**: add under `spiff/src/components/` or `spiff/src/views/` and register routes in `router/index.js`. - **bpmn-js module**: add under `spiff/src/bpmn/`, `renderers/`, `rules/`, or `resize/` and register in `BpmnEditor.vue`'s `additionalModules`. - **Moddle extension**: add under `spiff/src/moddle/` and register in `BpmnEditor.vue`'s `moddleExtensions`. ### Runtime Hooks `one_bpmn/hooks.py` registers: - A universal `doc_events` BPMN trigger across all DocTypes (insert/update/submit/cancel/trash) so document lifecycle changes can drive workflows. - `scheduler_events` running every minute to process BPMN timer start events and timer catch events (`one_bpmn/tasks.py`). --- ## Troubleshooting ### White Screen on /processa 1. Run `bench build --app one_bpmn` 2. Clear cache: `bench --site your-site.local clear-cache` 3. Hard refresh the browser (Ctrl+Shift+R) ### API "Not Whitelisted" Error Restart the server after adding new API methods: ```bash bench restart ``` ### BPMN Modeler Not Loading Check the browser console for errors. Common fixes: - Ensure bpmn-js CSS is imported - Verify the container element has proper dimensions ### XML Import Fails The app automatically decodes HTML entities in stored XML. If issues persist, check the browser console for the decoded XML output. ### SpiffWorkflow Extensions Not Showing - Verify `bpmn-js-spiffworkflow` is installed: `ls node_modules/bpmn-js-spiffworkflow/` - Ensure the `spiffworkflow` module and `spiffModdleExtension` are registered in `BpmnEditor.vue` - Check the browser console for import errors --- ## ProsAlly — AI Process Modelling Assistant ProsAlly is an AI-powered chat assistant embedded in the BPMN editor that helps users create, overwrite, and modify process diagrams through natural-language prompts. ### Overview ProsAlly lives as a collapsible side panel (420 px wide on desktop, full-height bottom sheet on mobile) inside the BPMN editor. It runs a multi-step agent pipeline: ``` User prompt │ ▼ Intent Classifier │ ├─ GENERATE_NEW / OVERWRITE_EXISTING / MODIFY_EXISTING │ │ │ ▼ │ Confirmer ──► "I'll draw … Shall I proceed?" + [Yes / No, let me adjust] │ │ (confirmed) │ ▼ │ Generator / Modifier ──► BPMN 2.0 XML ──► canvas │ ├─ AMBIGUOUS / INCOMPLETE │ │ │ ▼ │ Clarifier ──► focused question + option buttons │ └─ IRRELEVANT ──► polite redirect ``` ### Intent Classification | Intent | Trigger | ProsAlly response | |---|---|---| | `GENERATE_NEW` | User wants a brand-new process on an empty canvas | Confirms, then generates BPMN | | `OVERWRITE_EXISTING` | User wants to replace the existing model entirely | Confirms, then regenerates | | `MODIFY_EXISTING` | User wants to add/remove/change a specific part | Confirms, then patches XML | | `AMBIGUOUS` | Multiple valid interpretations | Asks a clarifying question with options | | `INCOMPLETE` | Clear intent but missing details | Asks for the missing information | | `IRRELEVANT` | Nothing to do with process modelling | Redirects politely | ### Key Files | File | Purpose | |---|---| | `spiff/src/components/ProsAllyPanel.vue` | Chat UI — messages, option buttons, rich-text input | | `spiff/src/utils/bpmnLayout.js` | Auto-layout — positions generated BPMN elements left-to-right | | `spiff/src/linting/bpmnlintrc.js` | bpmnlint rule configuration (errors vs. warnings) | | `one_bpmn/agents/google_adk/prosally_agent/prosally_agent.py` | LLM agent — intent classification, clarification, generation, modification | | `one_bpmn/utils/chat_persistence.py` | Persists conversation history (`Chat Conversation` DocType) | ### Agent Pipeline (Python) The `ProsAllyAgent` class in `prosally_agent.py` runs fully async. Its stages (LLM roles) are: 1. **Intent classifier** — expects `{"intent": "...", "reason": "..."}`. 2. **Clarifier** — for `AMBIGUOUS`/`INCOMPLETE`, returns `{"question": "...", "options": [...]}`. 3. **Confirmer** — for actionable intents, returns `{"summary": "...", "question": "..."}`. 4. **Generator** — produces complete BPMN 2.0 XML from scratch. 5. **Modifier** — receives existing canvas XML + a patch instruction, returns updated XML. All LLM responses are parsed via `_parse_json_response()`, which strips markdown code fences before calling `json.loads`, with a fallback that extracts the first `{...}` block from the raw response. ### Auto-Layout (`bpmnLayout.js`) When ProsAlly generates or modifies a diagram, the raw XML uses placeholder coordinates. The layout function: - Parses the XML with `DOMParser` to extract element types, IDs, and sequence-flow connections (injecting ``/`` references as it goes). - Runs a BFS + join-relaxation algorithm to assign left-to-right column positions. - Builds the entire `` section as a **plain string** with hardcoded namespace prefixes — never via `XMLSerializer` — to prevent namespace-prefix mangling that breaks bpmn-moddle reference resolution. - Reads the actual `` value and uses it as the `BPMNPlane bpmnElement`, ensuring they always match. - Assigns element dimensions: events 36×36, gateways 50×50, tasks 100×80. - Adds `isMarkerVisible="true"` on exclusive-gateway shapes. - Routes edges with straight connectors (same row), Manhattan L-routing (different rows), and top-arc routing (back-edges / loop-backs). ### BPMN Generator Rules The generator LLM is instructed to produce BPMN 2.0 that satisfies the active bpmnlint rules: - Fixed `id="Process_1"` on `` and matching `bpmnElement="Process_1"` on `` — eliminates `no-bpmndi` errors from ID mismatch. - Exclusive gateways use a `default="Flow_..."` attribute and `` on every non-default outgoing flow — eliminates `conditional-flows` warnings. - Separate DI placeholder dimensions per element type, matching the layout algorithm's `DIMS` table. ### LLM Configuration ProsAlly's LLM provider, model, and API key are configured per-agent in the **Processa Agent LLM Config** child table of the **AI Chat Settings** DocType — both provided by the separate **`onefm_mcp`** app. The `agent_id` must match `"prosally_agent"`. Supported providers: `anthropic`, `gemini`, `openai`. ### Conversation Persistence Each chat session is stored as a `Chat Conversation` record with `agent_mode="ProsAlly"`. The last 30 messages are loaded as context on each turn. The `conversation_name` is returned from the backend and stored in the frontend session, enabling multi-turn coherent conversations. ### Active Linting Rules **Errors** | Rule | Description | |---|---| | `start-event-required` | Process must have a start event | | `end-event-required` | Process must have an end event | | `no-disconnected` | All elements must have at least one connection | | `single-blank-start-event` | Exactly one blank (untyped) start event | | `no-bpmndi` | Every semantic element must have DI (BPMNShape/BPMNEdge) | | `event-sub-process-typed-start-event` | Event sub-processes need a typed start event | | `sub-process-blank-start-event` | Sub-processes need a blank start event | **Warnings** | Rule | Description | |---|---| | `conditional-flows` | Gateway outgoing flows must have conditions or a default | | `no-overlapping-elements` | Shapes must not overlap | | `label-required` | Elements should have names | | `no-implicit-split` | Tasks should not have multiple outgoing flows | | `superfluous-gateway` | Gateways with only one path | | `no-gateway-join-fork` | Gateways should not both join and fork | | `event-based-gateway` | Event-based gateway usage checks | | `no-complex-gateway` / `no-inclusive-gateway` | Discourage complex/inclusive gateways | | `no-implicit-start` / `no-implicit-end` | No implicit start/end | | `fake-join` | Detect fake joins | | `no-duplicate-sequence-flows` | No duplicate sequence flows | | `ad-hoc-sub-process`, `conditional-event`, `link-event`, `single-event-definition`, `superfluous-termination` | Additional structural checks | ### Example Prompts **Generate new process:** > "Create a leave request approval process. It starts when an employee submits a leave request. A line manager reviews it and either approves or rejects it. If approved, HR updates the records and the process ends. If rejected, the employee is notified and the process ends." **Modify existing process (canvas must have a diagram loaded):** > "Add a 'Send Confirmation Email' task after the 'Approve Request' step." **Overwrite existing:** > "Scrap the current model and redraw the entire process from scratch based on the new SOP." --- ## License MIT ## Running Tests Run the full app test suite from bench: ```bash bench --site run-tests --app one_bpmn --failfast ``` ## Contributing 1. Branch from `staging` 2. Keep changes scoped to the work item 3. Open PRs back to `staging` 4. Prefer small, reviewable changes ## Architecture Overview - `one_bpmn/api/` — backend endpoints organized into domain-specific submodules (process CRUD, compilation, instance lifecycle, server scripts, comments, editability, version history, notifications, shared utils) - `one_bpmn/one_bpmn/doctype/` — BPMN DocTypes and server logic (process models, instances, active tasks, activity logs, configuration) - `one_bpmn/tasks.py` — scheduled timer-related processing - `one_bpmn/hooks.py` — universal document-event trigger and scheduler events - `spiff/` — the Vue.js frontend (bpmn-js editor + ProsAlly assistant) - ProsAlly's conversation/config DocTypes are provided by the separate `onefm_mcp` app