Files
wehub-resource-sync bf2343b7e4
Integration Tests - MySQL + Elasticsearch / Detect Changes (push) Has been cancelled
Integration Tests - MySQL + Elasticsearch / integration-tests-mysql-elasticsearch (push) Has been cancelled
Integration Tests - PostgreSQL + Elasticsearch + Redis / Detect Changes (push) Has been cancelled
Integration Tests - PostgreSQL + Elasticsearch + Redis / integration-tests-postgres-elasticsearch-redis (push) Has been cancelled
Integration Tests - PostgreSQL + OpenSearch / Detect Changes (push) Has been cancelled
Integration Tests - PostgreSQL + OpenSearch / integration-tests-postgres-opensearch (push) Has been cancelled
Java Checkstyle / java-checkstyle (push) Has been cancelled
Maven Collate Tests / maven-collate-ci (push) Has been cancelled
OpenMetadata Service Unit Tests / openmetadata-service-unit-tests-status (push) Has been cancelled
Publish Package to Maven Central Repository / publish-maven-packages (push) Has been cancelled
OpenMetadata Service Unit Tests / Detect Changes (push) Has been cancelled
OpenMetadata Service Unit Tests / openmetadata-service-unit-tests (push) Has been cancelled
OpenMetadata Service Unit Tests / k8s_operator-unit-tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:35:45 +08:00

91 lines
6.2 KiB
Markdown

## ADDED Requirements
### Requirement: openTask node — idempotent Thread/task creation
The `openTask` node (`nodeType: automatedTask`, `nodeSubType: openTask`) SHALL compile into a Flowable ServiceTask referencing `OpenTaskDelegate`. It SHALL idempotently create a Thread with configurable `TaskType` and `TaskStatus.Open`. If an open Thread/task already exists for the entity, it SHALL be a no-op.
#### Scenario: BPMN structure is compiled correctly
- **WHEN** a workflow definition contains an `openTask` node with config `{ "template": "incident", "taskType": "RequestTestCaseFailureResolution" }`
- **THEN** the compiled BPMN model SHALL contain a ServiceTask referencing `OpenTaskDelegate.class.getName()`
- **AND** the ServiceTask SHALL have Expression fields for `templateExpr`, `taskTypeExpr`, `responsiblesExpr`, and `inputNamespaceMapExpr`
#### Scenario: Node registered in NodeFactory
- **WHEN** `NodeFactory` receives a node definition with `nodeSubType: openTask`
- **THEN** it SHALL instantiate `OpenTask` and return a valid node
### Requirement: OpenTaskDelegate wires Flowable to business logic
The `OpenTaskDelegate` SHALL implement `JavaDelegate`, receive configuration via Flowable `Expression` fields, extract values from the `DelegateExecution`, instantiate `OpenTaskImpl`, call it, and set the `taskCreated` process variable from the result. On business logic failure, it SHALL throw a `BpmnError`.
#### Scenario: Delegate passes config to impl and sets process variable
- **WHEN** `OpenTaskDelegate.execute()` is called with a `DelegateExecution` containing valid expression values
- **THEN** it SHALL instantiate `OpenTaskImpl` with resolved config values, call the impl, and set `execution.setVariable("taskCreated", result)`
#### Scenario: Delegate wraps exceptions as BpmnError
- **WHEN** `OpenTaskImpl` throws an exception during execution
- **THEN** `OpenTaskDelegate` SHALL catch it and throw a `BpmnError`
### Requirement: OpenTaskImpl creates Thread/task (clean state)
When no open Thread/task exists for the entity, `OpenTaskImpl` SHALL create a Thread with the configured `TaskType` and `TaskStatus.Open` and return `taskCreated = true`. Auto-assignment is configurable via the optional `responsibles` config field. When `responsibles` is not set, the task SHALL be created unassigned (matching current behavior).
#### Scenario: First failure creates unassigned Thread (default, no responsibles config)
- **WHEN** no open Thread/task exists for the entity
- **AND** no `responsibles` config is set on the node
- **THEN** `OpenTaskImpl` SHALL create an unassigned Thread task and return `taskCreated = true`
#### Scenario: First failure auto-assigns to table owner (responsibles configured)
- **WHEN** no open Thread/task exists for the entity
- **AND** `responsibles.source` is `"tableOwner"`
- **THEN** `OpenTaskImpl` SHALL create a Thread task assigned to the table entity's owner and return `taskCreated = true`
#### Scenario: First failure auto-assigns to specific user (responsibles configured)
- **WHEN** no open Thread/task exists for the entity
- **AND** `responsibles.source` is `"specificUser"` with `responsibles.target` set to a user FQN
- **THEN** `OpenTaskImpl` SHALL create a Thread task assigned to the specified user and return `taskCreated = true`
### Requirement: OpenTaskImpl skips when Thread/task already exists
When an open Thread/task already exists for the entity, `OpenTaskImpl` SHALL skip creation and return `taskCreated = false`.
#### Scenario: Duplicate event is idempotently skipped
- **WHEN** an open Thread/task already exists for the entity (e.g., Ack or Assigned event after Thread was created on New)
- **THEN** `OpenTaskImpl` SHALL return `taskCreated = false`
- **AND** no duplicate Thread SHALL be created
### Requirement: OpenTaskImpl runs as governance-bot
All actions performed by `OpenTaskImpl` (Thread creation, task assignment) SHALL execute under the `governance-bot` identity.
#### Scenario: Governance-bot identity prevents event loops
- **WHEN** `OpenTaskImpl` creates a Thread task
- **THEN** the ChangeEvent generated by that creation SHALL have `governance-bot` as the updatedBy user
- **AND** `WorkflowEventConsumer` SHALL skip processing that event
### Requirement: closeTask node — Thread/task closure
The `closeTask` node (`nodeType: automatedTask`, `nodeSubType: closeTask`) SHALL compile into a Flowable ServiceTask referencing `CloseTaskDelegate`. It SHALL close an open Thread/task for the entity. If no open Thread/task exists, it SHALL be a no-op.
#### Scenario: BPMN structure is compiled correctly
- **WHEN** a workflow definition contains a `closeTask` node with config `{ "template": "incident", "taskType": "RequestTestCaseFailureResolution" }`
- **THEN** the compiled BPMN model SHALL contain a ServiceTask referencing `CloseTaskDelegate.class.getName()`
#### Scenario: Node registered in NodeFactory
- **WHEN** `NodeFactory` receives a node definition with `nodeSubType: closeTask`
- **THEN** it SHALL instantiate `CloseTask` and return a valid node
### Requirement: CloseTaskDelegate wires Flowable to business logic
The `CloseTaskDelegate` SHALL implement `JavaDelegate`, receive configuration via Flowable `Expression` fields, instantiate `CloseTaskImpl`, call it, and set the `taskClosed` process variable.
#### Scenario: Delegate passes config to impl and sets process variable
- **WHEN** `CloseTaskDelegate.execute()` is called with a `DelegateExecution`
- **THEN** it SHALL instantiate `CloseTaskImpl`, call the impl, and set `execution.setVariable("taskClosed", result)`
### Requirement: CloseTaskImpl closes Thread/task
When an open Thread/task exists for the entity, `CloseTaskImpl` SHALL close it and return `taskClosed = true`. When no open Thread/task exists, it SHALL return `taskClosed = false`.
#### Scenario: Open Thread/task is closed
- **WHEN** an open Thread/task exists for the entity
- **THEN** `CloseTaskImpl` SHALL close the Thread task and return `taskClosed = true`
#### Scenario: No-op when no open Thread/task exists
- **WHEN** no open Thread/task exists for the entity
- **THEN** `CloseTaskImpl` SHALL return `taskClosed = false` without error
### Requirement: CloseTaskImpl runs as governance-bot
All actions performed by `CloseTaskImpl` SHALL execute under the `governance-bot` identity.