Hooks & pipelines
Server-side collection behavior lives in TypeScript beside each collection module. Hooks and
pipelines are declared on defineCollection() in collections/<name>/<name>.collection.ts — they compile into the build output
and run inside the runtime with full policy evaluation.
Hooks
Hooks react to collection lifecycle events: validation, side effects, and computed fields on
create, update, and delete. Add hooks.before / hooks.after under create, update, or delete on the collection definition.
import { defineCollection, text } from '@norbital-ai/pod/authoring';
export const payroll_runs = defineCollection('payroll_runs', {
table: { /* … */ },
create: {
input: { columns: { /* … */ } },
hooks: {
before: async ({ input, api }) => { /* validate */ return input; },
after: async ({ input, api }) => { /* side effects */ }
}
},
update: {
input: { columns: { /* … */ } },
hooks: {
before: async ({ input, existing, api }) => input
}
}
}); Register collections in collections/index.ts and include them in defineWorkspaceRegistry({ collections }) in workspace.ts.
Use hooks for business rules that must run on every mutation — generating related records,
recalculating totals, enforcing invariants, or calling external systems through facility bindings.
Reads inside hooks use api.<collection>.findMany({ where, with }) only; writes belong in automation/.
Pipelines
Pipelines handle bulk export and import flows for a collection. Add top-level export and import handlers on the same defineCollection() definition.
import { defineCollection } from '@norbital-ai/pod/authoring';
export const payroll_runs = defineCollection('payroll_runs', {
table: { /* … */ },
export: async (ctx, api) => {
const rows = await api.payroll_runs.findMany({ where: ctx.scope.where });
return [{ label: 'Export', attachments: [/* … */], delivery: { method: 'download' } }];
},
import: async (ctx, api) => {
/* parse ctx.scope.import_data → rows for upsert */
return parsedRows;
}
}); When to use which
- Hooks — per-record mutations, validation, side effects on standard routes
- Pipelines — structured export/import that reads many records and returns tabular output
- Automations — scheduled or manual background jobs not tied to a single mutation
- Remote functions — arbitrary server endpoints callable from apps or external clients