Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

104 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 events 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 workflows `payloadSchemaRef`. When the trigger events 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 triggers 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** (`payloadSchemaRef` is 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 `schemaRef` equality (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
1. **Build workflow**: choose trigger event → see source schemaRef → choose/confirm workflow payloadSchemaRef → if mismatch, define trigger mapping; if match, leave mapping empty.
2. **Publish workflow**: validator computes runnable status. If mismatch + missing mapping: publish fails; draft saves with invalid status.
3. **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.
4. **Run workflow (Run dialog)**: choose event type to seed “source schema”, enter source payload, run uses trigger mapping to produce workflow payload.
5. **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 triggers **source schema ref** (from event catalog; optionally override-able).
- Display the workflows **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 `event` root (the full incoming event). The source payload is available at `event.payload` and is typed from the triggers 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 `sourcePayloadSchemaRef` with precedence:
1) 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 triggers source schema ref, then run with mapping applied.
- Trigger mapping expressions must use `event` as the root variable; the incoming payload is accessed via `event.payload` (no `payload` alias 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_ref` to workflow runtime event records (v2) so events retain source schema provenance.
- Extend workflow trigger shape to include optional `sourcePayloadSchemaRef` override and optional `payloadMapping`.
- Expose `payload_schema_ref` in workflow event list APIs so UI can show it.
## Security / Permissions
- Creating/editing trigger mapping requires workflow `manage` permission.
- 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_ref` to 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_ref` going forward (inbound email already does).
## Open Questions
- Trigger mapping root variable name: **`event`** (resolved). Steps continue to use `payload` for the workflow payload; trigger mapping uses `event.payload` for 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.