---
name: scheduled-jobs-and-automation
description: Build scheduled background workflows with tibi-server jobs. Covers cron design, job context, safe automation patterns, reporting/cleanup/sync use cases, and how jobs interact with hooks, audit, and realtime.
---

# scheduled-jobs-and-automation

## When to use this skill

Use this skill when:

- A project needs scheduled cleanup, reporting, imports, syncs, reminders, or maintenance tasks
- You want automation without an incoming HTTP request
- Jobs should update data, send mail, call APIs, or emit realtime events
- You need to decide whether logic belongs in a hook, an action, or a job

## Goal

The goal is to design jobs as reliable background workflows, not as miscellaneous scripts.

Jobs on this stack are:

- cron-triggered
- goja-based JavaScript programs
- independent of HTTP requests
- able to use many of the same server-side packages as hooks

## Source of truth

Use these sources when implementing or reviewing jobs:

- `tibi-server/docs/11-jobs.md`
- `tibi-server/docs/10-audit.md`
- `tibi-server/docs/07-realtime.md`
- `api/config.yml`

## Hook vs. action vs. job

Choose the right execution surface.

- **Hook**: request-coupled logic around CRUD or actions
- **Action**: endpoint-style business workflow triggered by an explicit call
- **Job**: scheduled background automation without an incoming request

Do not place scheduled logic into hooks just because the code already exists there.

## Good use cases

Strong job use cases:

- cleanup of old documents or temp data
- periodic report generation
- scheduled API synchronization
- cache warming or maintenance tasks
- reminder and digest emails
- scheduled realtime announcements

Weak use cases:

- workflows that must run immediately on user action
- logic that depends on live request/response objects
- features that need interactive user feedback during execution

## Job configuration

Every job should define:

- cron schedule
- file path
- timeout when appropriate
- optional metadata via `meta`

Treat cron frequency as a product and operations decision. Do not set aggressive schedules without a real need.

## Job context limits

Jobs have broad server-side access, but they are not request-driven.

Important consequences:

- no `request`
- no `response`
- no `user.*`
- no `cookie.*`
- no `channel.subscribe`
- `channel.send` is available

If the logic depends on request context, it does not belong in a job.

## Safe automation patterns

Jobs should be:

- idempotent where possible
- bounded in runtime
- explicit in filters and update scope
- observable through logs or downstream effects

Avoid “run and mutate everything” jobs without clear selection criteria.

## Interaction with audit and realtime

Jobs are not isolated from other system behavior.

- DB operations from jobs appear in audit with `source.type: "job"`
- jobs can emit realtime events through `channel.send`

This makes jobs useful for background workflows that should still be visible operationally.

## Recommended job patterns

### Cleanup job

Recommended shape:

- explicit age threshold
- narrow filter
- bounded timeout
- optional reporting of removed count

### Scheduled reporting

Recommended shape:

- aggregate counts or summaries
- render a report template if needed
- send mail or store result

### External sync

Recommended shape:

- pull from external API
- normalize data
- update local records idempotently
- log enough context for troubleshooting

### Scheduled notifications

Recommended shape:

- compute upcoming or due events
- send mail, action-like side effect, or realtime signal
- avoid duplicate sends through clear state checks

## Operational concerns

When adding a job, decide:

- how often it runs
- what timeout it needs
- whether reruns are safe
- how failure is detected
- whether a manual rerun path exists

Jobs should not become invisible critical infrastructure.

## Anti-patterns

- Using jobs for logic that belongs in request-time hooks or actions
- Overly frequent cron schedules for expensive tasks
- No timeout on potentially slow network-heavy jobs
- Broad destructive updates without precise filters
- Silent failures with no observable output or effect

## Verification checklist

After adding a job, verify all of these:

1. The cron schedule matches the real business need.
2. The job logic does not rely on request-only APIs.
3. Timeout and runtime expectations are reasonable.
4. Repeated execution does not corrupt data.
5. Any audit/realtime side effects are intentional.
6. `yarn validate` stays clean.

## What an LLM should inspect first

When asked to automate something on this starter, inspect in this order:

1. `tibi-server/docs/11-jobs.md`
2. whether the trigger is scheduled, request-driven, or manual
3. whether the logic needs audit visibility or realtime side effects
4. the project config area where the job will be declared
5. the exact data mutation scope

This prevents turning cron tasks into unbounded background risk.
