Skip to main content
Workflows provide durable background execution for async processing, scheduled jobs, multi-step pipelines, and data aggregation. Apps define workflows in src/server/workflows/ and schedule them via schedules.json.

Daily task summary

We want the task tracker to have a daily workflow that aggregates task metrics, generates a human-readable summary with the Anthropic LLM service, and posts it to the team Slack channel. Define the workflow in src/server/workflows/dailySummary.ts:
import type { JobDefinition } from '@synthetiq/workflows';

export const dailySummary: JobDefinition = {
  name: "Daily Task Summary",
  description: "Aggregate task metrics, generate an AI summary, and post to Slack",
  variables: {
    appId: { type: "param" },
  },
  steps: [
    {
      importFromDatabase: {
        appId: "{{var.appId}}",
        tableName: "Task",
        columns: ["id", "status", "createdAt"],
      },
      outputTable: "tasks",
    },
    {
      sql: `
        SELECT
          COUNT(*) AS totalTasks,
          SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completedTasks,
          SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) AS activeTasks
        FROM tasks
      `,
      outputTable: "summary",
    },
    {
      service: "anthropic",
      operation: "streamMessage",
      forEach: { source: "summary" },
      params: {
        model: "claude-sonnet-4-20250514",
        max_tokens: 256,
        messages: [
          {
            role: "user",
            content: "Write a brief daily task summary for a team Slack channel. Total tasks: {{item.totalTasks}}, completed: {{item.completedTasks}}, active: {{item.activeTasks}}. Keep it concise and friendly.",
          },
        ],
      },
      outputTable: "aiSummary",
      outputSchema: {
        text: "VARCHAR",
      },
    },
    {
      service: "slack",
      operation: "sendMessage",
      forEach: { source: "aiSummary" },
      params: {
        channel: "#task-updates",
        text: "{{item.text}}",
      },
      outputTable: "slackResult",
      outputSchema: {
        ok: "BOOLEAN",
        ts: "VARCHAR",
      },
    },
  ],
};
Export it from src/server/workflows/index.ts:
export { dailySummary } from './dailySummary';

Scheduling

Configure the workflow to run daily in schedules.json:
{
  "schedules": [
    {
      "name": "daily-task-summary",
      "cron": "0 2 * * *",
      "timezone": "UTC",
      "skipIfRunning": true,
      "workflow": "./src/server/workflows/dailySummary.ts",
      "params": {
        "appId": "task-tracker"
      }
    }
  ]
}
Schedules are registered during the build pipeline and validated against the workflow definitions. For the full workflow DSL, step types, pagination, forEach, error handling, and worker configuration, see the Workflows Framework.