From 07f72f6c19b7a7c9a383a37ff8a9fb21d9347a22 Mon Sep 17 00:00:00 2001 From: zichun Date: Sat, 9 May 2026 19:39:36 +0800 Subject: [PATCH] docs: en wiki — Activiti is bypassed by xly's simple approval path --- en/docs/api-reference/internal.md | 2 ++ en/docs/reference/maintainer/activiti.md | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/en/docs/api-reference/internal.md b/en/docs/api-reference/internal.md index 9e288d7..36ae0e2 100644 --- a/en/docs/api-reference/internal.md +++ b/en/docs/api-reference/internal.md @@ -26,6 +26,8 @@ page is the catalog of HTTP entry points. | `/business/getSelectDataBysControlId/{sId}` | POST | Dropdown population for a single control, by control `sId`. | | `/business/getSelectLimit/{sId}` | POST | Paginated variant of the dropdown call. | | `/business/addSysLocking` | POST | Optimistic-lock acquisition when a user starts editing a document — inserts a row in the system lock table keyed by `(sFormGuid, sUserId)`. The SPA fires this when entering edit mode so concurrent editors get a conflict warning. Handler: `BusinessBaseController.java:400-407`. | +| `/business/doExamine` | POST | Simple "approve" — flips `bCheck = 1` on the named row via SQL. **Does NOT invoke Activiti**; this is xly's lightweight approval path used by every module that doesn't need multi-step workflow. Handler: `BusinessBaseController.java:384-391` → `BusinessBaseServiceImpl.doExamine` → `ExamineServiceImpl`. See [Two approval paths](../reference/maintainer/activiti.md#two-approval-paths) for when Activiti is used instead. | +| `/business/getProData` | POST | Generic stored-procedure invocation for a module — alternate path to `/procedureCall/doGenericProcedureCall`. Handler: `BusinessBaseController.java:350-358` → `BusinessBaseServiceImpl.getProData`. Used by FROUNT for module-level proc reads (the home dashboard `/getProData?sModelsId=...&sName=` pattern). | These endpoints are documented in detail by [Slice 1](../slices/01-hello-world.md) (`getModelBysId` + grid load + save) and diff --git a/en/docs/reference/maintainer/activiti.md b/en/docs/reference/maintainer/activiti.md index 1d3855a..9ac1343 100644 --- a/en/docs/reference/maintainer/activiti.md +++ b/en/docs/reference/maintainer/activiti.md @@ -1,15 +1,39 @@ # Activiti integration -> **State on this dev DB: engine wired, never used.** The Activiti -> engine is fully bootstrapped at runtime, the `act_*` schema is -> provisioned, the BPMN modeler UI is reachable — but **every -> workflow-related table is empty**. No BPMN deployed, no process -> instances ever started, no `gdsmodule` row currently has -> `bCheck = 1`. The plumbing is hot; nothing is flowing. +> **TL;DR — Activiti is wired, the engine runs, no traffic flows +> through it.** Engine bootstrapped, `act_*` schema provisioned at +> 6.0.0.4, BPMN modeler reachable. But every workflow table is 0 +> rows: no BPMN, no procdefs, no instances, no tasks. No +> `gdsmodule.bCheck=1`. No `gdsmoduleflow` link. **The approval +> button users see (`/business/doExamine`) bypasses Activiti +> entirely** and just UPDATEs `bCheck=1` via SQL — see +> [Two approval paths](#two-approval-paths) below. This page documents what's actually wired (concrete classes, URLs, engine state) and what would have to be true for it to do anything. +## Two approval paths + +xly ships two parallel approval mechanisms. They look similar from +the UI but go through completely different code: + +| Path | Triggered by | Backend | Activiti involvement | +|---|---|---|---| +| **Simple "approve" toggle** | The "审核" button on a single-row form | `POST /business/doExamine` → `BusinessBaseController.java:384-391` → `BusinessBaseServiceImpl.doExamine()` → `ExamineServiceImpl` (xlyBusinessService). The service runs an UPDATE that flips `bCheck = 1` (and writes audit fields). | **None.** `grep` confirms `ExamineServiceImpl` calls neither `runtimeService`, `taskService`, `processService`, nor any other Activiti API. The `bCheck` flag is xly's own boolean, owned by `BusinessBaseServiceImpl`. Used widely as a list filter (`SalesOrderServiceImpl` and friends do `WHERE bCheck = 1` on every "show approved-only" query). | +| **Multi-step BPMN workflow** | A user submits a row whose module has `bCheck = 1` AND a populated `gdsmoduleflow` row pointing at a deployed `act_re_procdef` | `ProcessServiceImpl.submitApply()` → `runtimeService.startProcessInstanceByKey(...)`. Subsequent approvers act through `CurrencyFlowController.complete(...)` → `taskService.complete()`. xly mirrors state in `biz_flow` + `biz_todo_item`. | **Full Activiti.** Requires a deployed BPMN (in `act_re_procdef`), an active process instance (in `act_ru_*`), and an assigned task (`act_ru_task`). | + +In this dev DB, **path 1 is the only path that runs**. Path 2 has zero +configuration anywhere — no BPMN deployed, no `gdsmoduleflow` row, no +`gdsmodule.bCheck=1` modules. So when a user clicks 审核 today, the +record gets approved via the simple-toggle path and Activiti is not +involved. + +Why the second path even exists: a customer that *does* need a real +multi-step approval (warehouse → finance → GM, with reassignment and +delegation) gets it by deploying a BPMN through the modeler and +linking modules via `gdsmoduleflow`. That activates path 2 for those +modules; path 1 still handles everything else. + ## Activiti is wired — engine ON Despite the dev DB being idle, the engine boots with `xlyEntry`: -- libgit2 0.22.2