Create Your First Model

This tutorial walks through the first useful AuraBoot development loop: define a model, add fields, create commands, render a page, and verify the result in the browser. The example is intentionally small, but it uses the same concepts as larger CRM, ERP, and workflow modules.

You will build a simple Task module.

What you will create

ResourceCodePurpose
Modelpm_taskStores task records
Dictionarypm_task_statusControls task lifecycle values
Commandscreate_pm_task, update_pm_task, complete_pm_taskMutate task records safely
Pagepm_task_listDisplays tasks in a list
Permissionspm.task.*Controls access
Menupm_tasksAdds navigation

Step 1: Define status values

Create a dictionary for task status:

{
  "code": "pm_task_status",
  "name": "Task Status",
  "items": [
    { "code": "todo", "name": "To Do", "sortOrder": 1 },
    { "code": "in_progress", "name": "In Progress", "sortOrder": 2 },
    { "code": "done", "name": "Done", "sortOrder": 3 }
  ]
}

Use dictionaries for values that will appear in forms, filters, badges, dashboards, and workflows.

Step 2: Define the model

Create models/pm_task.json:

{
  "code": "pm_task",
  "name": "Task",
  "type": "entity",
  "description": "Simple project task",
  "fields": [
    { "code": "title", "name": "Title", "dataType": "text", "required": true },
    { "code": "description", "name": "Description", "dataType": "long_text" },
    { "code": "status", "name": "Status", "dataType": "dict", "dictCode": "pm_task_status", "required": true },
    { "code": "assignee", "name": "Assignee", "dataType": "reference", "refModelCode": "sys_user" },
    { "code": "due_date", "name": "Due Date", "dataType": "date" }
  ]
}

This model gives AuraBoot enough information to create storage, validate field types, and render controls.

Step 3: Create commands

Create a command for new tasks:

{
  "code": "create_pm_task",
  "name": "Create Task",
  "modelCode": "pm_task",
  "type": "create",
  "fields": [
    { "fieldCode": "title", "required": true },
    { "fieldCode": "description" },
    { "fieldCode": "status", "defaultValue": "todo", "readonly": true },
    { "fieldCode": "assignee" },
    { "fieldCode": "due_date" }
  ]
}

Create an update command:

{
  "code": "update_pm_task",
  "name": "Update Task",
  "modelCode": "pm_task",
  "type": "update",
  "fields": [
    { "fieldCode": "title", "required": true },
    { "fieldCode": "description" },
    { "fieldCode": "status" },
    { "fieldCode": "assignee" },
    { "fieldCode": "due_date" }
  ]
}

Create a state transition command:

{
  "code": "complete_pm_task",
  "name": "Complete Task",
  "modelCode": "pm_task",
  "type": "state_transition",
  "stateField": "status",
  "fromStates": ["todo", "in_progress"],
  "toState": "done"
}

The create command sets a default status. The complete command enforces a lifecycle rule instead of allowing any status update.

Step 4: Create a list page

Create pages/pm_task_list.json:

{
  "code": "pm_task_list",
  "name": "Tasks",
  "modelCode": "pm_task",
  "pageType": "list",
  "schema": {
    "searchFields": ["title", "description"],
    "toolbar": {
      "actions": [
        { "type": "command", "commandCode": "create_pm_task", "label": "New Task" }
      ]
    },
    "columns": [
      { "fieldCode": "title", "width": 260 },
      { "fieldCode": "status", "width": 140 },
      { "fieldCode": "assignee", "width": 160 },
      { "fieldCode": "due_date", "width": 140 },
      { "fieldCode": "updated_at", "width": 180 }
    ],
    "rowActions": [
      { "type": "command", "commandCode": "update_pm_task", "label": "Edit" },
      { "type": "command", "commandCode": "complete_pm_task", "label": "Complete" }
    ]
  }
}

Step 5: Register permissions and menu

Create permissions:

[
  { "code": "pm.task.view", "name": "View Tasks" },
  { "code": "pm.task.create", "name": "Create Tasks" },
  { "code": "pm.task.update", "name": "Update Tasks" },
  { "code": "pm.task.complete", "name": "Complete Tasks" }
]

Create menu entry:

[
  {
    "code": "pm_tasks",
    "name": "Tasks",
    "path": "/dynamic/pm_task_list",
    "permissionCode": "pm.task.view",
    "sortOrder": 100
  }
]

Step 6: Validate and publish

Run validation before import:

aura plugin validate plugins/project-tracker

Then publish:

aura plugin publish plugins/project-tracker --yes

Step 7: Verify in the browser

After publish:

  1. Refresh the application.
  2. Open the Tasks menu item.
  3. Create a task.
  4. Confirm it appears in the list.
  5. Edit the task.
  6. Complete the task and confirm the status changes to done.

If the menu is missing, check permissions and bootstrap assignments. If the page loads but columns are missing, check page field codes against the model.

What you learned

You created the core resources of an AuraBoot business module:

  • A model defines data.
  • A dictionary controls status values.
  • Commands define valid operations.
  • A page renders the model.
  • Permissions and menu entries make the module usable.

Next, read Config-only Plugins to package this into a reusable module.