Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
7.8 KiB
PRD — Stable Workflow Payload Across Trigger Schema Changes
- Slug:
workflow-trigger-payload-mapping - Date:
2025-12-27 - Status: Draft
Summary
Workflows have a payloadSchemaRef that should remain stable over time, even if the trigger event’s schema evolves. This plan introduces an explicit “source payload schema” concept for event triggers and an optional trigger-level mapping (event payload → workflow payload). When the source schema ref matches the workflow payload schema ref, “no mapping” is a valid state and execution uses the payload as-is.
Problem
Today, event-triggered workflows implicitly assume the inbound event payload already matches the workflow’s payloadSchemaRef. When the trigger event’s schema changes (or differs between tenants/system), workflows can silently stop running or become confusing to debug. Users also lack a clear UX for: (a) seeing the trigger’s source schema, (b) deciding whether they need a mapping, and (c) understanding whether a workflow is runnable for a given event payload schema.
Goals
- Preserve the invariant: workflow payload is stable (
payloadSchemaRefis the canonical contract for steps, mapping UI, expression autocomplete, etc.). - Allow trigger event schemas to change independently of workflows, without breaking stable workflows when a mapping exists.
- Make “no mapping” a valid state when
sourcePayloadSchemaRef === payloadSchemaRef. - Block execution (not saving) when required mapping is missing or invalid; surface this via validation status/details.
- Record enough schemaRef/mapping provenance on events/runs for debugging and audit.
Non-goals
- Automatic migration of existing workflows when event schemas change.
- Schema compatibility inference beyond
schemaRefequality (i.e., “structurally compatible” schemas without mapping). - Backward-compatibility layers for legacy event shapes (explicitly not required).
- A generalized “schema transform language” beyond existing mapping primitives (expressions / field refs / literals).
Users and Primary Flows
Users
- MSP admin / automation builder
- Internal support / engineers debugging automation
Primary flows
- Build workflow: choose trigger event → see source schemaRef → choose/confirm workflow payloadSchemaRef → if mismatch, define trigger mapping; if match, leave mapping empty.
- Publish workflow: validator computes runnable status. If mismatch + missing mapping: publish fails; draft saves with invalid status.
- Ingest event: event arrives with eventName + payload (and optionally a source schemaRef). System resolves
sourcePayloadSchemaRef, then for each matching workflow version:- If refs match and no mapping: payload passes through unchanged.
- If mapping exists: map → validate → start run (even when refs match).
- If refs differ and mapping missing/invalid: do not start run.
- Run workflow (Run dialog): choose event type to seed “source schema”, enter source payload, run uses trigger mapping to produce workflow payload.
- Debug: event list/run logs show source schemaRef used and whether mapping was applied.
UX / UI Notes
- In the workflow designer trigger section:
- Display the trigger’s source schema ref (from event catalog; optionally override-able).
- Display the workflow’s payload schema ref (existing picker).
- If refs match: show “Identity (no mapping required)” and hide mapping editor by default.
- If refs differ: show required mapping editor (event → workflow payload) with schema-aware field pickers.
- Trigger mapping expressions evaluate with an
eventroot (the full incoming event). The source payload is available atevent.payloadand is typed from the trigger’s source schema ref. The workflow payload root variable (payload) continues to refer to the workflow payload inside normal workflow steps. - Validation messaging should explicitly mention:
- Missing/unknown source schema ref
- Mismatch requiring mapping
- Mapping gaps (missing required fields) and expression errors
Requirements
Functional Requirements
- Event ingestion resolves a
sourcePayloadSchemaRefwith precedence:- event submission payloadSchemaRef, 2) event catalog payload_schema_ref, 3) unknown (validation error).
- If event submission provides a schemaRef that differs from the event catalog, accept the event and record a warning (and telemetry) indicating the conflict; submission schemaRef still wins precedence.
- Workflows can optionally define a trigger-level mapping from source payload → workflow payload.
- “No mapping” is valid when schema refs match; execution uses source payload as workflow payload.
- When schema refs match, trigger mapping remains optional; if provided, it is applied and validated like any other mapping.
- When refs differ, mapping is required for execution and is validated deeply (including nested required fields).
- Missing secrets referenced by trigger mapping are validation errors.
- Validation details are persisted and shown in the designer.
- Run dialog can build a source-payload form from the trigger’s source schema ref, then run with mapping applied.
- Trigger mapping expressions must use
eventas the root variable; the incoming payload is accessed viaevent.payload(nopayloadalias in the trigger mapping context to avoid confusion with workflow payload).
Non-functional Requirements
- Mapping evaluation and schema validation must be deterministic and auditable (store schemaRef + mapping provenance on run/events).
- Avoid runtime surprises: if mapping is required and invalid, the workflow does not start.
Data / API / Integrations
- Add
payload_schema_refto workflow runtime event records (v2) so events retain source schema provenance. - Extend workflow trigger shape to include optional
sourcePayloadSchemaRefoverride and optionalpayloadMapping. - Expose
payload_schema_refin workflow event list APIs so UI can show it.
Security / Permissions
- Creating/editing trigger mapping requires workflow
managepermission. - Viewing schema refs and mapping details requires workflow
read(consistent with existing behavior).
Observability
- Audit log for publish/save already exists; extend run/event metadata to include:
- sourcePayloadSchemaRef used
- whether mapping was applied
- catalog-vs-submission schemaRef conflict warning (when present)
- validation failures preventing start (for debugging)
Rollout / Migration
- DB migration to add
payload_schema_refto workflow runtime events table (v2). - Backfill is not required; existing events can have null source schemaRef.
- Existing system event catalog entries should include
payload_schema_refgoing forward (inbound email already does).
Open Questions
- Trigger mapping root variable name:
event(resolved). Steps continue to usepayloadfor the workflow payload; trigger mapping usesevent.payloadfor the source payload. - If event submission provides a schemaRef that conflicts with event catalog: accept and warn (resolved). Submission wins precedence; record warning/telemetry for observability.
- If schemaRefs match, do we allow an optional mapping anyway? Yes (resolved). Mapping remains optional but is validated/applied when provided.
Acceptance Criteria (Definition of Done)
- When trigger source schemaRef matches workflow payload schemaRef, a workflow with no trigger mapping is valid and runnable.
- When source schemaRef differs, publish fails without trigger mapping; draft can save but is invalid for execution.
- Event-triggered runs apply trigger mapping (when present) and validate the resulting payload against workflow payloadSchemaRef.
- Workflow event list/run views show the source schemaRef used and whether mapping was applied.
- Designer clearly communicates whether mapping is required and guides users to fix invalid states.