Skip to content

Add business logic

Choose the smallest server-side mechanism that matches the behavior and keeps authorization, validation, and transactions consistent.

Application developers and reviewers.

An application with its tables, permissions, and metadata workflow defined.

Behavior Use
Record defaults or validation Hooks and data events
Pre/post lifecycle behavior Hooks and data events
Explicit user operation Function/action
Several related registrations Script
Bounded HTTP or email integration Async Function/action
Other native or reusable integration Reviewed TypeScript

Hooks and data events run inside the write transaction and must be synchronous; an async handler raises async lifecycle handlers are not supported. Anything that awaits belongs in an async Function. initValue runs when a user opens a new record as a draft, before any row exists; see Record lifecycle.

Execute related writes inside a transaction through DataContext. A transactional Function is synchronous and atomic. An async Function may await the built-in HTTP and email services, but it must use short explicit ctx.tts() blocks for database writes. Keep validation deterministic, never await network calls inside database transactions, and enforce authorization on the server even when the client hides an action.

Test success, rejection, rollback, unauthorized access, and concurrent behavior. See Run tests and debug.

Architecture · Record lifecycle · Testing