Skip to content

Latest commit

 

History

History
289 lines (237 loc) · 6.08 KB

File metadata and controls

289 lines (237 loc) · 6.08 KB
title Getting Started
description Build your first ObjectStack application in 5 minutes.

ObjectStack is a protocol-first platform. The @objectstack/spec package provides Zod schemas and strict TypeScript types to build valid metadata definitions.

## Initialize your project

You can start from scratch or add ObjectStack to an existing TypeScript project.

mkdir my-app
cd my-app
npm init -y
npm install typescript zod @objectstack/spec
npx tsc --init
## Define your first Object

Create a file named src/domains/crm/contact.object.ts. This is where the power of Zod-First Definition comes in. You get autocomplete and validation out of the box.

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

export const Contact = ObjectSchema.create({
  name: 'contact',
  label: 'Contact',
  pluralLabel: 'Contacts',
  icon: 'user',
  description: 'People associated with accounts',
  nameField: 'full_name',
  
  fields: {
    // Basic Information
    first_name: Field.text({ 
      label: 'First Name', 
      required: true,
      maxLength: 100,
    }),
    
    last_name: Field.text({ 
      label: 'Last Name', 
      required: true,
      maxLength: 100,
    }),
    
    // Formula field - automatically calculated
    full_name: Field.formula({ 
      label: 'Full Name',
      expression: 'CONCAT(first_name, " ", last_name)',
    }),
    
    // Contact Information
    email: Field.email({ 
      label: 'Email',
      unique: true,
    }),
    
    phone: Field.phone({ 
      label: 'Phone',
    }),
    
    // Selection with predefined options
    type: Field.select({
      label: 'Contact Type',
      options: [
        { label: 'Customer', value: 'customer', default: true },
        { label: 'Partner', value: 'partner' },
        { label: 'Vendor', value: 'vendor' },
      ],
    }),
    
    // Relationship to Account
    account: Field.masterDetail('account', {
      label: 'Account',
      required: true,
      deleteBehavior: 'cascade',
    }),
  },
  
  enable: {
    apiEnabled: true,
    trackHistory: true,
  }
});
## Add an Account Object

Create src/domains/crm/account.object.ts for the parent object:

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

export const Account = ObjectSchema.create({
  name: 'account',
  label: 'Account',
  pluralLabel: 'Accounts',
  icon: 'building',
  nameField: 'name',
  
  fields: {
    // Autonumber field
    account_number: Field.autonumber({
      label: 'Account Number',
      format: 'ACC-{0000}',
    }),
    
    name: Field.text({ 
      label: 'Account Name', 
      required: true,
      searchable: true,
      maxLength: 255,
    }),
    
    // Currency field
    annual_revenue: Field.currency({ 
      label: 'Annual Revenue',
      min: 0,
    }),
    
    // Select with custom colors (for kanban boards)
    type: Field.select({
      label: 'Account Type',
      options: [
        { label: 'Prospect', value: 'prospect', color: '#FFA500', default: true },
        { label: 'Customer', value: 'customer', color: '#00AA00' },
        { label: 'Partner', value: 'partner', color: '#0000FF' },
      ],
    }),
  },
  
  enable: {
    apiEnabled: true,
    trackHistory: true,
  }
});
## Create Application Manifest

Create objectstack.config.ts to bundle your objects into an app:

import { defineManifest } from '@objectstack/spec';
import { Account } from './src/domains/crm/account.object';
import { Contact } from './src/domains/crm/contact.object';

export default defineManifest({
  name: 'my_crm',
  label: 'My CRM',
  version: '1.0.0',
  description: 'Simple CRM application',
  
  objects: [Account, Contact],
  
  navigation: {
    tabs: [
      {
        label: 'Sales',
        items: [
          { type: 'object', object: 'account' },
          { type: 'object', object: 'contact' },
        ],
      },
    ],
  },
});
## Validate the Protocol

Create a build script src/build.ts to verify your definitions:

import config from '../objectstack.config';

// This will throw a ZodError if your schema is invalid
console.log(`✅ App '${config.label}' is valid!`);
console.log(`📦 Objects: ${config.objects.map(o => o.name).join(', ')}`);

// Export as JSON for runtime use
import fs from 'fs';
fs.writeFileSync(
  'dist/manifest.json', 
  JSON.stringify(config, null, 2)
);

Run it:

npx tsx src/build.ts
## Explore Advanced Features

Now that you have a working app, explore advanced features:

1. Add Validation Rules

validations: [
  {
    name: 'unique_email',
    type: 'unique',
    fields: ['email'],
    message: 'Email already exists',
  },
  {
    name: 'positive_revenue',
    type: 'script',
    expression: 'annual_revenue >= 0',
    message: 'Revenue must be positive',
  },
]

2. Add Workflow Rules

workflows: [
  {
    name: 'update_last_activity',
    trigger: 'on_update',
    actions: [
      {
        type: 'field_update',
        field: 'last_activity_date',
        value: 'TODAY()',
      },
    ],
  },
]

3. Configure Views

views: {
  list: {
    type: 'grid',
    columns: ['account_number', 'name', 'type', 'annual_revenue'],
    filters: [
      { field: 'type', operator: '=', value: 'customer' }
    ],
  },
  kanban: {
    type: 'kanban',
    groupBy: 'type',
    columns: ['name', 'annual_revenue'],
  },
}
## Next Steps

Now that you have valid metadata, you can:

  1. Explore Examples: Check out the CRM Example for a full-featured implementation
  2. Learn Field Types: See the Field Types Guide for all 30+ field types
  3. Build UI: Use the metadata with ObjectStack runtime to generate interfaces
  4. Deploy: Push to an ObjectStack kernel for production use

Additional Resources: