chore: target Java 17 and document usage plus roadmap
Lower the compiler baseline to 17, rename listDefinitions to queryDefinitions, and align README/usage/roadmap with planned vs out-of-scope work. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# Ordo
|
||||
|
||||
轻量审批流程引擎。宿主通过 `OrdoEngine` 注册流程定义、发起实例、审批/驳回/撤回,并查询任务、实例与审计历史。引擎不绑定业务表单,也不自带 REST;业务数据放在 `ProcessContext` 里。
|
||||
|
||||
要求 **Java 17+**。当前版本 `0.0.1-SNAPSHOT`。
|
||||
|
||||
## 模块
|
||||
|
||||
| 模块 | 作用 |
|
||||
|---|---|
|
||||
| `ordo-api` | 公共模型与 `OrdoEngine` 端口 |
|
||||
| `ordo-core` | 运行时(`DefaultOrdoEngine` / `InMemoryOrdoEngine`) |
|
||||
| `ordo-storage-jdbc` | JDBC 存储 + Flyway 迁移(V1–V5) |
|
||||
| `ordo-spring-boot-starter` | Spring Boot 自动装配(JDBC + Flyway) |
|
||||
| `ordo-example` | 内存引擎示例 |
|
||||
|
||||
存储实现面向 **PostgreSQL**(测试可用 H2 PostgreSQL 兼容模式)。Starter **不携带** JDBC 驱动,宿主自行加入 `postgresql` 或 `h2`。Spring Boot 4 还需额外引入 `spring-boot-starter-flyway`,否则迁移不会跑。
|
||||
|
||||
## 能力
|
||||
|
||||
- 线性或多步图:`StepTransition` + 可选 `RoutingCondition`
|
||||
- 会签/或签:`ApprovalPolicy.ALL` / `ANY`(多候选人)
|
||||
- ACTION 步骤:事务提交后调用宿主 `ActionHandler`
|
||||
- 发起人撤回:`WITHDRAWN`,待办任务 `SKIPPED`
|
||||
- 分页查询:任务 / 实例 / 流程定义
|
||||
- 审计时间线:`ProcessEvent` + `queryHistory`
|
||||
- 扩展点:`AssigneeResolver`、`RoutingCondition`、`ActionHandler`、`OrdoEventListener`
|
||||
|
||||
开发计划:任务转派、到期升级、`CANCELLED`、定义不可变多版本、MySQL 方言。多租户与官方 REST Starter **暂不在计划中**。见 [docs/roadmap.md](docs/roadmap.md)。
|
||||
|
||||
详细用法(定义 JSON、扩展点、异常、查询、ACTION/审计语义)见 **[docs/usage.md](docs/usage.md)**。对外行为变更时同步更新该文档。
|
||||
|
||||
## 内存快速开始
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.jetlumen</groupId>
|
||||
<artifactId>ordo-core</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
```java
|
||||
OrdoEngine ordo = new InMemoryOrdoEngine();
|
||||
ordo.register(ProcessDefinition.linear("leave-request", "Leave request", List.of(
|
||||
ApprovalStep.single("manager", "Manager approval", "maria"),
|
||||
ApprovalStep.single("hr", "HR approval", "henry")
|
||||
)));
|
||||
|
||||
ProcessInstance instance = ordo.start("leave-request", "alice",
|
||||
new ProcessContext(Map.of("requestId", "LEAVE-2026-001")));
|
||||
ApprovalTask manager = ordo.findPendingTasksByInstanceId(instance.id()).get(0);
|
||||
ordo.approve(manager.id(), "maria", "ok");
|
||||
```
|
||||
|
||||
完整示例:`ordo-example` 的 `LeaveRequestExample`。
|
||||
|
||||
## JSON 流程定义
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "leave-request-routed",
|
||||
"name": "Leave request",
|
||||
"steps": [
|
||||
{ "id": "notify-submitted", "name": "Notify submitted", "kind": "ACTION", "action": "leave-submitted-mail" },
|
||||
{ "id": "manager", "name": "Manager approval", "candidates": ["maria"], "policy": "ANY" },
|
||||
{ "id": "hr", "name": "HR approval", "candidates": ["henry"], "policy": "ANY" },
|
||||
{ "id": "notify-approved", "name": "Notify approved", "kind": "ACTION", "action": "leave-approved-mail" }
|
||||
],
|
||||
"transitions": [
|
||||
{ "from": "notify-submitted", "to": "manager" },
|
||||
{ "from": "manager", "to": "hr", "when": "days-gt-3", "priority": 0 },
|
||||
{ "from": "manager", "to": "notify-approved", "priority": 1 },
|
||||
{ "from": "hr", "to": "notify-approved" },
|
||||
{ "from": "notify-approved", "to": null }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `kind` 默认 `APPROVAL`;ACTION 用 `"action"` 作为 handler 查找键。
|
||||
- 转移按 `priority` 升序匹配;`when` 为空或条件命中则走该边;`to: null` 表示结束。
|
||||
- 代码侧可用 `ProcessDefinitionParser.fromJson(...)`。
|
||||
- `replace` 会整体替换同 id 定义;存在 `RUNNING` 实例时拒绝替换。
|
||||
|
||||
## Spring Boot
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.jetlumen</groupId>
|
||||
<artifactId>ordo-spring-boot-starter</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
需要 `DataSource`。存在 `DataSource` 且 `ordo.enabled` 不为 `false` 时装配 JDBC 引擎。
|
||||
|
||||
```yaml
|
||||
ordo:
|
||||
enabled: true
|
||||
definitions:
|
||||
location: classpath*:ordo/*.json # 默认值;启动时 replace 加载
|
||||
```
|
||||
|
||||
宿主提供 Bean 即可覆盖默认值:
|
||||
|
||||
| Bean | 默认 |
|
||||
|---|---|
|
||||
| `AssigneeResolver` | 候选人即办理人 |
|
||||
| `RoutingCondition` | 始终匹配 |
|
||||
| `ActionHandler` | 空操作 |
|
||||
| `OrdoEventListener` | 可注册多个,提交后按顺序调用 |
|
||||
|
||||
## 运行时约定
|
||||
|
||||
**办理人** 必须等于任务 `assignee`,否则 `UnauthorizedTaskOperationException`。
|
||||
**撤回** 仅发起人可操作,且实例须为 `RUNNING`。
|
||||
|
||||
实例状态:`RUNNING` / `APPROVED` / `REJECTED` / `WITHDRAWN`。
|
||||
任务状态:`PENDING` / `APPROVED` / `REJECTED` / `SKIPPED`。
|
||||
|
||||
**ACTION** 在审批事务提交之后执行。失败只记 `FAILED`、打日志、发 `ACTION_FAILED`,**不回滚已生效审批、不阻塞后续步骤**。可重试策略留给宿主(listener 或 `queryActionExecutions`)。
|
||||
|
||||
**历史** `queryHistory(instanceId, page)` 按时间升序。事件类型包括实例起止、任务创建/审批/跳过、ACTION 成败。
|
||||
`OrdoEventListener.onEvent` 在提交后派发;单个 listener 抛错不影响流程和其他 listener。
|
||||
|
||||
## 查询
|
||||
|
||||
```java
|
||||
ordo.queryTasks(TaskQuery.any().withAssignee("maria").withStatus(TaskStatus.PENDING),
|
||||
PageRequest.of(0, 20));
|
||||
ordo.queryInstances(InstanceQuery.any().withInitiator("alice"), PageRequest.of(0, 20));
|
||||
ordo.queryDefinitions(PageRequest.of(0, 20));
|
||||
ordo.queryHistory(instanceId, PageRequest.of(0, 50));
|
||||
ordo.queryActionExecutions(instanceId, PageRequest.of(0, 20));
|
||||
```
|
||||
|
||||
任务/实例列表默认最新优先;历史与 ACTION 执行记录按发生时间升序。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
mvn -pl ordo-api,ordo-core,ordo-storage-jdbc,ordo-spring-boot-autoconfigure,ordo-spring-boot-starter install
|
||||
```
|
||||
|
||||
先 `install` 再给外部工程(如宿主应用)引用。
|
||||
Reference in New Issue
Block a user