Skip to content

feat(automation): schedule flow trigger — auto-launch flows on cron/interval/once - #1423

Merged
xuyushun441-sys merged 1 commit into
mainfrom
feat/schedule-trigger
May 31, 2026
Merged

xuyushun441-sys merged 1 commit into
mainfrom
feat/schedule-trigger

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Collaborator

What

The time-based sibling of #1421 (record-change trigger). Completes the schedule arm of the automation engine's FlowTrigger extension point so a flow whose start node declares a schedule auto-launches on cron / interval / once — no manual engine.execute().

No engine change — the engine already parses a flow's start node into a schedule binding (flow.type === 'schedule' or a start-node config.schedule descriptor); that shipped with #1421. This PR is purely the concrete trigger plugin.

New plugin: @objectstack/plugin-trigger-schedule

  • ScheduleTrigger implements the engine's FlowTrigger extension point and delegates timing to the platform IJobService (the 'job' service). It stays adapter-agnostic — the job service selects a cron-capable adapter (durable DbJobAdapter / CronJobAdapter) for cron schedules and the interval adapter for the rest.
  • normalizeSchedule accepts the canonical JobSchedule plus ergonomic shorthands: a bare cron string, { cron } / { expression }, { every } / { intervalMs }, { at }.
  • On fire, the flow runs with event: 'schedule' and params: { jobId, flowName, schedule }; the engine's start-condition gate still applies.
  • Error-isolated — a scheduled flow failure is logged and swallowed, never crashing the job runner.
  • Per-flow job name (flow-schedule:<flowName>) so stop() cancels exactly one flow; idempotent re-bind.
  • Lazy job-service resolution per bind, so the job service's kernel:ready adapter upgrade (interval → durable Db) is always picked up.
  • Graceful degrade when the automation or job service is absent (kernel:ready + getService, mirroring plugin-audit / the record-change trigger).
  • Depends on com.objectstack.service.job so its adapter upgrade runs first.

Usage

kernel
  .use(new AutomationServicePlugin())  // engine + flows
  .use(new JobServicePlugin())         // the 'job' service (cron/interval/db)
  .use(new ScheduleTriggerPlugin());   // ← makes schedule flows live

Tests

17 tests: normalizeSchedule shapes / shorthands / rejects, schedule+cancel, config.schedule fallback, fire→context, error isolation, stop, idempotency, plugin wiring + graceful degrade + lazy resolution. Builds clean (full DTS typecheck). service-automation 104 (no regression — no engine change).

Follow-up

This completes the two trigger types the plan scoped (record-change + schedule). Strong-typing the start-trigger config in spec (engine reads it defensively today) remains an optional later cleanup.

@vercel

vercel Bot commented May 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment May 31, 2026 11:18pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file tests tooling size/l labels May 31, 2026
…nterval/once

The time-based sibling of plugin-trigger-record-change. The automation engine
already parses a flow's start node into a `schedule` binding (flow.type ===
'schedule' or a start-node `config.schedule` descriptor) — shipped with the
record-change trigger PR — so this is purely the concrete trigger, with no
engine change.

New plugin @objectstack/plugin-trigger-schedule:
- ScheduleTrigger implements the engine's FlowTrigger extension point and
  delegates timing to the platform IJobService (the 'job' service), staying
  adapter-agnostic: the job service selects a cron-capable adapter (DbJobAdapter
  / CronJobAdapter) for cron and the interval adapter otherwise.
- normalizeSchedule accepts the canonical JobSchedule plus shorthands (bare cron
  string, { cron }/{ expression }, { every }/{ intervalMs }, { at }).
- On fire the flow runs with event:'schedule' + params:{ jobId, flowName,
  schedule }; the engine's start-condition gate still applies.
- Error-isolated (a flow failure never crashes the job runner); per-flow job
  name so stop() cancels exactly one flow; job service resolved lazily per bind
  so adapter upgrades (interval → durable Db) are picked up; graceful degrade
  when automation/job service absent (kernel:ready + getService).

Depends on com.objectstack.service.job so its adapter upgrade runs first.

Tests: 17 (normalizeSchedule shapes/shorthands/rejects, schedule/cancel,
config.schedule fallback, fire→context, error isolation, idempotency, plugin
wiring + graceful degrade + lazy resolution). Builds clean (full DTS).
Adds the package to the changeset fixed group.

This branch was successfully deployed

1 active deployment
Preview — e5b9511b Deployed May 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants