BaryoDev / BaryoDev/barakoCMS

Workflows: a schedule trigger in the tenant's time zone, with catch-up and one run per due time

Open
#839 0 comments 0 reactions 0 assignees View on GitHub
core
Dominant language
C#
Stars
6
Forks
7
Avg merge
4h 42m
Merged PRs (30d)
307

Description

Split from #255 with Arnel's agreement on 14 September 2026: the workflow side of scheduling moves to 4.3.0, beside the workflow chain work it pairs with (#575, #831, #835). #255 keeps the scheduling API other modules use, on 5.0.0.

Acceptance case: every day at midnight, sweep attendance (#835).

## Change

- **A schedule trigger on a workflow.** `{ "schedule": "0 0 * * *", "timeZone": "tenant" }`. Cron with five fields, validated when the workflow is saved, with the next five due times returned so barakoBrew can show them. The tenant's time zone comes from site settings (#793); an explicit IANA zone is also accepted.
- **The due time as input.** A scheduled run carries `{{schedule.at}}` and `{{schedule.previousAt}}`, so "yesterday" is computed from when the run was due, not when it ran.
- **Missed runs.** If the API was down at a due time, a catch-up policy per workflow decides: `once` (default, fire one run for the latest missed time), `each` (fire every missed time, capped), or `skip`.
- **Exactly one run per due time.** The due time is the idempotency key, claimed in the database, so several API instances or a restart never fire it twice.
- **Daylight saving.** A due time that does not exist in the zone fires at the next valid minute; one that occurs twice fires once.
- **Operations.** Scheduled runs appear in workflow runs with their due time. A workflow can be paused, which stops new due times without deleting the schedule.
- **Built on `ScheduledContentService`'s sweep,** so there is one timer in the process, and #255 can later move both onto its module API.

## Done when

- With a fake clock, a midnight schedule in Asia/Manila fires once at 16:00 UTC, with `schedule.previousAt` the previous midnight.
- Stopping the host across two due times and starting it fires one run under `once` and two under `each`.
- Two hosts on one database fire one run for a due time.

## Where it lives

Core: workflow triggers and the one sweep timer, `ScheduledContentService`. #255 keeps the scheduling API for modules.

Contributor guide

Open the contributing guide

Research direction

Start with the workflow trigger implementation and ScheduledContentService, then trace how workflow runs and tenant site settings are represented. Use the fake-clock acceptance cases as the initial test map, including Asia/Manila, catch-up policies, and two hosts sharing a database. Done means the listed due-time, pause, daylight-saving, and exactly-once behaviors are covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, databases, distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.