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

10 KiB
Raw Blame History

Workflow Event Catalog v2 — Domain Events Expansion

Date 2026-01-23
Status Draft
Owner Workflow Overhaul

1. Summary

Expand the Workflow Event Catalog (v2) with a comprehensive, business-relevant set of domain events (tickets, scheduling, projects, billing, CRM, documents, email, integrations, assets/media), and implement end-to-end production emission of these events so customers can attach workflow v2 triggers reliably.

This plan implements the proposed catalog entries and runtime plumbing described in:

  • ee/docs/plans/2025-12-28-workflow-event-catalog/PRD.md
  • ee/docs/plans/2025-12-28-workflow-event-catalog/event-proposals.md

2. Problem / User Value

Today, the catalog exists and simulation tooling exists, but the catalog is incomplete and many valuable business moments are not emitted (or are emitted inconsistently across modules). Users cannot reliably automate real-world MSP flows (billing, dispatch, SLA, approvals, customer communication) because the event set is missing or not standardized.

Delivering a consistent, curated event set enables:

  • Faster automation authoring (“when X happens, do Y”).
  • Stronger observability and debugging (clear event types + stable payload shapes).
  • Safer integrations (schema validation + versioning).

3. Goals

  1. Add all proposed domain events to the system catalog with correct category/name/description and payload_schema_ref.
  2. Provide stable, versioned payload schemas in the workflow schema registry for every catalog event (payload.*.v1).
  3. Ensure the event bus accepts/validates these events (shared event bus schema/types).
  4. Emit events from real business logic paths across modules (not only via simulation).
  5. Add test coverage that ensures event emission + schema validation + catalog presence.

4. Non-goals

  • New UI work for the Events Catalog screen (covered by the 2025-12-28 plan).
  • Implementing entirely new product features solely to support events (e.g., building approvals if approvals dont exist).
  • Building “event replay” tooling beyond existing simulate.
  • Backfilling historical events.

5. Scope (What “Implemented” Means)

For each event type in event-proposals.md, “implemented” means:

  1. A catalog entry exists in system_event_catalog (or tenant event_catalog if intentionally tenant-only).
  2. The catalog entry has a payload_schema_ref (schema registry key) and appropriate metadata (category, description).
  3. The workflow schema registry has a registered schema at that ref (payload.<Event>.v1).
  4. The event bus type/schema permits publishing that eventType and validates payload shape at publish/ingest boundaries (as applicable).
  5. A real product path emits the event (or the plan explicitly marks it as “catalog-only” if its not yet backed by behavior).

6. Event Design Standards

6.1 Naming

  • event_type: SCREAMING_SNAKE_CASE (existing convention).
  • payload_schema_ref: payload.<PascalCaseEventName>.v1 (versioned; changes require .v2).

6.2 Payload conventions

Payload schemas must use camelCase JSON keys (no snake_case). This aligns with existing event bus payload shapes and reduces mapping friction across the product.

Minimum recommended fields (where applicable):

  • tenantId (always; required by schema)
  • Entity identifiers: ticketId, projectId, invoiceId, etc. Prefer a single canonical ID per domain; do not embed full entity snapshots unless strictly necessary.
  • Actor (when meaningful):
    • actorUserId (preferred when initiated by an internal user)
    • actorContactId (when initiated by an external/client contact)
    • actorType only when needed to disambiguate (USER / CONTACT / SYSTEM)
  • State transitions:
    • Use previousX / newX (e.g. previousStatus, newStatus).
    • For assignment-style transitions, prefer explicit fields like previousAssigneeUserId / newAssigneeUserId.
  • Mutations:
    • updatedFields: string[] with dot-paths (e.g. ["billingAddress.line1", "dueDate"]) and/or
    • changes: Record<string, { previous: unknown; new: unknown }> keyed by the same dot-paths.
  • Timestamps:
    • occurredAt (always; ISO 8601 string) — when the event happened.
    • Include domain timestamps such as createdAt / updatedAt only if they add meaningful context for workflows.

6.3 Catalog vs event bus vs schema registry

We maintain three related “sources of truth”:

  • Catalog tables (system_event_catalog, event_catalog): which events are workflow-relevant and discoverable in UI.
  • Event bus schema/types (shared/workflow/streams/eventBusSchema.ts): what event types can be published/ingested safely.
  • Workflow schema registry (shared/workflow/runtime/registries/schemaRegistry + registrations): canonical payload schemas for trigger mapping + simulation.

This plan ensures these are consistent for the expanded event set.

7. Implementation Approach

7.1 Foundations (once)

  • Define/confirm canonical payload field naming (camelCase vs snake_case) and align new schemas accordingly.
  • Add shared helpers to reduce duplication when publishing events (including a single place to apply tenantId/actor enrichment).
  • Add schema registry definitions and registrations for new payload refs.
  • Update shared/workflow/streams/eventBusSchema.ts to include event types and payload schema mappings for the expanded set.
  • Add migrations that insert/update catalog entries (idempotent upserts by event_type).

7.2 Domain emission (by module)

Implement emission in the closest “business action” layer (server actions/services) where the state change is authoritative, using the event bus publisher utilities so the workflow worker ingests events via the shared global stream.

Modules in scope:

  • Tickets: status/priority/assignment, messages/comments, SLA stages, approvals (if present).
  • Scheduling: schedule entries/appointments, blocks, dispatch/field ops (if present), capacity thresholds.
  • Projects: project lifecycle, tasks, dependencies, approvals (if present).
  • Billing: invoice lifecycle, payments, credits, contracts, recurring billing runs.
  • CRM: clients/contacts, interactions/notes, tags.
  • Documents: upload/delete, associate/detach, generated docs, signatures (if present).
  • Email: inbound/outbound lifecycle, delivery/bounce/complaint/unsubscribe signals (where supported).
  • Notifications: send/deliver/fail/read (where supported).
  • Surveys/CSAT: sent/response/reminder/expired, CSAT alerts.
  • Integrations: sync lifecycle, token health, webhooks, mapping changes.
  • Assets/media: asset lifecycle and assignment, media processing.

7.3 Compatibility / de-duping

Some proposed names overlap with existing event bus types (e.g., TICKET_COMMENT_ADDED vs proposed TICKET_MESSAGE_ADDED; scheduling SCHEDULE_ENTRY_* vs proposed APPOINTMENT_*). This plan requires an explicit decision per overlap:

  • Either standardize on existing event types and treat the proposal name as an alias/deprecated proposal, or
  • Introduce the new event type and deprecate the old one, with clear mapping guidance.

8. Risks

  • Overlaps/renames can break existing workflows if we replace event types rather than add new ones.
  • Some events depend on behavior that may not exist across all tenants (SLA, approvals, dispatch/field ops).
  • Email delivery/bounce/complaint events are provider-dependent and may require additional webhook ingestion.
  • Large surface area increases maintenance burden if payload standards drift across domains.

9. Rollout / Migration Notes

  • Use idempotent catalog upsert migrations (safe to re-run).
  • Prefer additive changes (new event types) over renames; if deprecating, keep old event types operational for a defined window.
  • Ship in phases by module so customers can start using early events while later modules are implemented.

10. Open Questions (please confirm)

  1. Canonical identifiers: Should CRM use clientId everywhere, or do we also standardize on companyId? (The existing catalog already has both concepts in different places.)
  2. Message vs comment: Should we keep existing TICKET_COMMENT_* event types and map the proposed TICKET_MESSAGE_ADDED to those (or vice versa)?
    • Decision (2026-01-23): Introduce TICKET_MESSAGE_* as the canonical domain event set for workflow v2; keep TICKET_COMMENT_* as legacy/back-compat (no automatic aliasing due to payload shape differences).
  3. Appointments vs schedule entries: Should the scheduling layer expose APPOINTMENT_* events, or reuse/expand SCHEDULE_ENTRY_*?
    • Decision (2026-01-23): Introduce APPOINTMENT_* as canonical workflow triggers; keep SCHEDULE_ENTRY_* for lower-level schedule entry changes and existing calendar-sync integrations.
  4. Catalog-only events: Are SLA/approval/dispatch events expected to exist as real product behavior today, or should they be cataloged but emitted only when those modules are enabled?
    • Decision (2026-01-23): TICKET_APPROVAL_* and PROJECT_APPROVAL_* events are catalog-only for now. The product does not currently have a ticket/project approval request/decision subsystem (no authoritative create/approve/reject path to hook), so we will not emit these events until that behavior exists.
    • Decision (2026-01-24): DOCUMENT_SIGNATURE_REQUESTED, DOCUMENT_SIGNED, and DOCUMENT_SIGNATURE_EXPIRED are catalog-only for now. The product does not currently have an e-signature request/fulfillment subsystem (no authoritative request/create or provider callback/webhook ingestion path to hook), so we will not emit these events until that behavior exists.
  5. Payload field casing: Confirm were standardizing on camelCase payload keys for new schemas (matches much of shared/workflow/streams/eventBusSchema.ts today).
    • Decision: use camelCase payload keys for all new payload.*.v1 schemas and event bus payloads.

11. Acceptance Criteria / Definition of Done

  • All events in event-proposals.md are either:
    • Implemented end-to-end (catalog + schema registry + event bus + emission), or
    • Explicitly marked as deferred/catalog-only with rationale and tracked follow-up.
  • The workflow v2 simulator can simulate every catalog event using its payload_schema_ref.
  • Integration tests validate that representative business actions publish the expected event type with a valid payload and that the workflow worker ingests it without schema errors.