Getting Started
Authoring
Access Control
Reference
Examples
Collections
Collections
Each domain collection is one directory at src/collections/<lower_snake_case_id>/. The directory name is the collection
ID; the model does not repeat it.
Model
import { defineModel, enums, text } from '@norbital-ai/pod/authoring';
export default defineModel(
{
name: text().notNull(),
status: enums({ values: ['active', 'complete'] })
},
{ description: 'Project site', record_label: 'scope.record.name', icon: 'lucide:map-pin' }
); Models carry zero presentation metadata — no .display(), importance, enumOptions, or defaultSort. Use enums({ values: string[] }) for closed value sets.
Save the declaration as src/collections/sites/+model.ts. System collections are
merged at build time and must not be redefined in tenant source.
Relationships
The single src/collections/+relationship.ts role defines relationships for the full registry
and uses its adjacent generated type.
import type { Relationships } from './$types.js';
export default ((r) => ({
sites: { site_visits: r.many.site_visits() },
site_visits: {
site: r.one.sites({ from: r.site_visits.site_id, to: r.sites.norbital_id })
}
})) satisfies Relationships; Companion roles
+hooks.ts— per-record validation and same-transaction side effects+pipelines.ts— canonical collection import/export behavior+integrations.ts— external receive/send bindings that reuse pipelines
Each role default-exports one declaration and uses the adjacent generated ./$types.js. No registration file is required.