AuraBoot's 20+ Stage Command Pipeline Explained
An inside look at AuraBoot's 20+ stage command pipeline — the engine behind data operations from CRUD to multi-step business transactions.
AuraBoot's 20+ Stage Command Pipeline Explained
Every time you create a record, update a status, or approve a workflow in AuraBoot, your operation passes through a 20+ stage pipeline. The point is not ceremony; it is to keep validation, permissions, side effects, audit, and integrations in one predictable path.
Why a Pipeline?
Traditional approaches scatter business logic across controllers, services, interceptors, and database triggers. When something goes wrong, you're debugging across four layers of code. When you need to add a validation, you're modifying service classes that handle dozens of operations.
AuraBoot's pipeline centralizes all data mutation logic into a single, ordered sequence. Each stage has a clear responsibility, runs in a defined order, and is configurable per-command through the DSL.
The Core Stages
Stage 1: Request Parsing
Raw HTTP request is parsed into a structured CommandRequest object. Field values are type-coerced to match the model definition. Unknown fields are rejected.
Stage 2: Authentication
Verifies the JWT token and resolves the current user, tenant, and session context. The MetaContext is populated and available to all subsequent stages.
Stage 3: Permission Check
The command's permissionCode is checked against the user's role assignments. AuraBoot supports:
- Model-level permissions (can this user access leads?)
- Command-level permissions (can this user convert leads?)
- Field-level permissions (can this user see the revenue field?)
Stage 4: Entitlement Check
For SaaS deployments, this stage verifies that the tenant's subscription tier allows the requested operation. A tenant on the Free plan might be limited to 1,000 records per model.
Stage 5: Pre-Validation
Schema-level validations run first: required fields, data type matching, length constraints, unique checks. These are fast, stateless checks that catch obvious errors before any business logic executes.
Stage 6: Field Defaults
Default values are computed and applied to missing fields:
{
"fieldDefaults": {
"status": "NEW",
"assigned_to": "${CURRENT_USER}",
"due_date": "${DATE_ADD(NOW, 7, 'DAY')}",
"code": "${AUTO_NUMBER('ORD', 6)}"
}
}
Expressions have access to the current user, tenant, record context, and built-in functions.
Stage 7: Business Validation
Custom validation rules that require business context:
{
"businessValidation": {
"rules": [
{
"field": "quantity",
"operator": "LTE",
"valueFrom": "product.stock_quantity",
"message": "Quantity exceeds available stock"
}
]
}
}
These rules can reference other models and perform cross-entity checks.
Stage 8: Computed Fields
Fields whose values derive from other fields:
{
"computedFields": {
"total_amount": "${quantity * unit_price}",
"tax_amount": "${total_amount * tax_rate}",
"grand_total": "${total_amount + tax_amount}"
}
}
The computation engine handles dependency ordering automatically.
Stage 9: Pre-Hooks
Extension point for custom Java logic that must run before the data mutation. Used sparingly — most logic should be declarative.
Stage 10: Confirmation
For destructive operations, the pipeline can pause and request user confirmation:
{
"confirmMessage": "$i18n:order.confirm_cancel"
}
Stage 11: Data Mutation
The actual database write. CREATE inserts a new record. UPDATE modifies existing fields. DELETE performs a soft delete (or hard delete for dynamic entities).
Stage 12: Post-Hooks
Extension point for custom logic after the mutation. Access to both the previous and current record state.
Stage 13: Side Effects
Declarative secondary operations triggered by the primary command:
{
"sideEffects": [
{
"type": "CREATE",
"targetModel": "activity_log",
"fieldMap": {
"entity_type": "order",
"entity_id": "${recordId}",
"action": "STATUS_CHANGED",
"description": "Order status changed to ${status}"
}
}
]
}
Side effects run in the same transaction, ensuring atomicity.
Stage 14: Roll-Up Aggregation
If the modified record is a child in a roll-up relationship, the parent's aggregated field is recalculated:
{
"feature": {
"rollUp": {
"childModel": "order_line",
"childField": "amount",
"childFk": "order_id",
"function": "SUM"
}
}
}
Supported functions: SUM, COUNT, AVG, MIN, MAX.
Stage 15: Linkage Effects
Frontend form linkage rules are evaluated — cascading dropdowns, conditional visibility, computed displays.
Stage 16: Audit Logging
Every mutation is recorded with the user, timestamp, operation type, changed fields, and previous values. Audit logs are immutable and tenant-scoped.
Stage 17: Cache Invalidation
Related caches are invalidated: model schema cache, named query results, dashboard aggregations, and any custom cache entries.
Stage 18: Event Publishing
An AuraEvent is published to the internal event bus. Listeners can react asynchronously to trigger notifications, webhooks, or downstream processing.
Stage 19: Webhook Dispatch
If configured, the event is dispatched to external webhook URLs with the full payload, supporting retry and dead-letter queuing.
Stage 20: Response
The pipeline returns a structured response with the created/updated record, any validation errors, and metadata.
Customizing the Pipeline
Not every command needs every stage. A simple status update might skip field defaults, computed fields, and confirmation. A complex financial transaction might add custom pre-hooks and additional business validations.
Each stage is enabled or disabled through the command's DSL configuration. No code changes required.
Real-World Example: Order Approval
Consider a purchase order approval workflow. The command DSL might look like:
{
"code": "purchase_order__submit_for_approval",
"modelCode": "purchase_order",
"actionType": "UPDATE",
"triggerMode": "DIRECT",
"permissionCode": "procurement:po:submit",
"businessValidation": {
"rules": [
{ "field": "status", "operator": "EQ", "value": "DRAFT", "message": "Only draft orders can be submitted" },
{ "field": "total_amount", "operator": "GT", "value": 0, "message": "Order must have line items" }
]
},
"fieldDefaults": {
"status": "PENDING_APPROVAL",
"submitted_at": "${NOW}",
"submitted_by": "${CURRENT_USER}"
},
"sideEffects": [
{
"type": "CREATE",
"targetModel": "approval_task",
"fieldMap": {
"entity_type": "purchase_order",
"entity_id": "${recordId}",
"approver": "${department_manager}",
"due_date": "${DATE_ADD(NOW, 3, 'DAY')}"
}
}
]
}
This single command definition:
- Checks the user has
procurement:po:submitpermission (Stage 3) - Validates the order is in DRAFT status and has items (Stage 7)
- Sets status, timestamp, and submitter (Stage 6)
- Saves the update (Stage 11)
- Creates an approval task for the department manager (Stage 13)
- Logs the entire operation for audit (Stage 16)
- Publishes an event for notifications (Stage 18)
Seven behaviors, zero lines of imperative code.
Error Handling
If any stage fails, the entire transaction rolls back. The client receives a structured error response indicating which stage failed and why. This makes debugging straightforward — you always know exactly where in the pipeline the problem occurred.
Conclusion
The 20+ stage pipeline is what separates AuraBoot from simple CRUD generators. It provides a shared path for permission checks, validation, auditing, event publishing, and extensions while keeping the behavior configurable through the DSL.
Learn more in our Command System documentation or try building your first command with the quick start guide.