Events
System hook events, what triggers them, and what your handler is expected to return.
Filenames use kebab case (before-save.ts); the underlying event name uses underscores (before_save). They’re equivalent.
| Event | File | Triggered by | Return value |
|---|---|---|---|
before_save | before-save.ts | Entity create / update, before commit. | An object of fields to change, merged into the entity. null to skip. Throw to reject the write. |
after_save | after-save.ts | Entity create / update, after commit. | Ignored — side-effect only. |
before_post | before-post.ts | The “post” workflow transition (e.g., posting an invoice to the ledger), before commit. | Throw to abort. |
after_post | after-post.ts | Same workflow, after commit. | Ignored. |
before_delete | before-delete.ts | Entity destroy, before commit. | Throw to abort. |
after_delete | after-delete.ts | Entity destroy, after commit. | Ignored. |
before_approve | before-approve.ts | Approval transition, before commit. | Throw to abort. |
after_approve | after-approve.ts | Approval transition, after commit. | Ignored. |
recalculate | recalculate.ts | Draft recalculation while a user edits — fires synchronously on changes. | Calculation components and warnings. See Hooks → Recalculate. |
before_post, before_approve, and the matching after_* events only fire on entities whose workflow includes a post or approve transition (Invoice, Bill, JournalEntry, etc. — not all entities have these). If your hook isn’t firing, that’s the first thing to check.
Hook context
Save hooks receive a HookContext:
interface HookContext<T = any> {
entity: T; // entity AFTER the change (or proposed entity, in before-*)
entityType: string;
operation: 'create' | 'update' | 'delete';
previous: T | null; // entity before; null on create
changes: string[]; // names of fields actually modified
}
previous is null on create. changes lists field names — useful for short-circuiting in after_save:
if (!ctx.changes.includes("status")) return;
The recalculate hook’s context is different — see Hooks → Recalculate.