HotCRM Logo

Metadata Types Reference

Comprehensive guide to every metadata type in HotCRM — from objects and UI to automation, security, AI, and system configuration.

Metadata Types Reference

HotCRM follows a metadata-first architecture: every business object, UI layout, automation rule, security policy, and AI capability is defined in TypeScript using schemas from @objectstack/spec. This guide covers every metadata type available in the platform.

Why metadata-first? By defining everything as typed metadata, HotCRM enables runtime introspection, AI-powered tooling, visual builders, and zero-downtime schema evolution — all without writing raw SQL or imperative UI code.


File Suffix Protocol

Every metadata file follows a strict naming convention inside packages/{package}/src/:

SuffixPurposeSchema Source
*.object.tsData model (schema)@objectstack/spec/data
*.hook.tsServer-side business logic
*.action.tsAPI endpoints and AI tools
*.page.tsUI page layouts@objectstack/spec/ui
*.view.tsList view configurations@objectstack/spec/ui
*.form.tsForm view definitions@objectstack/spec/ui
*.dashboard.tsDashboard definitions@objectstack/spec/ui
*.report.tsReport definitions@objectstack/spec/ui
*.chart.tsChart configurations@objectstack/spec/ui
*.action_ui.tsUI action definitions@objectstack/spec/ui
*.widget.tsWidget manifests@objectstack/spec/ui
*.workflow.tsWorkflow rules@objectstack/spec/automation
*.flow.tsVisual process flows@objectstack/spec/automation
*.statemachine.tsState machine definitions@objectstack/spec/automation
*.connector.tsExternal connectors@objectstack/spec/automation
*.permission.tsPermission sets@objectstack/spec/security
*.sharing.tsSharing rules@objectstack/spec/security
*.security.tsRLS, password, and session policies@objectstack/spec/security
*.agent.tsAI agent definitions@objectstack/spec/ai
*.mcp.tsMCP tools, resources, and prompts@objectstack/spec/ai
*.orchestration.tsAI orchestrations@objectstack/spec/ai
*.predictive.tsPredictive ML models@objectstack/spec/ai
*.notification.tsEmail templates and channels@objectstack/spec/system
*.schedule.tsScheduled jobs@objectstack/spec/system

Data Model

Object Definitions (*.object.ts)

Objects are the foundation of HotCRM. Every business entity — accounts, opportunities, cases, invoices — is defined as an ObjectSchema.

import { ObjectSchema, Field } from '@objectstack/spec/data';

export const Account = ObjectSchema.create({
  name: 'account',
  label: 'Account',
  pluralLabel: 'Accounts',
  icon: 'building',
  description: 'Enterprise customer and organization management',

  fields: {
    name: Field.text({
      label: 'Account Name',
      required: true,
      unique: true,
      maxLength: 255
    }),
    type: Field.select({
      label: 'Account Type',
      options: [
        { label: 'Prospect', value: 'prospect' },
        { label: 'Customer', value: 'customer' },
        { label: 'Partner', value: 'partner' },
      ]
    }),
    annual_revenue: Field.currency({
      label: 'Annual Revenue',
      precision: 18,
      scale: 2
    }),
    primary_contact: Field.lookup({
      label: 'Primary Contact',
      referenceTo: 'contact'
    }),
  },

  features: {
    searchable: true,
    trackFieldHistory: true,
    enableActivities: true,
    enableDuplicateDetection: true
  }
});

Key field types:

RelationshipField TypeUsage
Optional associationField.lookup()Reference to another object
Required parent-childField.masterDetail()Cascade delete with parent
Aggregate child dataField.summary()Rollup (sum, count, min, max)
Data TypeField TypeUsage
Multiple choicesField.select({ multiple: true })Multi-select picklist
File uploadField.file()Document/attachment fields
Image uploadField.image()Photo/avatar fields
GPS coordinatesField.location()Geographic location data
Mailing addressField.address()Structured postal address

File: packages/crm/src/account.object.ts


UI Metadata

Pages (*.page.ts)

Page layouts define the structure of record detail pages with regions, components, tabs, and related lists.

import type { Page } from '@objectstack/spec/ui';
import { PageSchema } from '@objectstack/spec/ui';

export const AccountPage = {
  name: 'account_detail',
  object: 'account',
  type: 'record' as const,
  label: 'Account Detail Page',

  regions: [
    {
      name: 'header',
      components: [
        {
          type: 'record:highlights' as const,
          properties: {
            fields: ['name', 'type', 'industry', 'annual_revenue', 'phone']
          }
        }
      ]
    },
    {
      name: 'tabs',
      components: [
        {
          type: 'page:tabs' as const,
          properties: {
            tabs: ['account_info', 'address_info', 'additional_info']
          }
        }
      ]
    }
  ]
} satisfies Page;

File: packages/crm/src/account.page.ts

List Views (*.view.ts)

Views define how records are displayed in list format, including columns, sorting, bulk actions, and inline editing.

import type { View } from '@objectstack/spec/ui';
import { ViewSchema } from '@objectstack/spec/ui';

export const AllAccountsView = {
  list: {
    name: 'all_accounts',
    label: 'All Accounts',
    columns: [
      { field: 'name', width: 250, sortable: true, link: true },
      { field: 'type', width: 120, sortable: true },
      { field: 'industry', width: 150, sortable: true },
      { field: 'annual_revenue', width: 150, sortable: true, align: 'right' as const },
    ],
    sort: [{ field: 'name', order: 'asc' as const }],
    bulkActions: ['delete', 'update_owner', 'export'],
    inlineEdit: true,
    pagination: { pageSize: 25, pageSizeOptions: [10, 25, 50, 100] }
  }
} satisfies View;

File: packages/crm/src/account.view.ts

Forms (*.form.ts)

Form views define data entry layouts with sections, columns, and field-level validation.

import type { FormView } from '@objectstack/spec/ui';
import { FormViewSchema } from '@objectstack/spec/ui';

export const LeadForm = {
  type: 'simple' as const,
  data: {
    provider: 'object' as const,
    object: 'lead'
  },
  sections: [
    {
      label: 'Lead Information',
      columns: '2' as const,
      fields: [
        { field: 'first_name', required: true },
        { field: 'last_name', required: true },
        { field: 'company', required: true },
        { field: 'email', required: true },
        { field: 'phone' },
        { field: 'industry' },
        { field: 'lead_source' },
        { field: 'description', colSpan: 2 }
      ]
    }
  ]
} satisfies FormView;

File: packages/crm/src/lead.form.ts

Dashboards (*.dashboard.ts)

Dashboards define grid-based layouts of metric, chart, and list widgets.

import type { Dashboard } from '@objectstack/spec/ui';
import { DashboardSchema } from '@objectstack/spec/ui';

export const CrmDashboard = {
  name: 'crm_dashboard',
  label: 'Sales Dashboard',
  description: 'Key sales metrics and pipeline overview',
  widgets: [
    {
      title: 'Total Pipeline Value',
      type: 'metric' as const,
      object: 'opportunity',
      valueField: 'amount',
      aggregate: 'sum' as const,
      filter: ['stage', '!=', 'closed_lost'],
      layout: { x: 0, y: 0, w: 3, h: 2 }
    },
    {
      title: 'Open Deals',
      type: 'metric' as const,
      object: 'opportunity',
      aggregate: 'count' as const,
      filter: ['stage', '!=', 'closed_lost'],
      layout: { x: 3, y: 0, w: 3, h: 2 }
    }
  ]
} satisfies Dashboard;

File: packages/crm/src/crm.dashboard.ts

Reports (*.report.ts)

Reports define data queries with groupings, aggregations, filters, and embedded chart configurations.

import type { Report } from '@objectstack/spec/ui';
import { ReportSchema } from '@objectstack/spec/ui';

export const PipelineReport = {
  name: 'pipeline_report',
  label: 'Sales Pipeline Report',
  description: 'Sales pipeline analysis with stage breakdown, win rate, and average deal size',
  objectName: 'opportunity',
  type: 'summary' as const,
  columns: [
    { field: 'name', label: 'Deal Name' },
    { field: 'account_id', label: 'Account' },
    { field: 'amount', label: 'Amount', aggregate: 'sum' as const },
    { field: 'probability', label: 'Probability', aggregate: 'avg' as const },
    { field: 'close_date', label: 'Close Date' },
    { field: 'owner_id', label: 'Owner' }
  ],
  groupingsDown: [
    { field: 'stage', sortOrder: 'asc' as const }
  ],
  chart: {
    type: 'funnel' as const,
    title: 'Pipeline by Stage',
  }
} satisfies Report;

File: packages/crm/src/pipeline_report.report.ts

Charts (*.chart.ts)

Standalone chart configurations for dashboards, reports, and embedded analytics.

import type { ChartConfig } from '@objectstack/spec/ui';
import { ChartConfigSchema } from '@objectstack/spec/ui';

export const RevenueTrendChart = {
  type: 'line' as const,
  title: 'Monthly Revenue Trend',
  subtitle: 'Revenue performance over time',
  description: 'Line chart showing monthly revenue trends with period-over-period comparison',
  xAxis: { field: 'month', title: 'Month' },
  yAxis: [{ field: 'revenue', title: 'Revenue ($)' }],
  series: [
    { name: 'closed_won', label: 'Closed Won Revenue', color: '#22C55E' },
    { name: 'pipeline', label: 'Pipeline Value', color: '#3B82F6' }
  ],
  height: 350,
  showLegend: true,
  showDataLabels: false
} satisfies ChartConfig;

File: packages/crm/src/revenue_trend.chart.ts

UI Actions (*.action_ui.ts)

Quick actions define user-facing operations with modal interfaces and parameter forms.

import type { Action } from '@objectstack/spec/ui';
import { ActionSchema } from '@objectstack/spec/ui';

export const LogCallAction: Action = ActionSchema.parse({
  name: 'log_call',
  label: 'Log a Call',
  object: 'activity',
  type: 'modal' as const,
  icon: 'phone',
  description: 'Quickly log a phone call with outcome and follow-up',
  params: [
    { name: 'subject', label: 'Subject', type: 'text', required: true },
    { name: 'duration_minutes', label: 'Duration (min)', type: 'number', required: true },
    { name: 'outcome', label: 'Outcome', type: 'select',
      options: ['Connected', 'Left Voicemail', 'No Answer', 'Wrong Number'] },
    { name: 'notes', label: 'Notes', type: 'textarea' }
  ]
});

File: packages/crm/src/crm_actions.action_ui.ts

Widgets (*.widget.ts)

Custom widget manifests for embedding in dashboards and pages.

import type { WidgetManifest } from '@objectstack/spec/ui';
import { WidgetManifestSchema } from '@objectstack/spec/ui';

export const SlaWidget = {
  name: 'sla_compliance',
  label: 'SLA Compliance',
  description: 'Displays SLA compliance metrics with met, breached, and at-risk counts',
  version: '1.0.0',
  category: 'display' as const,
  icon: 'shield-check',
  properties: [
    { name: 'objectName', label: 'Object', type: 'string' as const,
      required: true, default: 'case' },
    { name: 'slaField', label: 'SLA Status Field', type: 'string' as const,
      required: true, default: 'sla_status' },
    { name: 'periodDays', label: 'Period (days)', type: 'number' as const,
      default: 30 },
    { name: 'targetPercent', label: 'Target %', type: 'number' as const,
      default: 95 }
  ]
} satisfies WidgetManifest;

File: packages/support/src/sla_widget.widget.ts


Automation

Workflow Rules (*.workflow.ts)

Declarative automation triggered by record events (create, update, delete).

import { WorkflowRuleSchema, type WorkflowRule } from '@objectstack/spec/automation';

export const LeadAutoAssignment = {
  name: 'lead_auto_assignment',
  label: 'Auto Assign New Leads',
  object: 'lead',
  description: 'Automatically assign new leads to the next available sales rep',

  triggerType: 'onCreate',
  condition: 'status = "new" AND owner = NULL',

  actions: [
    {
      type: 'fieldUpdate',
      field: 'owner_id',
      formula: 'getNextAvailableRep(territory, industry)',
      description: 'Assign to next rep in round-robin'
    },
    {
      type: 'fieldUpdate',
      field: 'assigned_date',
      value: 'NOW()'
    },
    {
      type: 'emailAlert',
      template: 'new_lead_assigned',
      recipients: ['${owner.email}']
    }
  ]
} satisfies WorkflowRule;

File: packages/crm/src/lead.workflow.ts

Flows (*.flow.ts)

Visual, multi-step process automation with variables, branching, and loops.

import type { Flow } from '@objectstack/spec/automation';
import { FlowSchema } from '@objectstack/spec/automation';

export const LeadQualificationFlow = {
  name: 'lead_qualification',
  label: 'Lead Qualification',
  description: 'Automatically score, route, assign, and notify reps for new leads',
  version: 1,
  status: 'active' as const,
  type: 'record_change' as const,
  variables: [
    { name: 'lead_id', type: 'string', isInput: true, isOutput: false },
    { name: 'lead_score', type: 'number', isInput: false, isOutput: true },
    { name: 'temperature', type: 'string', isInput: false, isOutput: true },
  ],
  nodes: [
    {
      id: 'start',
      type: 'start' as const,
      label: 'New Lead Created',
      config: { object: 'lead', trigger: 'after_create' },
      position: { x: 0, y: 0 },
    },
    // ... scoring, routing, assignment, notification nodes
  ]
} satisfies Flow;

File: packages/crm/src/lead_qualification.flow.ts

State Machines (*.statemachine.ts)

Finite state machines that enforce valid transitions, guards, and entry/exit actions.

import { StateMachineSchema, type StateMachineConfig } from '@objectstack/spec/automation';

export const LeadLifecycleStateMachine = {
  name: 'lead_lifecycle',
  label: 'Lead Lifecycle State Machine',
  object: 'lead',
  description: 'Manages lead states from capture through qualification to conversion',

  initial: 'new',

  states: [
    {
      name: 'new',
      label: 'New',
      onEntry: [
        { type: 'fieldUpdate', field: 'status', value: 'new' },
        { type: 'emailAlert', template: 'new_lead_notification',
          recipients: ['${owner.email}'] },
      ],
      transitions: [
        {
          to: 'contacted',
          event: 'contact',
          guard: 'owner != NULL',
          description: 'First outreach to lead has been made',
        }
      ]
    }
    // ... contacted, qualified, converted, disqualified states
  ]
} satisfies StateMachineConfig;

File: packages/crm/src/lead.statemachine.ts

Connectors (*.connector.ts)

External integration metadata defining authentication, endpoints, and field mappings.

import type { Connector } from '@objectstack/spec/automation';
import { ConnectorSchema } from '@objectstack/spec/automation';

export const EmailConnector = {
  id: 'email_connector',
  name: 'Email Connector',
  description: 'Integrates with Gmail and Outlook for email activity logging and sending.',
  version: '1.0.0',
  icon: 'mail',
  category: 'communication',
  baseUrl: 'https://api.email-provider.com/v1',
  authentication: {
    type: 'oauth2',
    fields: [
      { name: 'client_id', label: 'Client ID', type: 'text', required: true },
      { name: 'client_secret', label: 'Client Secret', type: 'password', required: true },
    ]
  },
  actions: [
    { name: 'send_email', label: 'Send Email', method: 'POST', path: '/messages/send' },
    { name: 'search_threads', label: 'Search Threads', method: 'GET', path: '/threads/search' },
  ]
} satisfies Connector;

File: packages/crm/src/email_connector.connector.ts


Security

Permission Sets (*.permission.ts)

Role-based access control defining object-level CRUD and field-level visibility.

import { PermissionSetSchema } from '@objectstack/spec/security';
import type { PermissionSet } from '@objectstack/spec/security';

const fullAccess = {
  allowCreate: true, allowRead: true, allowEdit: true, allowDelete: true,
  viewAllRecords: true, modifyAllRecords: true
};

const standardAccess = {
  allowCreate: true, allowRead: true, allowEdit: true, allowDelete: false,
  viewAllRecords: false, modifyAllRecords: false
};

export const CRMAdmin: PermissionSet = PermissionSetSchema.parse({
  name: 'crm_admin',
  label: 'CRM Administrator',
  isProfile: false,
  objects: {
    account: fullAccess,
    contact: fullAccess,
    opportunity: fullAccess,
    lead: fullAccess,
  }
});

File: packages/crm/src/crm.permission.ts

Sharing Rules (*.sharing.ts)

Criteria-based record sharing across roles and groups.

import { SharingRuleSchema } from '@objectstack/spec/security';
import type { SharingRule } from '@objectstack/spec/security';

export const AccountTeamSharing: SharingRule = SharingRuleSchema.parse({
  name: 'account_team_sharing',
  label: 'Share Customer Accounts with Sales Team',
  object: 'account',
  type: 'criteria',
  condition: "type = 'customer'",
  accessLevel: 'read',
  sharedWith: { type: 'role', value: 'sales_team' }
});

export const OpportunityDealSharing: SharingRule = SharingRuleSchema.parse({
  name: 'opportunity_deal_sharing',
  label: 'Share High-Value Opportunities with Deal Team',
  object: 'opportunity',
  type: 'criteria',
  condition: "amount > 100000 AND stage != 'closed_lost'",
  accessLevel: 'edit',
  sharedWith: { type: 'group', value: 'deal_team' }
});

File: packages/crm/src/crm.sharing.ts

Row-Level Security (*.security.ts — RLS)

Fine-grained record-level access policies based on user context.

import { RowLevelSecurityPolicySchema } from '@objectstack/spec/security';
import type { RowLevelSecurityPolicy } from '@objectstack/spec/security';

export const SalesRepAccountAccess: RowLevelSecurityPolicy =
  RowLevelSecurityPolicySchema.parse({
    name: 'sales_rep_account_access',
    label: 'Sales Rep — Own Accounts Only',
    object: 'account',
    role: 'sales_rep',
    condition: 'owner_id = $current_user_id',
    accessLevel: 'readWrite'
  });

File: packages/crm/src/crm_rls.security.ts

Password and Session Policies (*.security.ts)

Enterprise security configuration for authentication and session management.

import { PasswordPolicySchema } from '@objectstack/spec/security';

export const EnterprisePasswordPolicy = PasswordPolicySchema.parse({
  minLength: 12,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSymbols: true,
  expirationDays: 90,
  historyCount: 5,
  lockoutThreshold: 5,
  lockoutDurationMinutes: 30
});
import { SessionPolicySchema } from '@objectstack/spec/security';

export const EnterpriseSessionPolicy = SessionPolicySchema.parse({
  idleTimeoutMinutes: 30,
  absoluteTimeoutMinutes: 480,
  requireMfa: true,
  allowedIpRanges: ['10.0.0.0/8', '172.16.0.0/12'],
  secureCookies: true,
  sameSite: 'strict'
});

Files: packages/core/src/password_policy.security.ts, packages/core/src/session_policy.security.ts


AI and MCP

AI Agents (*.agent.ts)

Autonomous AI agents with system prompts, tool bindings, and guardrails.

export const SalesAssistantAgent = {
  name: 'sales_assistant',
  role: 'Sales AI Assistant',
  description: 'Intelligent sales assistant to help reps qualify leads and close deals',

  systemPrompt: `You are an expert sales assistant with deep CRM knowledge.
Your responsibilities:
1. Help sales representatives qualify leads efficiently
2. Provide insights on opportunities and suggest next best actions
3. Generate personalized outreach content

Tone: Professional, helpful, and results-oriented.`,

  tools: [
    {
      name: 'scoreLeads',
      description: 'Score leads based on fit, intent, and engagement signals',
      action: 'lead_scoring',
      parameters: {
        lead_id: { type: 'string', description: 'Lead record ID', required: true }
      }
    }
  ]
};

File: packages/crm/src/sales_assistant.agent.ts

MCP Tools (*.mcp.ts)

Tools exposed to AI models via the Model Context Protocol. See the MCP Integration Guide for full details.

import { MCPToolSchema } from '@objectstack/spec/ai';

export const SearchAccountsTool = MCPToolSchema.parse({
  name: 'search_accounts',
  description: 'Search CRM accounts by name, industry, or revenue range',
  inputSchema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'Search term' },
      industry: { type: 'string', description: 'Filter by industry' },
      minRevenue: { type: 'number', description: 'Minimum annual revenue' },
    },
    required: ['query']
  }
});

File: packages/crm/src/crm_mcp_tools.mcp.ts

MCP Resources (*.mcp.ts)

Read-only data endpoints exposed to AI for context retrieval.

import { MCPResourceSchema } from '@objectstack/spec/ai';

export const PipelineSummaryResource = MCPResourceSchema.parse({
  uri: 'hotcrm://crm/pipeline-summary',
  name: 'Pipeline Summary',
  description: 'Current pipeline stage distribution with velocity metrics',
  mimeType: 'application/json'
});

File: packages/crm/src/crm_mcp_resources.mcp.ts

MCP Prompts (*.mcp.ts)

Pre-built prompt templates for common AI interactions.

import { MCPPromptSchema } from '@objectstack/spec/ai';

export const DealAnalysisPrompt = MCPPromptSchema.parse({
  name: 'deal_analysis',
  description: 'Analyze deal health with risk assessment and close probability',
  arguments: [
    { name: 'opportunity_id', description: 'Opportunity to analyze', required: true }
  ]
});

File: packages/crm/src/crm_prompts.mcp.ts

AI Orchestrations (*.orchestration.ts)

Multi-step AI pipelines that chain tasks together with conditional logic.

import { AIOrchestrationSchema } from '@objectstack/spec/ai';

export const SalesOrchestration = AIOrchestrationSchema.parse({
  name: 'sales_deal_pipeline',
  label: 'Sales Deal Intelligence Pipeline',
  description: 'Multi-step AI analysis when opportunity stage changes',
  trigger: { type: 'record_change', object: 'opportunity', field: 'stage' },
  steps: [
    { id: 'classify_risk', type: 'ai_task', model: 'gpt-4o',
      prompt: 'Classify deal risk as low/medium/high based on: {{deal_summary}}' },
    { id: 'summarize', type: 'ai_task', model: 'gpt-4o',
      prompt: 'Generate a 3-sentence deal summary for: {{opportunity.name}}' },
    { id: 'recommend', type: 'ai_task', model: 'gpt-4o',
      prompt: 'Recommend the single best next action for this deal' },
  ],
  postActions: [
    { type: 'fieldUpdate', object: 'opportunity', field: 'risk_level',
      value: '{{classify_risk.output}}' }
  ],
  execution: { mode: 'sequential', timeoutSeconds: 120 }
});

File: packages/ai/src/sales_orchestration.orchestration.ts

Predictive Models (*.predictive.ts)

Machine learning model definitions for scoring and forecasting.

import { PredictiveModelSchema } from '@objectstack/spec/ai';

export const LeadScoringModel = PredictiveModelSchema.parse({
  name: 'lead_scoring',
  label: 'Lead Conversion Predictor',
  description: 'Gradient-boosting classifier predicting lead-to-opportunity conversion',
  object: 'lead',
  target: { field: 'is_converted', type: 'binary_classification' },
  features: [
    { field: 'industry', type: 'categorical' },
    { field: 'company_size', type: 'numerical' },
    { field: 'lead_source', type: 'categorical' },
    { field: 'engagement_score', type: 'numerical' },
    { field: 'email_opens', type: 'numerical' },
    { field: 'website_visits', type: 'numerical' },
  ],
  training: {
    algorithm: 'gradient_boosting',
    splitRatio: { train: 0.7, validation: 0.15, test: 0.15 },
    crossValidation: { folds: 5 },
    minRecords: 5000
  }
});

File: packages/ai/src/lead_scoring.predictive.ts


System

Email Templates (*.notification.ts)

Templated email content with merge variables for automated communications.

import { EmailTemplateSchema } from '@objectstack/spec/system';
import type { z } from 'zod';

type EmailTemplate = z.infer<typeof EmailTemplateSchema>;

export const welcomeEmail: EmailTemplate = EmailTemplateSchema.parse({
  id: 'welcome_email',
  subject: 'Welcome to {{company.name}}, {{account.name}}!',
  body: [
    '<h2>Welcome Aboard!</h2>',
    '<p>Dear {{contact.name}},</p>',
    '<p>Thank you for choosing {{company.name}}.</p>',
    '<p>Your dedicated account manager is {{owner.name}}.</p>',
  ].join('\n'),
  bodyType: 'html',
  variables: ['company.name', 'account.name', 'contact.name', 'owner.name']
});

File: packages/crm/src/crm_email_templates.notification.ts

Notification Channels (*.notification.ts)

Multi-channel notification delivery configuration.

import { NotificationChannelSchema } from '@objectstack/spec/system';

export const emailChannel = NotificationChannelSchema.parse('email');
export const smsChannel = NotificationChannelSchema.parse('sms');
export const pushChannel = NotificationChannelSchema.parse('push');
export const inAppChannel = NotificationChannelSchema.parse('in-app');

File: packages/core/src/notification_channels.notification.ts

Scheduled Jobs (*.schedule.ts)

Cron-based job definitions for background processing.

import { JobSchema } from '@objectstack/spec/system';
import type { z } from 'zod';

type Job = z.infer<typeof JobSchema>;

export const dailyRevenueRecognition: Job = JobSchema.parse({
  id: 'daily_revenue_recognition',
  name: 'daily_revenue_recognition',
  schedule: { type: 'cron', expression: '0 1 * * *', timezone: 'UTC' },
  handler: 'finance.recognize_revenue',
  enabled: true,
  retryPolicy: { maxRetries: 3, backoffMs: 5000 },
  timeout: 300000
});

File: packages/finance/src/finance_jobs.schedule.ts


Schema Validation Cheat Sheet

Every metadata file must be validated at definition time. Use the appropriate parse method:

// Data
ObjectSchema.create({ ... });            // @objectstack/spec/data

// UI
PageSchema.parse({ ... });               // @objectstack/spec/ui
ViewSchema.parse({ ... });               // @objectstack/spec/ui
FormViewSchema.parse({ ... });           // @objectstack/spec/ui
DashboardSchema.parse({ ... });          // @objectstack/spec/ui
ReportSchema.parse({ ... });             // @objectstack/spec/ui
ChartConfigSchema.parse({ ... });        // @objectstack/spec/ui
ActionSchema.parse({ ... });             // @objectstack/spec/ui
WidgetManifestSchema.parse({ ... });     // @objectstack/spec/ui

// Automation
WorkflowRuleSchema.parse({ ... });       // @objectstack/spec/automation
FlowSchema.parse({ ... });              // @objectstack/spec/automation
StateMachineSchema.parse({ ... });       // @objectstack/spec/automation
ConnectorSchema.parse({ ... });          // @objectstack/spec/automation

// Security
PermissionSetSchema.parse({ ... });      // @objectstack/spec/security
SharingRuleSchema.parse({ ... });        // @objectstack/spec/security
RowLevelSecurityPolicySchema.parse({}); // @objectstack/spec/security
PasswordPolicySchema.parse({ ... });     // @objectstack/spec/security
SessionPolicySchema.parse({ ... });      // @objectstack/spec/security

// AI
AgentSchema.parse({ ... });              // @objectstack/spec/ai
MCPToolSchema.parse({ ... });            // @objectstack/spec/ai
MCPResourceSchema.parse({ ... });        // @objectstack/spec/ai
MCPPromptSchema.parse({ ... });          // @objectstack/spec/ai
AIOrchestrationSchema.parse({ ... });    // @objectstack/spec/ai
PredictiveModelSchema.parse({ ... });    // @objectstack/spec/ai

// System
EmailTemplateSchema.parse({ ... });      // @objectstack/spec/system
NotificationChannelSchema.parse({ ... });// @objectstack/spec/system
JobSchema.parse({ ... });               // @objectstack/spec/system

Tip: Use satisfies for type-safe definitions without runtime parsing, or .parse() for runtime validation in production.

On this page