camunda / camunda/api-test-generator
design: EntityLifecycle for ProcessInstance — two revokers (delete vs cancel) + POST-style revoker method
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 3
- Avg merge
- 13h 41m
- Merged PRs (30d)
- 23
Description
Context
Spinning out of the scope discussion on #280 (EntityLifecycle scenario template). ProcessInstance is the missing 11th OCA entity kind by every shape criterion except the revoker, where it has two open questions that warrant a dedicated design conversation before being folded into the standard EntityLifecycle template.
Why ProcessInstance doesn't fit the #280 template as-drawn
Standard EntityLifecycle (#280) assumes:
shape: "entity"
establishedBy: POST → 201
observableVia: GET → 200
revokedBy: DELETE → 204
ProcessInstance breaks two of those:
createProcessInstance: POST /process-instances → 201 ✅
getProcessInstance: GET /process-instances/{processInstanceKey} → 200 ✅
deleteProcessInstance: POST /process-instances/{processInstanceKey}/deletion ❌ POST, not DELETE
cancelProcessInstance: POST /process-instances/{processInstanceKey}/cancellation ❌ POST, not DELETE
So:
- Revoker method isn't DELETE — both candidate revokers are
POST /…/deletionandPOST /…/cancellation(RPC-style action endpoints, not CRUD-style DELETE). - Two distinct revokers with different semantics —
cancelProcessInstanceis the engine-level termination (stops execution, leaves audit trail);deleteProcessInstanceis the audit-cleanup operation (removes the historical record). They're not interchangeable; a lifecycle test needs to decide which one to exercise (or test both).
Open design questions
-
Which revoker is "the" revoker for the lifecycle suite?
cancelProcessInstance— closer to "delete" from a user's mental model (the instance stops doing work); but the instance is still queryable as a completed/terminated record afterward, so observe-absent viagetProcessInstancewould return 200 withstate: "CANCELED", not 404.deleteProcessInstance— gives the 404 we want for observe-absent, but is a privileged audit-cleanup operation that's not the normal end-of-life for an instance.- Both — emit two lifecycle suites (cancel-then-delete chain, or two independent suites).
-
How should the schema constraint on
revokedByaccommodate POST-style revokers?- Relax the L3 invariant from "method = DELETE" to "method ∈ {DELETE, POST}" with a heuristic (path ending in
/deletion,/cancellation,/resolution)? - Add an explicit
revokeShape: "delete" | "action"field onEntityKind? - Carve out a new EntityKind shape (e.g.
shape: "engine-entity") with looser invariants?
- Relax the L3 invariant from "method = DELETE" to "method ∈ {DELETE, POST}" with a heuristic (path ending in
-
Observe-absent semantics for
cancelare not 404. They're "GET returns 200 withstate: CANCELED". This is the same shape as the existingruntime-states.jsonwitness predicate (e.g.ProcessInstanceCompleted.witnessalready encodes a JSONPath equals-check onstate). Should the EntityLifecycle template grow awitness-shape observe step alongside the 404 one?
Related entities with the same shape
If the answer to #3 is "yes, add a witness-shape observe", several engine-managed concepts likely fit the same generalised template:
- ProcessInstanceIncident —
resolveProcessInstanceIncidents(bulk POST); observe-absent is "GET incident returns 200 withstate: RESOLVED" or "search returns empty for this incidentKey". - Job — completion/failure via
completeJob/failJob/throwJobError; observe-final-state via state field. - UserTask —
assignUserTask/unassignUserTask/completeUserTask; observe via state field.
These are out of scope for #280 (CRUD entities) and out of scope for this issue (ProcessInstance specifically), but the design choice on #3 above sets the direction for how they'd eventually be modelled.
Acceptance criteria (to be confirmed once design questions resolved)
- Design decision recorded on questions 1–3 above.
- If schema relaxation:
entityKindsSchema.tsupdated and L3 invariants extended. - If new shape: new shape added with its own all-or-nothing rule.
- ProcessInstance entry added to
configs/camunda-oca/ontology/entity-kinds.json. - Lifecycle suite(s) emitted for ProcessInstance.
- L3 invariant updated to include ProcessInstance in the expected suite enumeration.
Out of scope
- All other engine-managed concepts (Job, UserTask, Incident) — once a pattern is settled here, those follow as separate issues.
- The 10 standard CRUD entities are covered by #280.
Parent / related: #279, #280
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the design discussion in #280 and the schema entry point in entityKindsSchema.ts, then compare the existing configs/camunda-oca/ontology/entity-kinds.json entries. Trace how L3 invariants and lifecycle suites are emitted; done means recording decisions for questions 1–3 and satisfying the corresponding schema, ProcessInstance, suite, and invariant acceptance criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, typescript
- Domain
- api, testing, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100