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
| Resource | Code | Purpose |
|---|---|---|
| Model | pm_task | Stores task records |
| Dictionary | pm_task_status | Controls task lifecycle values |
| Commands | create_pm_task, update_pm_task, complete_pm_task | Mutate task records safely |
| Page | pm_task_list | Displays tasks in a list |
| Permissions | pm.task.* | Controls access |
| Menu | pm_tasks | Adds 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-trackerThen publish:
aura plugin publish plugins/project-tracker --yesStep 7: Verify in the browser
After publish:
- Refresh the application.
- Open the Tasks menu item.
- Create a task.
- Confirm it appears in the list.
- Edit the task.
- 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.