Skip to content

fix: include node type in plugin condition/action payload - #345

Merged
pikann merged 5 commits into
masterfrom
feat/automation-node-type-payload
Aug 3, 2026
Merged

fix: include node type in plugin condition/action payload#345
pikann merged 5 commits into
masterfrom
feat/automation-node-type-payload

Conversation

@pikann

@pikann pikann commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

pluginNodePayload previously omitted the automation node's own Type, so a plugin binary that registers handlers for more than one Condition or Action node type had no way to know which one the host was asking it to evaluate/run - it could only guess from the config shape, which is fragile and breaks down when two node types share overlapping config fields.

Adds node_type to the JSON payload sent to plugins via EvaluateCondition/RunAction, alongside the existing config and task fields. Updates both call sites (evaluatePluginConditionAgainstTasks, runPluginAction).

Paired with the plugin-sdk-go change that adds NodeType to ConditionRequest/ActionRequest and dispatches plugin-side handlers by node type (see Paca-AI/plugin-sdk-go#<branch:
feat/automation-condition-action-nodes>).

Verified: go build ./... clean on services/api; go test passes on internal/worker, internal/service/automation, internal/domain/plugin, internal/platform/plugin. Added assertions in automation_consumer_test.go confirming node_type actually lands in the JSON dispatched to EvaluateCondition/RunAction, not just that dispatch succeeds.

pluginNodePayload previously omitted the automation node's own Type,
so a plugin binary that registers handlers for more than one
Condition or Action node type had no way to know which one the host
was asking it to evaluate/run - it could only guess from the config
shape, which is fragile and breaks down when two node types share
overlapping config fields.

Adds node_type to the JSON payload sent to plugins via
EvaluateCondition/RunAction, alongside the existing config and task
fields. Updates both call sites (walkPluginCondition, runPluginAction).

Paired with the plugin-sdk-go change that adds NodeType to
ConditionRequest/ActionRequest and dispatches plugin-side handlers by
node type (see Paca-AI/plugin-sdk-go#<branch:
feat/automation-condition-action-nodes>).

Verified: go build ./... clean on services/api; go test passes on
internal/worker, internal/service/automation, internal/domain/plugin,
internal/platform/plugin.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Adds node_type to plugin condition/action payloadpluginNodePayload now includes the node's Type field so a plugin declaring multiple node types can dispatch internally. Both walkPluginCondition and runPluginAction call sites are updated.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

pikann added 2 commits July 31, 2026 12:09
- Renamed test functions to reflect the new applyUpdateTask method for assigning, setting status, priority, tags, and custom fields.
- Updated assertions and error messages in tests to align with the new method.
- Introduced a new test consumer with Redis for handling plugin trigger events.
- Enhanced fakePluginRuntime to capture payloads dispatched to EvaluateCondition and RunAction.
- Added tests for evaluating plugin conditions against tasks with various match modes.
- Implemented tests for handling plugin trigger events, ensuring correct execution and task resolution.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The old action types and their ActionConfig fields are removed without a migration or compatibility path — see the cross-cutting issue below.

Reviewed changes since prior review (584fa21)

  • Consolidated action types — Replaced 5 single-field built-in actions (assign, set_status, set_priority, add_tag, set_custom_field) with a single ActionUpdateTask backed by TaskFieldUpdate, letting one node update any combination of task fields at once.
  • Added 7 new condition leaf fields — Title, story points, sprint, parent task, reporter, start date, and due date are now usable in built-in condition branches, with operator sets matching each field's type (date comparisons, contains for title, etc.).
  • Added plugin-emitted trigger event processing — A plugin's event_emit call now appends to StreamPluginTriggerEvents when its topic matches a loaded plugin's declared trigger, and AutomationConsumer reads it alongside the existing task-activity and external-trigger streams, resolving project + task from the event payload.
  • Added plugin condition target/match-mode — Plugin condition nodes now support task-target resolution (self, children, related) and match-mode aggregation (any/all), the same way built-in condition leaves do, via the new evaluatePluginConditionAgainstTasks.
  • Extended pluginNodePayload — Now includes project_id alongside node_type, so a plugin knows its project scope without requiring a user-entered project_id in config.
  • Schema-driven plugin config forms — Frontend config panel renders plugin-contributed node configs from the plugin manifest's JSON Schema, replacing the raw JSON textarea for plugin types that declare a schema.
  • Plugin condition edge validationPluginConditionTrueHandle moved to the domain package and validateEdgeHandle now properly gates plugin condition edges to exactly "true" or "else".

⚠️ Old action types removed with no migration path

The five prior built-in action types — assign, set_status, set_priority, add_tag, set_custom_field — and their corresponding ActionConfig fields (status_id, importance, tag, field_key, value) are deleted in this diff. Any existing automation node saved with one of these types will:

  • Fail validation on savevalidateActionConfig no longer has cases for these types, and the plugin resolver won't recognize them, so validateNodeTypeAndConfig rejects them.
  • Fail at execution timeapplyActionForTask's default branch dispatches unknown types to runPluginAction, which won't resolve them.

If there are existing automations in the database with these action types, this is a hard break. If not (e.g., this feature hasn't reached a deployment with real data yet), the change is safe but the commit message understates its scope — the PR description still says this is about adding node_type to plugin payloads.

Technical details
# Old action type removal

## Affected sites
- `services/api/internal/domain/automation/entity.go` — old `ActionType` constants and `ValidBuiltinActionTypes` entries removed; old `ActionConfig` fields replaced by `Update *TaskFieldUpdate`
- `services/api/internal/service/automation/automation_service.go` — old `validateActionConfig` cases removed
- `services/api/internal/worker/automation_consumer.go` — old `applyAssign`/`applySetStatus`/`applySetPriority`/`applyAddTag`/`applySetCustomField` methods removed

## Required outcome
- Either add a data migration that rewrites existing automation nodes from old action types to `update_task` (old `assign { member_id: X }``update_task { assignee_ids: [X] }`, etc.), or confirm no existing data uses these types and close this as intentional.

## Open questions for the human
- Do existing automations in any environment (prod, staging) use the old action types?
- Is the scope expansion deliberate, or should the action consolidation + plugin trigger event processing be separate PRs?

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes since prior review (5f62b42)

  • Added migration for legacy action types — New 000029_migrate_legacy_automation_actions.sql rewrites every automation_nodes row carrying assign, set_status, set_priority, add_tag, or set_custom_field into the equivalent update_task with structured TaskFieldUpdate JSONB configs, directly addressing the prior review's primary concern. The add_tagtags conversion is explicitly documented as lossy (append semantics lost in favor of full replacement) with a rationale that leaving the node unrecognized is strictly worse.
  • Added date format enforcement across the frontend-backend boundarytoDateInputValue/fromDateInputValue helpers now convert between <input type="date"> YYYY-MM-DD values and RFC 3339 strings for start_date/due_date in both condition leaves and update_task action configs. Backend tests (TestConditionLeaf_Evaluate_DueDateComparisons, TestConditionLeaf_Evaluate_DateFieldRejectsNonRFC3339Value, TestApplyUpdateTask_DueDate_JSONRoundTrip) guard the contract that compareTimePtr requires.
  • Fixed applyUpdateTask idempotency edge cases — Description comparison now uses bytes.Equal instead of only len > 0; tag and assignee comparisons use order-insensitive sortedStrings/sortedUUIDs helper functions so a reordered slice correctly registers as a no-op. Added corresponding test coverage.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes since prior review (544ba5b)

  • Updated e2e tests to use update_task action type — Every e2e test that referenced the old single-field action types (add_tag, assign, set_status, set_priority, set_custom_field) now uses the consolidated update_task with the corresponding TaskFieldUpdate fields. Conversions verified: add_tagupdate.tags, assignupdate.assignee_ids, set_statusupdate.status_id, set_priorityupdate.importance, set_custom_fieldupdate.custom_fields.
  • Updated unit test assertionsTestValidateEdgeHandle_PluginConditionSource now correctly accepts PluginConditionTrueHandle for plugin condition nodes (matching the validateEdgeHandle logic change from a prior commit), and TestValidateActionConfig_AddTag_AcceptsTarget is renamed to _UpdateTask_AcceptsTarget with the corresponding TaskFieldUpdate config.
  • Clarified compareTimePtr flow — A default: branch comment makes explicit that the first switch on op is a fast path for OpIsEmpty/OpIsNotEmpty; OpEquals/OpNotEquals/OpGreaterThan/OpLessThan are handled below after parsing the target time.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@pikann
pikann merged commit fe6423c into master Aug 3, 2026
6 checks passed
@pikann
pikann deleted the feat/automation-node-type-payload branch August 3, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant