Skip to content

Events & Tasks

In Lombok, events, triggers, tasks, and workers are distinct, source-defined concepts. This page enumerates the concrete event names, task names, trigger kinds, and the mappings the platform source actually defines.

The execution model is:

  1. Something happens in Lombok (or an app emits its own event).
  2. An event record is created.
  3. A matching trigger (event-, schedule-, or user-action-based) resolves to a task.
  4. The task is dispatched to a worker (runtime or docker).
  5. The worker reports progress, logs, and a final completion (success or error) back to the platform.

The authoritative definitions live in the app repo:

ConceptFile
Event names & identifier rulespackages/types/src/events.types.ts
Trigger, task, progress & invocation schemaspackages/types/src/task.types.ts
Core task names & data shapespackages/api/src/task/task.constants.ts
Built-in event→task mappingpackages/api/src/task/constants/core-tasks.constants.ts
Manifest schema & validationpackages/types/src/apps.types.ts

CoreEvent (events.types.ts) enumerates the events the platform itself emits:

CoreEvent valueEmitted identifier
object_addedcore:object_added
object_removedcore:object_removed
object_updatedcore:object_updated
folder_scannedcore:folder_scanned
serverless_task_enqueuedcore:serverless_task_enqueued
docker_task_enqueuedcore:docker_task_enqueued
new_user_registeredcore:new_user_registered

Two schemas constrain event identifiers:

  • Bare identifiereventIdentifierSchema: non-empty, matches ^[a-z_]+$. Used for app-emitted events.
  • Core-prefixed identifiercorePrefixedEventIdentifierSchema: matches ^core:[a-z_]+$. Used wherever a platform event is referenced.

The core namespace comes from CORE_IDENTIFIER = 'core'.

From the event service behavior:

  • When the core platform emits an event, it is stored and matched as core:<event>, and enabled apps whose subscribedCoreEvents include that identifier are candidates to receive it.
  • When an app emits an event, the emitter is the app’s identifier and the event uses the bare identifier. That event is delivered to the emitting app’s own triggers.

CORE_EVENT_TRIGGERS_TO_TASKS_MAP defines the platform’s own reactions to core events. It is a partial map:

Core eventCore taskCondition
object_addedanalyze_objectalways
new_user_registeredsend_email_verification_linkuserEmail present and userEmailVerified === false
docker_task_enqueuedrun_docker_workeralways
serverless_task_enqueuedrun_serverless_workeralways

object_removed, object_updated, and folder_scanned are valid events but have no built-in core-task mapping here.

A trigger binds an event, schedule, or user action to a task. taskTriggerConfigSchema is a discriminated union on kind. All trigger kinds share a base: taskIdentifier, optional condition, optional onComplete[], optional onProgress[].

kindAddsRuntime-registerable?
eventeventIdentifier, optional dataTemplate, optional triggerKeyYes
scheduleconfig, required triggerKeyYes
user_actionoptional scopeNo
{
"kind": "event",
"eventIdentifier": "core:object_added",
"taskIdentifier": "demo_object_added_worker_task"
}
  • eventIdentifier accepts a bare identifier or a core:-prefixed one.
  • triggerKey is optional.
  • dataTemplate lets the trigger shape the task’s data from the event.

scheduleConfigSchema has two variants:

Interval

{
"kind": "schedule",
"triggerKey": "hourly_job",
"config": { "kind": "interval", "interval": 1, "unit": "hours" },
"taskIdentifier": "demo_scheduled_worker_task"
}

Cron

{
"kind": "schedule",
"triggerKey": "weekday_morning_job",
"config": { "kind": "cron", "expression": "0 9 * * 1-5", "timezone": "UTC" },
"taskIdentifier": "demo_scheduled_worker_task"
}

Source constraints:

  • triggerKey is required on schedules.
  • Cron is 5-field only.
  • Sub-minute granularity is rejected.
  • timezone defaults to UTC when omitted.

Declared only in the manifest. Optional scope may narrow by user permissions and/or a specific folder.

Any trigger (and onComplete/onProgress handler) may carry a condition string. In source it is validated only for safety, not against a field whitelist.

A task is a named unit of work declared in the manifest:

{
"identifier": "demo_object_added_worker_task",
"label": "Demo Object Added Worker",
"description": "A task that runs for every newly added object.",
"handler": { "type": "runtime", "identifier": "demo_object_added_worker" }
}

Key rules:

  • identifier matches ^[a-z_]+$
  • handler.type is runtime or docker
  • runtime handlers must point at a declared runtime worker
  • docker handlers must point at a declared container-profile job

CoreTaskName enumerates the platform’s own task identifiers, described in CORE_TASKS:

CoreTaskNameIdentifierDescription
AnalyzeObjectanalyze_objectGenerate metadata and previews for an object
ReindexFolderreindex_folderReindex a folder and its contents
RunDockerWorkerrun_docker_workerRun a docker worker to execute a task
RunServerlessWorkerrun_serverless_workerRun a serverless worker to execute a task
SendEmailVerificationLinksend_email_verification_linkSend email verification link to a newly signed-up user
CreateEventNotificationscreate_event_notificationsCreate notification records for an event or group of events
BuildNotificationDeliveriesbuild_notification_deliveriesCreate notification delivery records for a unique notification
SendNotificationEmailssend_notification_emailsSend batched notification emails to users

Only a subset of these are wired directly from core events via CORE_EVENT_TRIGGERS_TO_TASKS_MAP.

onComplete lets a task enqueue follow-up tasks when it finishes. It is recursive.

onProgress reacts to a parent task’s progress reports rather than completion.

When a task runs, its invocation carries a kind describing why it ran:

kindKey context fields
system_actionoptional idempotencyData
eventeventId, emitterId, eventIdentifier, eventData, optional triggerKey, targetUserId, targetLocation
scheduletimestampBucket, triggerKey, config
user_actionuserId, requestId
app_actionrequestId
task_complete_childparent task context
task_progress_childparent task context

handler.identifier resolves to a worker. Runtime workers are declared in runtimeWorkers.

The executor that runs a task reports executorMetadata, a discriminated union on type:

  • system
  • docker
  • runtime

While running, a worker may emit TaskProgressReports with:

  • code
  • details
  • message
  • timestamp
  • executorMetadata

Separately, the platform broadcasts lifecycle updates via TaskUpdateType:

  • task_started
  • task_progress
  • task_completed
  • task_requeued
  • task_failed

A TaskDTO carries two log streams:

  • system log
  • task log

A task ends with a TaskCompletion on either the success or error path. On the error path the executor may set requeueDelayMs to retry later. The platform caps attempts at MAX_TASK_ATTEMPTS = 5.

events.types.ts also defines notification aggregation used by notification-related core tasks. EventNotificationAggregationScope is one of:

  • SERVER
  • FOLDER
  • FOLDER_OBJECT

The manifest schema enforces these cross-references:

  • core: event triggers must appear in subscribedCoreEvents
  • trigger task identifiers must point at declared tasks
  • runtime handlers must point at declared runtime workers
  • docker handlers must point at declared container-profile jobs
  • runtime worker entrypoints must exist in the uploaded bundle manifest

The simple demo app wires:

  • core event subscriptions
  • an event trigger on core:object_added
  • two schedule triggers
  • runtime-worker-backed tasks