Skip to content

Intent declarative glue: scheduled activities (cron → query → notify) - #6053

Merged
delchev merged 1 commit into
masterfrom
intent-glue-schedules
Jun 19, 2026
Merged

Intent declarative glue: scheduled activities (cron → query → notify)#6053
delchev merged 1 commit into
masterfrom
intent-glue-schedules

Conversation

@delchev

@delchev delchev commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What

Adds the schedules: block of the declarative-glue catalog — the "overdue reminders" pattern. On a cron tick, query an entity and notify per matching row, with no hand-written code:

schedules:
  - name: overdueLoans
    cron: "0 0 9 * * ?"
    entity: Loan
    where:
      - { field: dueOn,  op: lt, value: CURRENT_DATE }   # eq/ne/gt/ge/lt/le/like; CURRENT_DATE/CURRENT_TIMESTAMP → now()
      - { field: status, op: eq, value: "ACTIVE" }
    notify: { to: member.email, subject: "Overdue: {book.title}", body: "Your loan is overdue." }

→ generates gen/events/OverdueLoansJob.java: a @Scheduled JobHandler that runs new LoanRepository().findAll(Criteria…) and notifies per row.

How (heavy reuse of the just-merged foundation)

  • ScheduleSupport.criteriaExpression (pure, unit-tested) builds the typed Criteria chain from where (the query API from Typed Criteria query API on JavaRepository (intent glue foundation) #6050) — field names PascalCased to the entity properties; CURRENT_DATE/CURRENT_TIMESTAMPnow().
  • The per-row notify reuses NotificationSupport.plan (from Intent declarative glue: notifications (event → email @Listener) #6052) against the row entity — same relation-load + {field}/{relation.field} interpolation as notifications.
  • GlueIntentGenerator emits a schedules collection into <intent>.glue; Job.java.template renders the @Scheduled JobHandler; generateUtils.js gets the schedules collection case. Parser validates name/cron/entity/operators/notify; honors the .settings override.

Testing

  • ScheduleSupportTestCriteria building (operators, PascalCase fields, date tokens, numbers) — green.
  • IntentEngineIT.glue_template_generates_… extended: asserts the generated StaleOrdersJob is @Scheduled, queries via Criteria.create().lt("OrderDate", java.time.LocalDate.now()), loads the related Customer, and Mail.sends per row — green locally (Tests run: 1, Failures: 0). CI runs the full suite on H2/PostgreSQL/MSSQL.

Scope / gaps

Action is notify only; between/in operators and process trigger: { onSchedule: <cron> } (timer start event) are later increments.

🤖 Generated with Claude Code

Adds the `schedules:` block of the declarative-glue catalog: on a cron tick,
query an entity with a typed Criteria and notify per matching row - the
"overdue reminders" pattern, no hand-written code.

- ScheduleIntent / ScheduleConditionIntent model + parser validation (unique
  name, cron, declared entity, supported where operators, valid notify).
- ScheduleSupport.criteriaExpression (pure, unit-tested) builds the typed
  Criteria chain from `where` (eq/ne/gt/ge/lt/le/like; field names PascalCased
  to entity properties; CURRENT_DATE/CURRENT_TIMESTAMP -> now()).
- GlueIntentGenerator emits a `schedules` collection into <intent>.glue; the
  per-row notify reuses NotificationSupport.plan against the row entity (same
  relation-load + interpolation as notifications). Job.java.template renders a
  @scheduled JobHandler that runs `new <Entity>Repository().findAll(Criteria...)`
  and sends per row; generateUtils.js gets the `schedules` collection case.
  Honors the .settings override.

Builds on the merged typed Criteria API and the notifications machinery.
Covered by ScheduleSupportTest + IntentEngineIT (the generated @scheduled job
queries via Criteria and notifies per row) - green locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@delchev
delchev merged commit ef65324 into master Jun 19, 2026
8 of 11 checks passed
@delchev
delchev deleted the intent-glue-schedules branch June 19, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant