@fleetbase/fleetops-engine 0.6.40 → 0.6.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,25 @@
1
1
  import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
2
3
 
3
- export default class OperationsRoute extends Route {}
4
+ export default class OperationsRoute extends Route {
5
+ @service('universe/menu-service') menuService;
6
+ @service universe;
7
+
8
+ beforeModel(transition) {
9
+ if (transition.intent && transition.intent.url) {
10
+ // Here we will check if it's an actual virtual route instead of operations
11
+ const intendedUrl = transition.intent.url;
12
+ const intentSegments = intendedUrl.split('/');
13
+ // Needs to match for section and slug
14
+ const section = intentSegments[2];
15
+ const slug = intentSegments[3];
16
+ // This is not a operations route check menu service for a virtual registration match
17
+ if (section !== 'operations') {
18
+ const menuItem = this.menuService.lookupMenuItem('engine:fleet-ops', slug, null, section);
19
+ if (menuItem) {
20
+ return this.universe.transitionMenuItem('console.fleet-ops.virtual', menuItem);
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
package/composer.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbase/fleetops-api",
3
- "version": "0.6.40",
3
+ "version": "0.6.41",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "keywords": [
6
6
  "fleetbase-extension",
package/extension.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Fleet-Ops",
3
- "version": "0.6.40",
3
+ "version": "0.6.41",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/fleetops",
6
6
  "license": "AGPL-3.0-or-later",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/fleetops-engine",
3
- "version": "0.6.40",
3
+ "version": "0.6.41",
4
4
  "description": "Fleet & Transport Management Extension for Fleetbase",
5
5
  "fleetbase": {
6
6
  "route": "fleet-ops"
@@ -0,0 +1,43 @@
1
+ <?php
2
+
3
+ use Illuminate\Database\Migrations\Migration;
4
+ use Illuminate\Database\Schema\Blueprint;
5
+ use Illuminate\Support\Facades\Schema;
6
+
7
+ /**
8
+ * Make `orchestrator_priority` nullable on the orders table.
9
+ *
10
+ * The original migration (2026_04_08_000003) added this column as NOT NULL
11
+ * with a database-level default of 50. When Eloquent explicitly passes NULL
12
+ * for the column (e.g. when a user submits the order form without filling in
13
+ * orchestrator constraints), the DB default is bypassed and MySQL raises:
14
+ *
15
+ * SQLSTATE[23000]: Integrity constraint violation: 1048
16
+ * Column 'orchestrator_priority' cannot be null
17
+ *
18
+ * This migration makes the column nullable so that existing installations
19
+ * that have already run the original migration are also protected. The
20
+ * application layer (Order model + controllers) already coerces null to 50,
21
+ * so NULL values will not appear in practice; the nullable flag is a
22
+ * belt-and-suspenders safety net for any code path that may have been missed.
23
+ */
24
+ return new class extends Migration {
25
+ public function up(): void
26
+ {
27
+ Schema::table('orders', function (Blueprint $table) {
28
+ $table->unsignedTinyInteger('orchestrator_priority')->default(50)->nullable()->change();
29
+ });
30
+ }
31
+
32
+ public function down(): void
33
+ {
34
+ // First back-fill any NULLs so the NOT NULL constraint can be restored.
35
+ \Illuminate\Support\Facades\DB::table('orders')
36
+ ->whereNull('orchestrator_priority')
37
+ ->update(['orchestrator_priority' => 50]);
38
+
39
+ Schema::table('orders', function (Blueprint $table) {
40
+ $table->unsignedTinyInteger('orchestrator_priority')->default(50)->nullable(false)->change();
41
+ });
42
+ }
43
+ };
@@ -299,6 +299,12 @@ class OrderController extends Controller
299
299
  $input['adhoc'] = Utils::isTrue($input['adhoc']) ? 1 : 0;
300
300
  }
301
301
 
302
+ // Ensure orchestrator_priority is never null — the column is NOT NULL
303
+ // and the DB default is bypassed when Eloquent receives an explicit null.
304
+ if (!isset($input['orchestrator_priority']) || !is_numeric($input['orchestrator_priority'])) {
305
+ $input['orchestrator_priority'] = 50;
306
+ }
307
+
302
308
  if (!isset($input['payload_uuid'])) {
303
309
  return response()->apiError('Attempted to attach invalid payload to order.');
304
310
  }
@@ -527,6 +533,12 @@ class OrderController extends Controller
527
533
  $order->dispatch();
528
534
  }
529
535
 
536
+ // Ensure orchestrator_priority is never null on update either —
537
+ // only apply the default when the key was explicitly sent as null/empty.
538
+ if (array_key_exists('orchestrator_priority', $input) && !is_numeric($input['orchestrator_priority'])) {
539
+ $input['orchestrator_priority'] = 50;
540
+ }
541
+
530
542
  // update the order
531
543
  $order->update($input);
532
544
  $order->flushAttributesCache();
@@ -126,6 +126,12 @@ class OrderController extends FleetOpsController
126
126
  $input['order_config_uuid'] = $defaultOrderConfig->uuid;
127
127
  }
128
128
  }
129
+
130
+ // Ensure orchestrator_priority is never null — the column is NOT NULL
131
+ // and the DB default is bypassed when Eloquent receives an explicit null.
132
+ if (!isset($input['orchestrator_priority']) || !is_numeric($input['orchestrator_priority'])) {
133
+ $input['orchestrator_priority'] = 50;
134
+ }
129
135
  },
130
136
  function (&$request, Order &$order, &$requestInput) {
131
137
  $input = $request->input('order');
@@ -219,6 +219,20 @@ class Order extends Model
219
219
  'orchestrator_priority' => 'integer',
220
220
  ];
221
221
 
222
+ /**
223
+ * The model's default attribute values.
224
+ *
225
+ * Ensures that `orchestrator_priority` is never persisted as NULL even when
226
+ * the caller omits the field entirely (e.g. the order/form component does
227
+ * not require the user to fill in orchestrator constraints). The value
228
+ * mirrors the database column default defined in the migration.
229
+ *
230
+ * @var array<string, mixed>
231
+ */
232
+ protected $attributes = [
233
+ 'orchestrator_priority' => 50,
234
+ ];
235
+
222
236
  /**
223
237
  * The attributes excluded from the model's JSON form.
224
238
  *
@@ -619,6 +633,18 @@ class Order extends Model
619
633
  return data_get($this, 'updatedBy.name');
620
634
  }
621
635
 
636
+ /**
637
+ * Set the orchestrator_priority attribute.
638
+ *
639
+ * Coerces null or non-numeric values to the default priority of 50 so that
640
+ * the NOT NULL database constraint is never violated when a user submits
641
+ * the order form without filling in the orchestrator constraints section.
642
+ */
643
+ public function setOrchestratorPriorityAttribute($value): void
644
+ {
645
+ $this->attributes['orchestrator_priority'] = is_numeric($value) ? (int) $value : 50;
646
+ }
647
+
622
648
  /**
623
649
  * Set the order type attribute, which defaults to `default`.
624
650
  */