Build a Custom Database

This guide implements a small project database. It assumes the Core Concepts and Schema Declarations mental model.

1. Create the declaration

import {
  Enums,
  bd,
  collection,
  createFormSchemaOrchestrator,
} from '@businessdash/sdk'

const ProjectStatus = Enums([
  'planned',
  'active',
  'complete',
] as const)

const clients = collection('clients', {
  visibility: 'private',
  labelIdentifierFieldName: 'name',
  fields: {
    name: bd
      .text()
      .required()
      .validate({ minLength: 2, maxLength: 120 }),
    email: bd
      .email()
      .optional()
      .formElement('email'),
  },
})

const projects = collection('projects', {
  visibility: 'private',
  labelIdentifierFieldName: 'title',
  fields: {
    title: bd
      .text()
      .required()
      .formElement('short_text')
      .validate({ minLength: 3, maxLength: 160 }),
    status: bd
      .enum(ProjectStatus)
      .default('planned')
      .formElement('dropdown'),
    budget: bd
      .number()
      .optional()
      .formElement('currency')
      .validate({ positive: true, round: 2 }),
    client: bd
      .relation()
      .references('clients')
      .onDelete('RESTRICT')
      .required(),
  },
})

export const definition = createFormSchemaOrchestrator([
  clients,
  projects,
])

export default definition.databaseSchema
export const projectFormTree = definition.uiFormTree

This implementation uses direct collections. SchemaBoundary is unnecessary unless the application needs feature tags, and no step or group is required.

2. Inspect the compiled artifact

npx bd print-data-model

Confirm:

  • both collections are present,
  • id fields were injected with the intended primary-key strategy,
  • projects.client resolved to the client collection,
  • field types, validation metadata, and form-element intent are correct.

3. Compare with Live

npx bd view-data-model --diff
npx bd sync-data-model --dry-run

The first command compares source with the promoted model. The second prints the migration proposal without creating a draft.

Review any:

  • removals,
  • type changes,
  • visibility changes,
  • identity changes that look like drop-and-add instead of rename.

4. Push a draft

npx bd sync-data-model \
  --note "Add clients and projects"

Promote the draft in:

Site Builder → Site Data → Database

The key proposes the change; a person controls promotion.

5. Seed records after promotion

Place convergent record files in bd-records/, then run:

npx bd sync-records --dry-run
npx bd sync-records

Relationship links use the record's separate relations object. Continue to Relationship Data for that two-pass workflow.

Extend this implementation

NeedContinue to
Add another stored typePrimitive Builders
Add defaults, indexes, or metadataField Modifiers
Add or debug constraintsValidation
Choose input componentsForm Elements
Add fixed choicesEnums
Add richer relationsRelationships and Extensions
Add steps, conditions, or repeatersUnified Form Orchestration
Review every CLI commandCollections and CLI Changes