docs(openspec): or-flow-object-write-node — flows can write objects (create/update/upsert/guarded delete)#2160
Conversation
…ects (create/update/upsert/guarded delete) The flow engine's nine built-in nodes transform items but none persists anything; 'no code, just flows' cannot materialise an object. Adds openregister.object-write: per-item create/update/upsert/delete with composite match keys, a per-step write cap (default 1000, fail-on-exceed), RBAC + attribution through the normal ObjectService path (fail-closed on ownerless runs — see #2158), and explicit item-level error semantics. Hardens the existing ObjectService::patchObject() (uuid-safe, RBAC forwarded, acting user, merge semantics) and widens deleteObject() for sessionless attribution. First consumers: hydra-cache maintenance + triage results (hydra-console chain); sibling change: openconnector-flow-nodes.
Quality Report — ConductionNL/openregister @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 174/174 | |||
| npm | ✅ | ✅ 555/555 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-07-27 09:27 UTC
Download the full PDF report from the workflow artifacts.
…elete objects Adds ObjectWriteNode, the built-in flow node that lets a graph flow write back to OpenRegister rather than only read and branch. Supports create, update, upsert and a guarded delete, resolving its target by uuid/slug/id scoped to a register+schema pair. Threads an explicit acting user through the write path so a sessionless caller (flow run, cron, import pipeline) is attributable rather than anonymous: - ObjectService::deleteObject() takes an optional $currentUser and evaluates the RBAC `delete` check against it instead of passing userId: null. - ObjectService::patchObject() is rewritten from a thin array_merge facade into the fleet's supported PATCH-semantic write path: RFC 7386-shaped recursive merge (absent key preserves, explicit null clears, lists replace wholesale), register/schema scoping, and no int cast on the identifier (the #1638 defect class). The merged result still goes through saveObject(), so validation, audit trail and events all apply. Registers the node on FlowNodeRegistrationListener alongside the other built-ins. Covered by ObjectWriteNodeTest and ObjectServicePatchObjectTest. Change: or-flow-object-write-node
Implementation landed (commit
|
What
OpenSpec change
or-flow-object-write-node— the flow engine's nine built-in nodes transform items but none can persist an object, so "no code, just flows" cannot materialise anything. Addsopenregister.object-write:confirmDelete: true, normal delete path with audit)ObjectService::patchObject()(uuid-safe, RBAC forwarded, acting user, PATCH merge semantics) and widensdeleteObject()for sessionless attributionFirst consumers: hydra-cache maintenance + triage results (hydra-console chain, hydra PR#384 / hermiq PR#52). Sibling: ConductionNL/openconnector spec/openconnector-flow-nodes.
16 requirements / 66 scenarios; validates
openspec validate --strict; tasks at the 20-checkbox cap. PO-reviewed 2026-07-27 (delete-in-v1, ObjectService PATCH, multi-match, write cap all explicit PO decisions).🤖 Generated with Claude Code