From 1c754aea009dd7d52933b93e0bbd205eb28fae17 Mon Sep 17 00:00:00 2001 From: Oz Sayag Date: Mon, 9 Feb 2026 21:35:16 +0200 Subject: [PATCH 1/2] automations --- skills/base44-cli/SKILL.md | 22 +- skills/base44-cli/references/automations.md | 295 ++++++++++++++++++ .../base44-cli/references/functions-create.md | 17 +- 3 files changed, 331 insertions(+), 3 deletions(-) create mode 100644 skills/base44-cli/references/automations.md diff --git a/skills/base44-cli/SKILL.md b/skills/base44-cli/SKILL.md index 549634b..bc3e494 100644 --- a/skills/base44-cli/SKILL.md +++ b/skills/base44-cli/SKILL.md @@ -100,7 +100,7 @@ my-app/ │ ├── entities/ # Entity schema definitions │ │ ├── task.jsonc │ │ └── board.jsonc -│ ├── functions/ # Backend functions (optional) +│ ├── functions/ # Backend functions (optional); automations live in function.jsonc │ │ └── my-function/ │ │ ├── function.jsonc │ │ └── index.ts @@ -120,6 +120,7 @@ my-app/ **Key files:** - `base44/config.jsonc` - Project name, description, site build settings - `base44/entities/*.jsonc` - Data model schemas (see Entity Schema section) +- `base44/functions/*/function.jsonc` - Function config and optional `automations` (CRON, simple triggers, entity hooks) - `base44/agents/*.jsonc` - Agent configurations (optional) - `src/api/base44Client.js` - Pre-configured SDK client for frontend use @@ -237,7 +238,8 @@ For complete documentation, see [entities-create.md](references/entities-create. | Action / Command | Description | Reference | | ------------------------- | --------------------------------------------- | ------------------------------------------------------- | | Create Functions | Define functions in `base44/functions` folder | [functions-create.md](references/functions-create.md) | -| `base44 functions deploy` | Deploy local functions to Base44 | [functions-deploy.md](references/functions-deploy.md) | +| Configure Automations | CRON, simple triggers, entity hooks in `function.jsonc` | [automations.md](references/automations.md) | +| `base44 functions deploy` | Deploy local functions (and automations) to Base44 | [functions-deploy.md](references/functions-deploy.md) | ### Agent Management @@ -283,6 +285,22 @@ Agents are conversational AI assistants that can interact with users, access you - **Entity tools**: `entity_name` + `allowed_operations` (array of: `read`, `create`, `update`, `delete`) - **Backend function tools**: `function_name` + `description` +#### Automation Quick Reference + +Automations are triggers defined in the `automations` array inside `function.jsonc`. They deploy with the function via `base44 functions deploy`. Four types: + +**Common fields (all types):** `name` (required), `description`, `function_args`, `is_active` (default: true) + +**Scheduled One-Time:** `type: "scheduled"`, `schedule_mode: "one-time"`, `one_time_date` (ISO string) + +**Scheduled CRON:** `type: "scheduled"`, `schedule_mode: "recurring"`, `schedule_type: "cron"`, `cron_expression`, optional `ends_type` / `ends_on_date` / `ends_after_count` + +**Scheduled Simple:** `type: "scheduled"`, `schedule_mode: "recurring"`, `schedule_type: "simple"`, `repeat_unit` (`"minutes"` \| `"hours"` \| `"days"` \| `"weeks"` \| `"months"`), optional `repeat_interval`, `start_time`, `repeat_on_days` (0–6), `repeat_on_day_of_month` (1–31), `ends_type` / `ends_on_date` / `ends_after_count` + +**Entity Hook:** `type: "entity"`, `entity_name` (matches entity schema name), `event_types`: array of `"create"` \| `"update"` \| `"delete"` (at least one) + +For full schemas and examples, see [automations.md](references/automations.md). + ### Site Deployment | Command | Description | Reference | diff --git a/skills/base44-cli/references/automations.md b/skills/base44-cli/references/automations.md new file mode 100644 index 0000000..985bbd2 --- /dev/null +++ b/skills/base44-cli/references/automations.md @@ -0,0 +1,295 @@ +# Function Automations + +Automations are triggers attached to backend functions. They cause a function to run automatically on a schedule (CRON, simple interval, or one-time) or when entity data changes (create, update, delete). Automations are defined in the `automations` array inside each function's `function.jsonc` and are deployed together with the function via `npx base44 functions deploy`. + +## Overview + +- **Where**: `base44/functions//function.jsonc` — optional `automations` array +- **Deploy**: Automations are deployed with the function; no separate command +- **Types**: Scheduled (one-time, CRON, simple interval) and entity hooks + +## Common Fields (All Automation Types) + +Every automation shares these base fields: + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `name` | string | Yes | Display name for the automation (min 1 char) | +| `description` | string \| null | No | Optional description | +| `function_args` | object \| null | No | Key-value args passed to the function when it runs | +| `is_active` | boolean | No | Whether the automation is active (default: `true`) | + +## Automation Types + +### 1. Scheduled One-Time + +Runs the function once at a specific date/time. + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `type` | `"scheduled"` | Yes | Must be `"scheduled"` | +| `schedule_mode` | `"one-time"` | Yes | One-time execution | +| `one_time_date` | string | Yes | ISO date/time when the function should run | + +**Example:** + +```jsonc +{ + "name": "my-function", + "entry": "index.ts", + "automations": [ + { + "name": "Launch reminder", + "type": "scheduled", + "schedule_mode": "one-time", + "one_time_date": "2026-03-01T09:00:00.000Z", + "description": "One-time reminder on launch day" + } + ] +} +``` + +### 2. Scheduled CRON (Recurring) + +Runs the function on a cron schedule (e.g. daily at 9am, every Monday). + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `type` | `"scheduled"` | Yes | Must be `"scheduled"` | +| `schedule_mode` | `"recurring"` | Yes | Recurring execution | +| `schedule_type` | `"cron"` | Yes | Use cron expression | +| `cron_expression` | string | Yes | Standard cron expression (e.g. `0 9 * * *` = 9am daily) | +| `ends_type` | `"never"` \| `"on"` \| `"after"` | No | When the schedule stops (default: `"never"`) | +| `ends_on_date` | string \| null | No | When `ends_type` is `"on"`, ISO date to stop | +| `ends_after_count` | number \| null | No | When `ends_type` is `"after"`, number of runs then stop | + +**Cron format:** `minute hour day-of-month month day-of-week` (e.g. `0 9 * * *` = 9:00 UTC daily). + +**Example:** + +```jsonc +{ + "name": "daily-report", + "entry": "index.ts", + "automations": [ + { + "name": "Daily Report", + "type": "scheduled", + "schedule_mode": "recurring", + "schedule_type": "cron", + "cron_expression": "0 9 * * *", + "description": "Run every day at 9:00 UTC", + "is_active": true + } + ] +} +``` + +### 3. Scheduled Simple (Recurring Interval) + +Runs the function on a simple repeat (every N minutes/hours/days/weeks/months). + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `type` | `"scheduled"` | Yes | Must be `"scheduled"` | +| `schedule_mode` | `"recurring"` | Yes | Recurring execution | +| `schedule_type` | `"simple"` | Yes | Use simple interval | +| `repeat_unit` | `"minutes"` \| `"hours"` \| `"days"` \| `"weeks"` \| `"months"` | Yes | Unit of repetition | +| `repeat_interval` | number | No | Positive integer; interval within the unit (default 1) | +| `start_time` | string \| null | No | Time of day to run (e.g. `"09:00"`) | +| `repeat_on_days` | number[] \| null | No | For weeks: 0–6 (0 = Sunday, 6 = Saturday) | +| `repeat_on_day_of_month` | number \| null | No | For months: 1–31 | +| `ends_type` | `"never"` \| `"on"` \| `"after"` | No | When the schedule stops (default: `"never"`) | +| `ends_on_date` | string \| null | No | When `ends_type` is `"on"`, ISO date to stop | +| `ends_after_count` | number \| null | No | When `ends_type` is `"after"`, number of runs then stop | + +**Example:** + +```jsonc +{ + "name": "weekly-cleanup", + "entry": "index.ts", + "automations": [ + { + "name": "Weekly Cleanup", + "type": "scheduled", + "schedule_mode": "recurring", + "schedule_type": "simple", + "repeat_unit": "weeks", + "repeat_interval": 1, + "repeat_on_days": [1], + "start_time": "02:00", + "description": "Every Monday at 2:00" + } + ] +} +``` + +### 4. Entity Hook + +Runs the function when an entity record is created, updated, or deleted. + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `type` | `"entity"` | Yes | Must be `"entity"` | +| `entity_name` | string | Yes | Entity name (matches entity schema name, e.g. `Order`, `Task`) | +| `event_types` | `("create" \| "update" \| "delete")[]` | Yes | At least one; which events trigger the function | + +**Example:** + +```jsonc +{ + "name": "on-order-created", + "entry": "index.ts", + "automations": [ + { + "name": "On Order Created", + "type": "entity", + "entity_name": "Order", + "event_types": ["create"], + "description": "Run when a new order is created" + }, + { + "name": "On Order Update or Delete", + "type": "entity", + "entity_name": "Order", + "event_types": ["update", "delete"] + } + ] +} +``` + +**Note:** Entity names must match the entity schema `name` in `base44/entities/` (e.g. entity file `order.jsonc` with `"name": "Order"` → use `"entity_name": "Order"`). + +## Full Examples + +### Daily CRON report + +**base44/functions/daily-report/function.jsonc:** + +```jsonc +{ + "name": "daily-report", + "entry": "index.ts", + "automations": [ + { + "name": "Daily Report", + "type": "scheduled", + "schedule_mode": "recurring", + "schedule_type": "cron", + "cron_expression": "0 9 * * *", + "is_active": true + } + ] +} +``` + +**base44/functions/daily-report/index.ts:** + +```typescript +import { createClientFromRequest } from "npm:@base44/sdk"; + +Deno.serve(async (req) => { + const base44 = createClientFromRequest(req); + // Scheduled runs get auth context; use asServiceRole if you need full access + const base44Admin = base44.asServiceRole; + + const orders = await base44Admin.entities.Orders.list({ limit: 100 }); + const summary = { total: orders.length, date: new Date().toISOString() }; + + // e.g. send to Slack, email, or store in another entity + return Response.json({ success: true, summary }); +}); +``` + +### Entity hook: on order created + +**base44/functions/on-order-created/function.jsonc:** + +```jsonc +{ + "name": "on-order-created", + "entry": "index.ts", + "automations": [ + { + "name": "On Order Created", + "type": "entity", + "entity_name": "Order", + "event_types": ["create"], + "is_active": true + } + ] +} +``` + +**base44/functions/on-order-created/index.ts:** + +```typescript +import { createClientFromRequest } from "npm:@base44/sdk"; + +Deno.serve(async (req) => { + const base44 = createClientFromRequest(req); + // Request body contains entity hook payload (e.g. entity id, event type, changed data) + const payload = await req.json(); + + const { entity_id, event_type } = payload; + const order = await base44.asServiceRole.entities.Orders.get(entity_id); + + // e.g. send confirmation email, update inventory + return Response.json({ success: true, orderId: order?.id }); +}); +``` + +### Weekly cleanup (simple schedule) + +**base44/functions/weekly-cleanup/function.jsonc:** + +```jsonc +{ + "name": "weekly-cleanup", + "entry": "index.ts", + "automations": [ + { + "name": "Weekly Cleanup", + "type": "scheduled", + "schedule_mode": "recurring", + "schedule_type": "simple", + "repeat_unit": "weeks", + "repeat_interval": 1, + "repeat_on_days": [1], + "start_time": "02:00", + "description": "Every Monday at 2:00" + } + ] +} +``` + +## Common Patterns + +| Pattern | Use | Automation type | +|--------|-----|------------------| +| Daily report / digest | Email or Slack at 9am | CRON with `cron_expression`: `0 9 * * *` | +| On new record | Notify, sync, or validate when entity is created | Entity hook with `event_types`: `["create"]` | +| On update/delete | Audit, cache invalidation, or cleanup | Entity hook with `event_types`: `["update"]` or `["delete"]` | +| Weekly job | Cleanup or aggregation every Monday | Simple with `repeat_unit`: `"weeks"`, `repeat_on_days`: `[1]` | +| One-time run | Launch task or migration at a fixed time | One-time with `one_time_date` | + +## Deploying + +Automations are deployed with their function. There is no separate automation deploy command. + +```bash +npx base44 functions deploy +``` + +This deploys all functions in `base44/functions/` and their `automations` arrays. For more on deployment, see [functions-deploy.md](functions-deploy.md). + +## Common Mistakes + +| Wrong | Correct | Why | +|-------|---------|-----| +| `entity_name: "order"` when schema name is `Order` | `entity_name: "Order"` | Entity name must match schema `name` exactly | +| `event_types: []` or missing | `event_types: ["create"]` (at least one) | At least one event type is required for entity hooks | +| `schedule_type: "cron"` without `cron_expression` | Always set `cron_expression` for cron | Cron schedules require a valid cron expression | +| Putting automations in a separate file | Put `automations` inside `function.jsonc` | Automations are part of the function config | +| Expecting a separate `base44 automations deploy` | Use `npx base44 functions deploy` | Automations deploy with the function | diff --git a/skills/base44-cli/references/functions-create.md b/skills/base44-cli/references/functions-create.md index c523cdc..8efeb45 100644 --- a/skills/base44-cli/references/functions-create.md +++ b/skills/base44-cli/references/functions-create.md @@ -33,7 +33,17 @@ Each function requires a `function.jsonc` configuration file: ```jsonc { "name": "my-function", - "entry": "index.ts" + "entry": "index.ts", + // Optionally add automations + "automations": [ + { + "name": "Daily run", + "type": "scheduled", + "schedule_mode": "recurring", + "schedule_type": "cron", + "cron_expression": "0 9 * * *" + } + ] } ``` @@ -43,6 +53,11 @@ Each function requires a `function.jsonc` configuration file: |----------|-------------|----------| | `name` | Function name (must match `/^[^.]+$/` - no dots allowed) | Yes | | `entry` | Entry point file path relative to the function directory (min 1 char) | Yes | +| `automations` | Array of triggers (CRON, simple schedule, one-time, entity hooks); deployed with the function | No | + +## Automations + +Functions can define automations (triggers) so they run on a schedule or when entity data changes. Add an optional `automations` array to `function.jsonc`. Supported types: **scheduled** (one-time, CRON, or simple interval) and **entity hooks** (on entity create/update/delete). Automations are deployed with the function via `npx base44 functions deploy`. For full schemas and examples, see [automations.md](automations.md). ## Entry Point File From e34de393c33105738cf6aa43e07e084ddb9eefe3 Mon Sep 17 00:00:00 2001 From: Oz Sayag Date: Tue, 10 Feb 2026 13:16:36 +0200 Subject: [PATCH 2/2] fixes --- skills/base44-cli/references/automations.md | 78 +++++++++++++++++---- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/skills/base44-cli/references/automations.md b/skills/base44-cli/references/automations.md index 985bbd2..7028aa2 100644 --- a/skills/base44-cli/references/automations.md +++ b/skills/base44-cli/references/automations.md @@ -29,7 +29,7 @@ Runs the function once at a specific date/time. |----------|------|----------|-------------| | `type` | `"scheduled"` | Yes | Must be `"scheduled"` | | `schedule_mode` | `"one-time"` | Yes | One-time execution | -| `one_time_date` | string | Yes | ISO date/time when the function should run | +| `one_time_date` | string | Yes | ISO date/time when the function should run (e.g. `"2024-01-15T10:00:00"`) | **Example:** @@ -51,19 +51,29 @@ Runs the function once at a specific date/time. ### 2. Scheduled CRON (Recurring) -Runs the function on a cron schedule (e.g. daily at 9am, every Monday). +Runs the function on a cron schedule. **Minimum interval is 5 minutes.** | Property | Type | Required | Description | |----------|------|----------|-------------| | `type` | `"scheduled"` | Yes | Must be `"scheduled"` | | `schedule_mode` | `"recurring"` | Yes | Recurring execution | | `schedule_type` | `"cron"` | Yes | Use cron expression | -| `cron_expression` | string | Yes | Standard cron expression (e.g. `0 9 * * *` = 9am daily) | +| `cron_expression` | string | Yes | Standard cron: `minute hour day-of-month month day-of-week` | | `ends_type` | `"never"` \| `"on"` \| `"after"` | No | When the schedule stops (default: `"never"`) | | `ends_on_date` | string \| null | No | When `ends_type` is `"on"`, ISO date to stop | | `ends_after_count` | number \| null | No | When `ends_type` is `"after"`, number of runs then stop | -**Cron format:** `minute hour day-of-month month day-of-week` (e.g. `0 9 * * *` = 9:00 UTC daily). +**End conditions** (apply to both CRON and simple recurring): +- `ends_type="never"` — Run indefinitely (default) +- `ends_type="on"` — Run until a date: set `ends_on_date` (e.g. `"2024-12-31T23:59:59"`) +- `ends_type="after"` — Run N times: set `ends_after_count` (e.g. `10`) + +**Cron format:** `minute hour day-of-month month day-of-week` + +**Examples:** +- `"*/5 * * * *"` — every 5 minutes (minimum interval) +- `"0 9 * * *"` — 9am daily +- `"0 9 * * 1-5"` — 9am every weekday (Mon–Fri) **Example:** @@ -87,7 +97,7 @@ Runs the function on a cron schedule (e.g. daily at 9am, every Monday). ### 3. Scheduled Simple (Recurring Interval) -Runs the function on a simple repeat (every N minutes/hours/days/weeks/months). +Runs the function on a simple repeat (every N minutes/hours/days/weeks/months). **Minimum interval for minutes is 5** (e.g. every 5 minutes). | Property | Type | Required | Description | |----------|------|----------|-------------| @@ -95,14 +105,23 @@ Runs the function on a simple repeat (every N minutes/hours/days/weeks/months). | `schedule_mode` | `"recurring"` | Yes | Recurring execution | | `schedule_type` | `"simple"` | Yes | Use simple interval | | `repeat_unit` | `"minutes"` \| `"hours"` \| `"days"` \| `"weeks"` \| `"months"` | Yes | Unit of repetition | -| `repeat_interval` | number | No | Positive integer; interval within the unit (default 1) | -| `start_time` | string \| null | No | Time of day to run (e.g. `"09:00"`) | +| `repeat_interval` | number | No | Positive integer; interval within the unit (default 1). For minutes, minimum is 5. | +| `start_time` | string \| null | No | Time of day (e.g. `"09:00"`, `"00:00"`) | | `repeat_on_days` | number[] \| null | No | For weeks: 0–6 (0 = Sunday, 6 = Saturday) | | `repeat_on_day_of_month` | number \| null | No | For months: 1–31 | | `ends_type` | `"never"` \| `"on"` \| `"after"` | No | When the schedule stops (default: `"never"`) | | `ends_on_date` | string \| null | No | When `ends_type` is `"on"`, ISO date to stop | | `ends_after_count` | number \| null | No | When `ends_type` is `"after"`, number of runs then stop | +**End conditions:** Same as for CRON — `ends_type` / `ends_on_date` / `ends_after_count` (see Scheduled CRON above). + +**Simple schedule examples:** +- Every 5 minutes: `repeat_interval=5`, `repeat_unit="minutes"` (minimum) +- Hourly: `repeat_interval=1`, `repeat_unit="hours"` +- Daily at specific time: `repeat_interval=1`, `repeat_unit="days"`, `start_time="09:00"` +- Weekly on specific days: `repeat_unit="weeks"`, `repeat_on_days=[1, 5]`, `start_time="10:00"` (e.g. Mon and Fri) +- Monthly on specific day: `repeat_unit="months"`, `repeat_on_day_of_month=15`, `start_time="00:00"` + **Example:** ```jsonc @@ -127,7 +146,9 @@ Runs the function on a simple repeat (every N minutes/hours/days/weeks/months). ### 4. Entity Hook -Runs the function when an entity record is created, updated, or deleted. +Runs the function when entity records are created, updated, or deleted. + +**Required:** `entity_name`, `event_types` (array of `"create"`, `"update"`, `"delete"` — at least one). | Property | Type | Required | Description | |----------|------|----------|-------------| @@ -135,7 +156,13 @@ Runs the function when an entity record is created, updated, or deleted. | `entity_name` | string | Yes | Entity name (matches entity schema name, e.g. `Order`, `Task`) | | `event_types` | `("create" \| "update" \| "delete")[]` | Yes | At least one; which events trigger the function | -**Example:** +**Example use cases:** +- Send email on new order: `entity_name="Order"`, `event_types=["create"]` +- Track status changes: `entity_name="Order"`, `event_types=["update"]` +- Cleanup on delete: `entity_name="User"`, `event_types=["delete"]` +- Multiple events: `entity_name="Order"`, `event_types=["create", "update"]` + +**Example config:** ```jsonc { @@ -159,7 +186,20 @@ Runs the function when an entity record is created, updated, or deleted. } ``` -**Note:** Entity names must match the entity schema `name` in `base44/entities/` (e.g. entity file `order.jsonc` with `"name": "Order"` → use `"entity_name": "Order"`). +**Note:** `entity_name` must match the entity schema `name` in `base44/entities/` (e.g. entity file `order.jsonc` with `"name": "Order"` → use `"entity_name": "Order"`). + +#### Entity hook payload + +The function receives a JSON body with: + +| Field | Description | +|-------|-------------| +| `event` | `{ type, entity_name, entity_id }` — event type, entity name, and record id | +| `data` | Current entity data. `null` if `payload_too_large` is true | +| `old_data` | Previous entity data (only for `"update"` events). `null` if `payload_too_large` is true or for create/delete | +| `payload_too_large` | `true` when entity data exceeded 200KB and was omitted. Use the Base44 SDK to fetch: `await base44.entities..get(entity_id)` (or the dynamic API) to load the record. | + +**Authentication / user identity:** When an automation runs (scheduled or entity hook), the request is authenticated as the **user who created the automation**, not as the user who performed the action. So `await base44.auth.me()` returns the automation creator. **There is no way to get the user who triggered the entity change** (e.g. who created, updated, or deleted the record). If you need to attribute actions, store a user reference on the entity (e.g. `created_by`, `updated_by`) and read it from `data` / `old_data` in the payload. ## Full Examples @@ -229,14 +269,21 @@ import { createClientFromRequest } from "npm:@base44/sdk"; Deno.serve(async (req) => { const base44 = createClientFromRequest(req); - // Request body contains entity hook payload (e.g. entity id, event type, changed data) const payload = await req.json(); + const { event, data, old_data, payload_too_large } = payload; + + // event: { type, entity_name, entity_id } + const entityId = event.entity_id; + const eventType = event.type; - const { entity_id, event_type } = payload; - const order = await base44.asServiceRole.entities.Orders.get(entity_id); + // If payload was too large, data/old_data are null — fetch via SDK + let current = data; + if (payload_too_large && eventType !== "delete") { + current = await base44.asServiceRole.entities.Orders.get(entityId); + } - // e.g. send confirmation email, update inventory - return Response.json({ success: true, orderId: order?.id }); + // e.g. send confirmation email on create, or compare old_data vs data on update + return Response.json({ success: true, orderId: entityId, eventType }); }); ``` @@ -290,6 +337,7 @@ This deploys all functions in `base44/functions/` and their `automations` arrays |-------|---------|-----| | `entity_name: "order"` when schema name is `Order` | `entity_name: "Order"` | Entity name must match schema `name` exactly | | `event_types: []` or missing | `event_types: ["create"]` (at least one) | At least one event type is required for entity hooks | +| Assuming `base44.auth.me()` is the user who triggered the entity change | Use `data` / `old_data` (e.g. `created_by`, `updated_by`) if you need who did the action | In automations, `auth.me()` is the user who **created the automation**. The triggering user is not available. | | `schedule_type: "cron"` without `cron_expression` | Always set `cron_expression` for cron | Cron schedules require a valid cron expression | | Putting automations in a separate file | Put `automations` inside `function.jsonc` | Automations are part of the function config | | Expecting a separate `base44 automations deploy` | Use `npx base44 functions deploy` | Automations deploy with the function |