@fleetbase/fleetops-engine 0.6.69 → 0.6.70
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.
- package/RELEASE.md +41 -8
- package/addon/components/admin/telematics-settings.hbs +143 -0
- package/addon/components/admin/telematics-settings.js +145 -0
- package/addon/components/fuel-integration/hub.hbs +1 -1
- package/addon/components/layout/fleet-ops-sidebar.js +37 -17
- package/addon/components/map/leaflet-live-map.hbs +4 -242
- package/addon/components/map/leaflet-live-map.js +2 -1
- package/addon/components/map/marker-card/driver.hbs +57 -0
- package/addon/components/map/marker-card/driver.js +3 -0
- package/addon/components/map/marker-card/vehicle.hbs +78 -0
- package/addon/components/map/marker-card/vehicle.js +3 -0
- package/addon/components/telematic/hub.hbs +1 -1
- package/addon/components/widget/live-fleet.hbs +8 -40
- package/addon/controllers/analytics/reports/index.js +5 -0
- package/addon/controllers/connectivity/devices/index.js +4 -0
- package/addon/controllers/connectivity/fuel-providers/index.js +6 -4
- package/addon/controllers/connectivity/sensors/index.js +4 -0
- package/addon/controllers/connectivity/telematics/index.js +4 -0
- package/addon/controllers/maintenance/equipment/index.js +11 -4
- package/addon/controllers/maintenance/inspection-forms/index.js +2 -2
- package/addon/controllers/maintenance/inspection-submissions/index.js +8 -2
- package/addon/controllers/maintenance/maintenances/index.js +4 -0
- package/addon/controllers/maintenance/parts/index.js +11 -4
- package/addon/controllers/maintenance/schedules/index.js +17 -4
- package/addon/controllers/maintenance/work-orders/index.js +11 -4
- package/addon/controllers/management/contacts/index.js +4 -0
- package/addon/controllers/management/drivers/index.js +4 -0
- package/addon/controllers/management/fleets/index.js +4 -0
- package/addon/controllers/management/fuel-reports/index.js +4 -0
- package/addon/controllers/management/fuel-transactions/index.js +9 -7
- package/addon/controllers/management/issues/index.js +4 -0
- package/addon/controllers/management/places/index.js +4 -0
- package/addon/controllers/management/vehicles/index.js +4 -0
- package/addon/controllers/management/vendors/index.js +4 -0
- package/addon/controllers/operations/orders/index/details.js +30 -1
- package/addon/controllers/operations/orders/index.js +7 -0
- package/addon/controllers/operations/service-rates/index.js +3 -0
- package/addon/controllers/settings/index.js +13 -0
- package/addon/controllers/settings/telematics.js +113 -0
- package/addon/extension.js +38 -6
- package/addon/routes/analytics/index.js +14 -1
- package/addon/routes/analytics/reports/index/details.js +1 -1
- package/addon/routes/analytics/reports/index/edit.js +1 -1
- package/addon/routes/analytics/reports/index/new.js +14 -1
- package/addon/routes/analytics/reports.js +14 -1
- package/addon/routes/connectivity/devices/index/new.js +14 -1
- package/addon/routes/connectivity/devices.js +14 -1
- package/addon/routes/connectivity/events.js +14 -1
- package/addon/routes/connectivity/fuel-providers/details/transactions.js +12 -0
- package/addon/routes/connectivity/fuel-providers/details.js +9 -0
- package/addon/routes/connectivity/fuel-providers/edit.js +9 -0
- package/addon/routes/connectivity/fuel-providers/new.js +14 -1
- package/addon/routes/connectivity/fuel-providers.js +14 -1
- package/addon/routes/connectivity/sensors/index/new.js +14 -1
- package/addon/routes/connectivity/sensors.js +14 -1
- package/addon/routes/connectivity/telematics/new.js +14 -1
- package/addon/routes/connectivity/telematics.js +14 -1
- package/addon/routes/connectivity/tracking.js +14 -1
- package/addon/routes/maintenance/equipment/index/details.js +2 -2
- package/addon/routes/maintenance/equipment/index/edit.js +2 -2
- package/addon/routes/maintenance/equipment/index/new.js +14 -1
- package/addon/routes/maintenance/equipment.js +14 -1
- package/addon/routes/maintenance/index.js +14 -1
- package/addon/routes/maintenance/inspection-forms/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-forms/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-forms.js +14 -1
- package/addon/routes/maintenance/inspection-submissions/index/details.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/edit.js +10 -1
- package/addon/routes/maintenance/inspection-submissions/index/new.js +14 -1
- package/addon/routes/maintenance/inspection-submissions.js +14 -1
- package/addon/routes/maintenance/maintenances/index/details.js +2 -2
- package/addon/routes/maintenance/maintenances/index/edit.js +2 -2
- package/addon/routes/maintenance/maintenances/index/new.js +14 -1
- package/addon/routes/maintenance/maintenances.js +14 -1
- package/addon/routes/maintenance/parts/index/details.js +2 -2
- package/addon/routes/maintenance/parts/index/edit.js +2 -2
- package/addon/routes/maintenance/parts/index/new.js +14 -1
- package/addon/routes/maintenance/parts.js +14 -1
- package/addon/routes/maintenance/schedules/index/details.js +2 -2
- package/addon/routes/maintenance/schedules/index/edit.js +2 -2
- package/addon/routes/maintenance/schedules/index/new.js +15 -1
- package/addon/routes/maintenance/schedules.js +15 -1
- package/addon/routes/maintenance/work-orders/index/details.js +2 -2
- package/addon/routes/maintenance/work-orders/index/edit.js +2 -2
- package/addon/routes/maintenance/work-orders/index/new.js +14 -1
- package/addon/routes/maintenance/work-orders.js +14 -1
- package/addon/routes/management/fuel-transactions/index/details.js +9 -0
- package/addon/routes/management/fuel-transactions.js +14 -1
- package/addon/routes/management/index.js +13 -0
- package/addon/routes/management/trailers.js +16 -0
- package/addon/routes/management/vendors/integrated/details.js +14 -1
- package/addon/routes/management/vendors/integrated/edit.js +14 -1
- package/addon/routes/management/vendors/integrated/new.js +14 -1
- package/addon/routes/management/vendors/integrated.js +14 -1
- package/addon/routes/operations/orders.js +40 -1
- package/addon/routes/operations/routes/index/details.js +14 -1
- package/addon/routes/operations/routes/index/new.js +13 -0
- package/addon/routes/operations/routes.js +14 -1
- package/addon/routes/operations/service-rates/index/new.js +11 -0
- package/addon/routes/operations/service-rates.js +14 -1
- package/addon/routes/settings/avatars.js +14 -1
- package/addon/routes/settings/custom-fields.js +14 -1
- package/addon/routes/settings/map.js +14 -1
- package/addon/routes/settings/notifications.js +11 -0
- package/addon/routes/settings/orchestrator.js +1 -1
- package/addon/routes/settings/payments/index.js +1 -1
- package/addon/routes/settings/routing.js +14 -1
- package/addon/routes/settings/scheduling.js +14 -1
- package/addon/routes/settings/telematics.js +21 -0
- package/addon/routes/virtual.js +11 -0
- package/addon/routes.js +1 -0
- package/addon/templates/settings/telematics.hbs +70 -0
- package/app/components/admin/telematics-settings.js +1 -0
- package/app/components/map/marker-card/driver.js +1 -0
- package/app/components/map/marker-card/vehicle.js +1 -0
- package/app/controllers/settings/telematics.js +1 -0
- package/app/routes/settings/telematics.js +1 -0
- package/app/templates/settings/telematics.js +1 -0
- package/composer.json +2 -2
- package/docs/AFAQY.md +1 -1
- package/docs/TELEMATICS_QUEUES.md +1 -1
- package/docs/TELEMETRY_ARCHITECTURE.md +72 -1
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/config/telemetry.php +12 -0
- package/server/migrations/2026_09_23_000001_add_retention_index_to_device_events.php +40 -0
- package/server/migrations/2026_09_23_000002_add_retention_index_to_positions.php +40 -0
- package/server/migrations/2026_09_23_000003_add_retention_index_to_telematic_sync_runs.php +40 -0
- package/server/src/Auth/Schemas/FleetOps.php +104 -5
- package/server/src/Console/Commands/DrainTelematicInbox.php +3 -13
- package/server/src/Console/Commands/ProcessOperationalAlerts.php +3 -3
- package/server/src/Console/Commands/PruneTelematicsData.php +318 -0
- package/server/src/Http/Controllers/Api/v1/OrchestrationController.php +9 -0
- package/server/src/Http/Controllers/FleetOpsController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/AnalyticsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/ContactController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/CustomerController.php +14 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/DeviceEventController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/DriverController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderConnectionController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/FuelProviderTransactionController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/FuelReportController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/InspectionFormController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/LiveController.php +16 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MaintenanceScheduleController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/ManifestController.php +15 -0
- package/server/src/Http/Controllers/Internal/v1/MetricsController.php +11 -0
- package/server/src/Http/Controllers/Internal/v1/NavigatorController.php +42 -1
- package/server/src/Http/Controllers/Internal/v1/OrchestrationController.php +12 -0
- package/server/src/Http/Controllers/Internal/v1/OrderController.php +22 -0
- package/server/src/Http/Controllers/Internal/v1/PaymentController.php +13 -0
- package/server/src/Http/Controllers/Internal/v1/RadarController.php +19 -0
- package/server/src/Http/Controllers/Internal/v1/ServiceAreaController.php +9 -3
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +465 -14
- package/server/src/Http/Controllers/Internal/v1/TelematicController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/TrailerController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VehicleController.php +21 -0
- package/server/src/Http/Controllers/Internal/v1/VendorController.php +17 -0
- package/server/src/Http/Controllers/Internal/v1/WorkOrderController.php +11 -0
- package/server/src/Jobs/DispatchTelematicsRetentionJobs.php +70 -0
- package/server/src/Jobs/PruneTelematicsDataJob.php +74 -0
- package/server/src/Listeners/NotifyDriverOnShiftChange.php +3 -3
- package/server/src/Mail/CustomerCredentialsMail.php +1 -1
- package/server/src/Orchestration/Engines/VroomOrchestrationEngine.php +9 -1
- package/server/src/Providers/FleetOpsServiceProvider.php +3 -0
- package/server/src/Support/Analytics/LiveFleet.php +18 -2
- package/server/src/Support/Authorization.php +103 -0
- package/server/src/Support/Database/TableIndexes.php +66 -0
- package/server/src/Support/OrderTracker.php +2 -2
- package/server/src/Support/Reporting/FleetOpsReportSchema.php +476 -116
- package/server/src/Support/Telematics/Retention/RetentionPolicy.php +300 -0
- package/server/src/Support/Telematics/Retention/TelemetryActivity.php +40 -0
- package/server/src/Support/Telematics/TelematicService.php +12 -2
- package/server/src/Support/Telematics/Telemetry/Ingestor.php +4 -2
- package/server/src/Tracking/TrackingIntelligenceService.php +1 -1
- package/server/src/Tracking/TrackingOptions.php +2 -2
- package/server/src/Traits/AuthorizesMethods.php +37 -0
- package/server/src/routes.php +9 -1
- package/server/tests/AnalyticsRoutesTest.php +29 -2
- package/server/tests/Feature/Http/AfaqyRealtimeIngestionTest.php +16 -1
- package/server/tests/Feature/Http/Api/TelematicsRetentionIndexMigrationTest.php +115 -0
- package/server/tests/Feature/Http/Internal/SettingControllerHelpersTest.php +71 -0
- package/server/tests/Feature/Http/Internal/TelematicsStorageDeadlinesTest.php +119 -0
- package/server/tests/InternalImportExportControllerContractsTest.php +5 -8
- package/server/tests/NavigatorControllerContractsTest.php +36 -4
- package/server/tests/NotificationAndMailContractsTest.php +31 -0
- package/server/tests/ObserverContractsTest.php +1 -1
- package/server/tests/OrchestratorConsumableApiTest.php +42 -0
- package/server/tests/ProviderContractsTest.php +10 -0
- package/server/tests/ReportSchemaContractsTest.php +120 -6
- package/server/tests/SettingControllerContractsTest.php +429 -18
- package/server/tests/SmallControllerContractsTest.php +8 -5
- package/server/tests/Support/PruneTelematicsDataProbe.php +55 -0
- package/server/tests/Unit/Console/Commands/ProcessOperationalAlertsCommandTest.php +2 -2
- package/server/tests/Unit/Console/PruneTelematicsDataCommandTest.php +353 -0
- package/server/tests/Unit/Jobs/DispatchTelematicsRetentionJobsTest.php +114 -0
- package/server/tests/Unit/Jobs/PruneTelematicsDataJobTest.php +60 -0
- package/server/tests/Unit/Orchestration/VroomEngineTransportAndSettingsTest.php +20 -0
- package/server/tests/Unit/Support/Analytics/LiveFleetTest.php +6 -0
- package/server/tests/Unit/Support/AuthorizationTest.php +142 -0
- package/server/tests/Unit/Support/MaintainableAndOperationalAlertsTest.php +12 -1
- package/server/tests/Unit/Support/MoreQuerySeamsTest.php +11 -2
- package/server/tests/Unit/Support/Telematics/Retention/RetentionPolicyTest.php +190 -0
- package/server/tests/Unit/Support/Telematics/Retention/TelemetryActivityTest.php +68 -0
- package/server/tests/Unit/Tracking/TrackingOptionsCompanySettingsTest.php +109 -0
- package/translations/en-us.yaml +48 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\FleetOps\Console\Commands;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\FleetOps\Support\Telematics\Retention\RetentionPolicy;
|
|
6
|
+
use Illuminate\Console\Command;
|
|
7
|
+
use Illuminate\Support\Collection;
|
|
8
|
+
use Illuminate\Support\Facades\Cache;
|
|
9
|
+
use Illuminate\Support\Facades\DB;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Applies each company's telematics retention policy.
|
|
13
|
+
*
|
|
14
|
+
* Deletes are hard deletes issued in bounded batches so a large backlog never
|
|
15
|
+
* monopolizes the tables ingestion is writing to; a capped run picks up where
|
|
16
|
+
* it left off on the next schedule tick.
|
|
17
|
+
*/
|
|
18
|
+
class PruneTelematicsData extends Command
|
|
19
|
+
{
|
|
20
|
+
public const TABLES = ['device_events', 'positions', 'telematic_deliveries', 'telematic_sync_runs'];
|
|
21
|
+
|
|
22
|
+
public const LOCK = 'fleetops:prune-telematics-data';
|
|
23
|
+
|
|
24
|
+
protected $signature = 'fleetops:prune-telematics-data
|
|
25
|
+
{--company= : Only prune data for this company (uuid or public id)}
|
|
26
|
+
{--orphans-only : Only prune data without an existing company or connection}
|
|
27
|
+
{--table=* : Only prune these tables (device_events, positions, telematic_deliveries, telematic_sync_runs)}
|
|
28
|
+
{--batch-size=1000 : Rows per delete or update statement}
|
|
29
|
+
{--max-batches=50 : Maximum batches per table per company per run}
|
|
30
|
+
{--dry-run : Report matching rows without deleting or compacting}
|
|
31
|
+
{--no-lock : Skip process locking}';
|
|
32
|
+
|
|
33
|
+
protected $description = 'Prune telematics device events, positions, deliveries and sync runs according to each company\'s retention policy.';
|
|
34
|
+
|
|
35
|
+
protected int $batchSize = 1000;
|
|
36
|
+
protected int $maxBatches = 50;
|
|
37
|
+
protected bool $dryRun = false;
|
|
38
|
+
|
|
39
|
+
public function handle(): int
|
|
40
|
+
{
|
|
41
|
+
$tables = $this->requestedTables();
|
|
42
|
+
if ($tables === null) {
|
|
43
|
+
$this->error('Unknown table. Valid tables: ' . implode(', ', self::TABLES) . '.');
|
|
44
|
+
|
|
45
|
+
return self::FAILURE;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
$lock = null;
|
|
49
|
+
if (!$this->option('no-lock')) {
|
|
50
|
+
$lock = Cache::lock(self::LOCK, 840);
|
|
51
|
+
if (!$lock->get()) {
|
|
52
|
+
$this->warn('Another telematics prune run appears to be in progress.');
|
|
53
|
+
|
|
54
|
+
return self::SUCCESS;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Queue workers may have cached settings before an administrator saved a new policy.
|
|
60
|
+
RetentionPolicy::flush();
|
|
61
|
+
$this->batchSize = max(100, min(5000, (int) $this->option('batch-size') ?: 1000));
|
|
62
|
+
$this->maxBatches = max(1, (int) $this->option('max-batches') ?: 50);
|
|
63
|
+
$this->dryRun = (bool) $this->option('dry-run');
|
|
64
|
+
|
|
65
|
+
$only = ((string) $this->option('company')) ?: null;
|
|
66
|
+
$orphansOnly = (bool) $this->option('orphans-only');
|
|
67
|
+
if ($only && $orphansOnly) {
|
|
68
|
+
$this->error('Choose either --company or --orphans-only.');
|
|
69
|
+
|
|
70
|
+
return self::FAILURE;
|
|
71
|
+
}
|
|
72
|
+
$companies = $orphansOnly ? new Collection() : $this->companies($only);
|
|
73
|
+
if ($only && $companies->isEmpty()) {
|
|
74
|
+
$this->error(sprintf('Company [%s] was not found.', $only));
|
|
75
|
+
|
|
76
|
+
return self::FAILURE;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
$totals = $this->emptyStats();
|
|
80
|
+
foreach ($companies as $company) {
|
|
81
|
+
$stats = $this->pruneCompany($company->uuid, $this->policyFor($company->uuid), $tables);
|
|
82
|
+
$totals = $this->mergeStats($totals, $stats);
|
|
83
|
+
$this->report($company->public_id ?: $company->uuid, $stats);
|
|
84
|
+
}
|
|
85
|
+
if (!$only) {
|
|
86
|
+
$stats = $this->pruneOrphans($this->policyFor(null), $tables);
|
|
87
|
+
$totals = $this->mergeStats($totals, $stats);
|
|
88
|
+
$this->report('orphaned', $stats);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
$this->info(sprintf(
|
|
92
|
+
'%s: deleted=%d compacted=%d batches=%d%s',
|
|
93
|
+
$this->dryRun ? 'Telematics prune dry run' : 'Telematics prune complete',
|
|
94
|
+
$totals['deleted'],
|
|
95
|
+
$totals['compacted'],
|
|
96
|
+
$totals['batches'],
|
|
97
|
+
$totals['capped'] ? ' (capped; more rows remain for the next run)' : ''
|
|
98
|
+
));
|
|
99
|
+
|
|
100
|
+
return self::SUCCESS;
|
|
101
|
+
} finally {
|
|
102
|
+
$lock?->release();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @return string[]|null null when an unknown table was requested
|
|
108
|
+
*/
|
|
109
|
+
protected function requestedTables(): ?array
|
|
110
|
+
{
|
|
111
|
+
$requested = array_values(array_filter((array) $this->option('table')));
|
|
112
|
+
if ($requested === []) {
|
|
113
|
+
return self::TABLES;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return array_diff($requested, self::TABLES) === [] ? array_values(array_unique($requested)) : null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
protected function companies(?string $only): Collection
|
|
120
|
+
{
|
|
121
|
+
$query = DB::table('companies')->select(['id', 'uuid', 'public_id'])->orderBy('id');
|
|
122
|
+
if ($only) {
|
|
123
|
+
$query->where(fn ($where) => $where->where('uuid', $only)->orWhere('public_id', $only));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return $query->get();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
protected function policyFor(?string $companyUuid): RetentionPolicy
|
|
130
|
+
{
|
|
131
|
+
return RetentionPolicy::forCompany($companyUuid);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
protected function pruneCompany(string $companyUuid, RetentionPolicy $policy, array $tables): array
|
|
135
|
+
{
|
|
136
|
+
$rows = fn ($query) => $query->where('company_uuid', $companyUuid);
|
|
137
|
+
|
|
138
|
+
$telematics = null;
|
|
139
|
+
if (array_intersect(['telematic_deliveries', 'telematic_sync_runs'], $tables) !== []) {
|
|
140
|
+
// Inbox tables carry no company; trashed connections still prune under their company's policy.
|
|
141
|
+
$telematics = DB::table('telematics')->where('company_uuid', $companyUuid)->pluck('uuid')->all();
|
|
142
|
+
}
|
|
143
|
+
$inbox = $telematics ? fn ($query) => $query->whereIn('telematic_uuid', $telematics) : null;
|
|
144
|
+
|
|
145
|
+
return $this->prune($rows, $inbox, $policy, $tables);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Rows whose company or connection no longer exists fall back to the system defaults.
|
|
150
|
+
*/
|
|
151
|
+
protected function pruneOrphans(RetentionPolicy $policy, array $tables): array
|
|
152
|
+
{
|
|
153
|
+
$rows = fn ($query) => $query->where(function ($where) {
|
|
154
|
+
$where->whereNull('company_uuid')->orWhereNotIn('company_uuid', DB::table('companies')->select('uuid'));
|
|
155
|
+
});
|
|
156
|
+
$inbox = fn ($query) => $query->whereNotExists(function ($connections) use ($query) {
|
|
157
|
+
$connections->selectRaw('1')
|
|
158
|
+
->from('telematics')
|
|
159
|
+
->join('companies', 'companies.uuid', '=', 'telematics.company_uuid')
|
|
160
|
+
->whereColumn('telematics.uuid', $query->from . '.telematic_uuid');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
return $this->prune($rows, $inbox, $policy, $tables);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
protected function prune(\Closure $rows, ?\Closure $inbox, RetentionPolicy $policy, array $tables): array
|
|
167
|
+
{
|
|
168
|
+
$stats = $this->emptyStats();
|
|
169
|
+
if (in_array('device_events', $tables, true)) {
|
|
170
|
+
$stats['tables']['device_events'] = $this->pruneDeviceEvents($rows, $policy);
|
|
171
|
+
}
|
|
172
|
+
if (in_array('positions', $tables, true)) {
|
|
173
|
+
$stats['tables']['positions'] = $this->prunePositions($rows, $policy);
|
|
174
|
+
}
|
|
175
|
+
if ($inbox && in_array('telematic_deliveries', $tables, true)) {
|
|
176
|
+
$stats['tables']['telematic_deliveries'] = $this->pruneDeliveries($inbox, $policy);
|
|
177
|
+
}
|
|
178
|
+
if ($inbox && in_array('telematic_sync_runs', $tables, true)) {
|
|
179
|
+
$stats['tables']['telematic_sync_runs'] = $this->pruneSyncRuns($inbox, $policy);
|
|
180
|
+
}
|
|
181
|
+
foreach ($stats['tables'] as $table) {
|
|
182
|
+
$stats['deleted'] += $table['deleted'];
|
|
183
|
+
$stats['compacted'] += $table['compacted'];
|
|
184
|
+
$stats['batches'] += $table['batches'];
|
|
185
|
+
$stats['capped'] = $stats['capped'] || $table['capped'];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return $stats;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
protected function pruneDeviceEvents(\Closure $rows, RetentionPolicy $policy): array
|
|
192
|
+
{
|
|
193
|
+
$stats = $this->emptyTableStats();
|
|
194
|
+
$cutoff = $policy->cutoff('event_retention_days');
|
|
195
|
+
// Soft-deleted events only grow the table; purge them regardless of age.
|
|
196
|
+
$this->deleteInBatches('device_events', 'id', fn ($query) => $rows($query)->whereNotNull('deleted_at'), $stats);
|
|
197
|
+
if ($cutoff) {
|
|
198
|
+
$this->deleteInBatches('device_events', 'id', fn ($query) => $rows($query)->where('created_at', '<', $cutoff->toDateTimeString()), $stats);
|
|
199
|
+
}
|
|
200
|
+
if ($policy->compactsEvents() && ($compactAt = $policy->cutoff('event_compact_after_days'))) {
|
|
201
|
+
// Keep the event (type, severity, location, normalized data) but drop the raw provider blobs.
|
|
202
|
+
// Rows past the delete cutoff are left to the delete sweep rather than rewritten first.
|
|
203
|
+
$this->updateInBatches(
|
|
204
|
+
'device_events',
|
|
205
|
+
'id',
|
|
206
|
+
function ($query) use ($rows, $cutoff, $compactAt) {
|
|
207
|
+
$query = $rows($query)->where('created_at', '<', $compactAt->toDateTimeString())->where(fn ($where) => $where->whereNotNull('payload')->orWhereNotNull('meta'));
|
|
208
|
+
|
|
209
|
+
return $cutoff ? $query->where('created_at', '>=', $cutoff->toDateTimeString()) : $query;
|
|
210
|
+
},
|
|
211
|
+
['payload' => null, 'meta' => null],
|
|
212
|
+
$stats
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return $stats;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
protected function prunePositions(\Closure $rows, RetentionPolicy $policy): array
|
|
220
|
+
{
|
|
221
|
+
$stats = $this->emptyTableStats();
|
|
222
|
+
$this->deleteInBatches('positions', 'id', fn ($query) => $rows($query)->whereNotNull('deleted_at'), $stats);
|
|
223
|
+
if ($cutoff = $policy->cutoff('position_retention_days')) {
|
|
224
|
+
$this->deleteInBatches('positions', 'id', fn ($query) => $rows($query)->where('created_at', '<', $cutoff->toDateTimeString()), $stats);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return $stats;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
protected function pruneDeliveries(\Closure $inbox, RetentionPolicy $policy): array
|
|
231
|
+
{
|
|
232
|
+
$stats = $this->emptyTableStats();
|
|
233
|
+
foreach (['processed' => 'processed_retention_hours', 'quarantined' => 'quarantine_retention_days'] as $status => $key) {
|
|
234
|
+
if ($cutoff = $policy->cutoff($key)) {
|
|
235
|
+
$this->deleteInBatches('telematic_deliveries', 'uuid', fn ($query) => $inbox($query)->where('status', $status)->where('updated_at', '<', $cutoff->toDateTimeString()), $stats);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return $stats;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
protected function pruneSyncRuns(\Closure $inbox, RetentionPolicy $policy): array
|
|
243
|
+
{
|
|
244
|
+
$stats = $this->emptyTableStats();
|
|
245
|
+
if ($cutoff = $policy->cutoff('sync_run_retention_days')) {
|
|
246
|
+
// In-flight runs are recovered by the drain command, never expired here.
|
|
247
|
+
$this->deleteInBatches('telematic_sync_runs', 'uuid', fn ($query) => $inbox($query)->whereNotIn('status', ['fetching', 'ingesting'])->where('updated_at', '<', $cutoff->toDateTimeString()), $stats);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return $stats;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
protected function deleteInBatches(string $table, string $key, \Closure $scope, array &$stats): void
|
|
254
|
+
{
|
|
255
|
+
if ($this->dryRun) {
|
|
256
|
+
$stats['deleted'] += $scope(DB::table($table))->count();
|
|
257
|
+
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
for ($batch = 0; $batch < $this->maxBatches; $batch++) {
|
|
261
|
+
$ids = $scope(DB::table($table))->orderBy($key)->limit($this->batchSize)->pluck($key);
|
|
262
|
+
if ($ids->isEmpty()) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
$stats['batches']++;
|
|
266
|
+
$stats['deleted'] += DB::table($table)->whereIn($key, $ids->all())->delete();
|
|
267
|
+
}
|
|
268
|
+
$stats['capped'] = true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
protected function updateInBatches(string $table, string $key, \Closure $scope, array $values, array &$stats): void
|
|
272
|
+
{
|
|
273
|
+
if ($this->dryRun) {
|
|
274
|
+
$stats['compacted'] += $scope(DB::table($table))->count();
|
|
275
|
+
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
for ($batch = 0; $batch < $this->maxBatches; $batch++) {
|
|
279
|
+
$ids = $scope(DB::table($table))->orderBy($key)->limit($this->batchSize)->pluck($key);
|
|
280
|
+
if ($ids->isEmpty()) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
$stats['batches']++;
|
|
284
|
+
$stats['compacted'] += DB::table($table)->whereIn($key, $ids->all())->update($values);
|
|
285
|
+
}
|
|
286
|
+
$stats['capped'] = true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
protected function report(string $label, array $stats): void
|
|
290
|
+
{
|
|
291
|
+
foreach ($stats['tables'] as $table => $counts) {
|
|
292
|
+
if (!$counts['deleted'] && !$counts['compacted'] && !$counts['capped']) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
$this->info(sprintf('%s %s: deleted=%d compacted=%d batches=%d%s', $label, $table, $counts['deleted'], $counts['compacted'], $counts['batches'], $counts['capped'] ? ' capped' : ''));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
protected function emptyTableStats(): array
|
|
300
|
+
{
|
|
301
|
+
return ['deleted' => 0, 'compacted' => 0, 'batches' => 0, 'capped' => false];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
protected function emptyStats(): array
|
|
305
|
+
{
|
|
306
|
+
return ['deleted' => 0, 'compacted' => 0, 'batches' => 0, 'capped' => false, 'tables' => []];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
protected function mergeStats(array $totals, array $stats): array
|
|
310
|
+
{
|
|
311
|
+
$totals['deleted'] += $stats['deleted'];
|
|
312
|
+
$totals['compacted'] += $stats['compacted'];
|
|
313
|
+
$totals['batches'] += $stats['batches'];
|
|
314
|
+
$totals['capped'] = $totals['capped'] || $stats['capped'];
|
|
315
|
+
|
|
316
|
+
return $totals;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Api\v1;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Controllers\Internal\v1\OrchestrationController as InternalOrchestrationController;
|
|
6
|
+
use Fleetbase\FleetOps\Orchestration\OrchestrationEngineRegistry;
|
|
6
7
|
use Illuminate\Http\JsonResponse;
|
|
7
8
|
use Illuminate\Http\Request;
|
|
8
9
|
|
|
@@ -14,6 +15,14 @@ use Illuminate\Http\Request;
|
|
|
14
15
|
*/
|
|
15
16
|
class OrchestrationController extends InternalOrchestrationController
|
|
16
17
|
{
|
|
18
|
+
public function __construct(OrchestrationEngineRegistry $registry)
|
|
19
|
+
{
|
|
20
|
+
// The fleetbase.api route group authenticates API credentials and establishes
|
|
21
|
+
// their company scope. Console IAM middleware belongs to the internal
|
|
22
|
+
// workbench, not to these organization-credential endpoints.
|
|
23
|
+
$this->registry = $registry;
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
public function run(Request $request): JsonResponse
|
|
18
27
|
{
|
|
19
28
|
return $this->publicResponse(parent::run($request));
|
|
@@ -2,12 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\FleetOps\Traits\AuthorizesMethods;
|
|
5
6
|
use Fleetbase\Http\Controllers\FleetbaseController;
|
|
7
|
+
use Illuminate\Database\Eloquent\Model;
|
|
6
8
|
|
|
7
9
|
class FleetOpsController extends FleetbaseController
|
|
8
10
|
{
|
|
11
|
+
use AuthorizesMethods;
|
|
12
|
+
|
|
9
13
|
/**
|
|
10
14
|
* The package namespace used to resolve from.
|
|
11
15
|
*/
|
|
12
16
|
public string $namespace = '\\Fleetbase\\FleetOps';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Explicit permissions for custom actions, keyed by controller method, e.g.
|
|
20
|
+
* `['bulkDispatch' => 'dispatch order']`. Those methods also carry
|
|
21
|
+
* `#[SkipAuthorizationCheck]` so AuthorizationGuard does not demand the
|
|
22
|
+
* permission it would otherwise infer from the HTTP verb.
|
|
23
|
+
*
|
|
24
|
+
* @var array<string, string|string[]>
|
|
25
|
+
*/
|
|
26
|
+
protected array $methodPermissions = [];
|
|
27
|
+
|
|
28
|
+
public function __construct(?Model $model = null, ?string $resource = null)
|
|
29
|
+
{
|
|
30
|
+
parent::__construct($model, $resource);
|
|
31
|
+
|
|
32
|
+
$this->authorizeMethods($this->methodPermissions);
|
|
33
|
+
}
|
|
13
34
|
}
|
|
@@ -14,6 +14,7 @@ use Fleetbase\FleetOps\Support\Analytics\OperationsPulse;
|
|
|
14
14
|
use Fleetbase\FleetOps\Support\Analytics\OrdersByStatus;
|
|
15
15
|
use Fleetbase\FleetOps\Support\Analytics\RevenueTrend;
|
|
16
16
|
use Fleetbase\FleetOps\Support\Analytics\TopDrivers;
|
|
17
|
+
use Fleetbase\FleetOps\Support\Authorization;
|
|
17
18
|
use Fleetbase\Http\Controllers\Controller;
|
|
18
19
|
use Illuminate\Http\Request;
|
|
19
20
|
|
|
@@ -28,6 +29,16 @@ use Illuminate\Http\Request;
|
|
|
28
29
|
*/
|
|
29
30
|
class AnalyticsController extends Controller
|
|
30
31
|
{
|
|
32
|
+
public function __construct()
|
|
33
|
+
{
|
|
34
|
+
// Not a resource controller, so AuthorizationGuard cannot resolve a permission for it.
|
|
35
|
+
$this->middleware(function ($request, $next) {
|
|
36
|
+
Authorization::authorize('view analytics');
|
|
37
|
+
|
|
38
|
+
return $next($request);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
public function operationsPulse(Request $request)
|
|
32
43
|
{
|
|
33
44
|
return $this->run($request, OperationsPulse::class);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Attributes\SkipAuthorizationCheck;
|
|
5
6
|
use Fleetbase\FleetOps\Exports\ContactExport;
|
|
6
7
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
7
8
|
use Fleetbase\FleetOps\Http\Resources\v1\Vendor as VendorResource;
|
|
@@ -26,6 +27,15 @@ use Maatwebsite\Excel\Facades\Excel;
|
|
|
26
27
|
|
|
27
28
|
class ContactController extends FleetOpsController
|
|
28
29
|
{
|
|
30
|
+
/**
|
|
31
|
+
* Permissions for methods AuthorizationGuard cannot map to a schema action (see FleetOpsController).
|
|
32
|
+
*
|
|
33
|
+
* @var array<string, string|string[]>
|
|
34
|
+
*/
|
|
35
|
+
protected array $methodPermissions = [
|
|
36
|
+
'convertToVendor' => 'create vendor',
|
|
37
|
+
];
|
|
38
|
+
|
|
29
39
|
/**
|
|
30
40
|
* The resource to query.
|
|
31
41
|
*
|
|
@@ -108,6 +118,7 @@ class ContactController extends FleetOpsController
|
|
|
108
118
|
]);
|
|
109
119
|
}
|
|
110
120
|
|
|
121
|
+
#[SkipAuthorizationCheck]
|
|
111
122
|
public function convertToVendor(Request $request, string $id)
|
|
112
123
|
{
|
|
113
124
|
$contact = $this->contactForVendorConversion($id);
|
|
@@ -5,6 +5,7 @@ namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
|
5
5
|
use Fleetbase\FleetOps\Mail\CustomerCredentialsMail;
|
|
6
6
|
use Fleetbase\FleetOps\Models\Contact;
|
|
7
7
|
use Fleetbase\FleetOps\Support\ProfileAccountManager;
|
|
8
|
+
use Fleetbase\FleetOps\Traits\AuthorizesMethods;
|
|
8
9
|
use Fleetbase\Http\Controllers\Controller;
|
|
9
10
|
use Fleetbase\Models\User;
|
|
10
11
|
use Illuminate\Http\Request;
|
|
@@ -13,6 +14,19 @@ use Illuminate\Support\Str;
|
|
|
13
14
|
|
|
14
15
|
class CustomerController extends Controller
|
|
15
16
|
{
|
|
17
|
+
use AuthorizesMethods;
|
|
18
|
+
|
|
19
|
+
public function __construct()
|
|
20
|
+
{
|
|
21
|
+
$this->authorizeMethods([
|
|
22
|
+
'createPortalLogin' => 'reset-credentials-for customer',
|
|
23
|
+
'sendCredentials' => 'reset-credentials-for customer',
|
|
24
|
+
'deactivatePortalLogin' => 'reset-credentials-for customer',
|
|
25
|
+
'reactivatePortalLogin' => 'reset-credentials-for customer',
|
|
26
|
+
'resetCredentials' => 'reset-credentials-for customer',
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
|
|
16
30
|
public function createPortalLogin(Request $request)
|
|
17
31
|
{
|
|
18
32
|
$customer = $this->resolveCustomer($request);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Attributes\SkipAuthorizationCheck;
|
|
5
6
|
use Fleetbase\FleetOps\Exceptions\DeviceAlreadyAttachedException;
|
|
6
7
|
use Fleetbase\FleetOps\Exports\DeviceExport;
|
|
7
8
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
@@ -17,6 +18,16 @@ use Maatwebsite\Excel\Facades\Excel;
|
|
|
17
18
|
|
|
18
19
|
class DeviceController extends FleetOpsController
|
|
19
20
|
{
|
|
21
|
+
/**
|
|
22
|
+
* Permissions for methods AuthorizationGuard cannot map to a schema action (see FleetOpsController).
|
|
23
|
+
*
|
|
24
|
+
* @var array<string, string|string[]>
|
|
25
|
+
*/
|
|
26
|
+
protected array $methodPermissions = [
|
|
27
|
+
'attach' => 'update device',
|
|
28
|
+
'detach' => 'update device',
|
|
29
|
+
];
|
|
30
|
+
|
|
20
31
|
/**
|
|
21
32
|
* The resource to query.
|
|
22
33
|
*
|
|
@@ -110,6 +121,7 @@ class DeviceController extends FleetOpsController
|
|
|
110
121
|
/**
|
|
111
122
|
* Attach a device to a supported FleetOps resource.
|
|
112
123
|
*/
|
|
124
|
+
#[SkipAuthorizationCheck]
|
|
113
125
|
public function attach(Request $request, string $id): JsonResponse
|
|
114
126
|
{
|
|
115
127
|
$request->validate([
|
|
@@ -152,6 +164,7 @@ class DeviceController extends FleetOpsController
|
|
|
152
164
|
/**
|
|
153
165
|
* Detach a device from its current FleetOps resource.
|
|
154
166
|
*/
|
|
167
|
+
#[SkipAuthorizationCheck]
|
|
155
168
|
public function detach(string $id): JsonResponse
|
|
156
169
|
{
|
|
157
170
|
$device = $this->resolveDevice($id);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Attributes\SkipAuthorizationCheck;
|
|
5
6
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
7
|
use Fleetbase\FleetOps\Models\DeviceEvent;
|
|
7
8
|
use Fleetbase\FleetOps\Support\Utils;
|
|
@@ -9,6 +10,15 @@ use Illuminate\Http\JsonResponse;
|
|
|
9
10
|
|
|
10
11
|
class DeviceEventController extends FleetOpsController
|
|
11
12
|
{
|
|
13
|
+
/**
|
|
14
|
+
* Permissions for methods AuthorizationGuard cannot map to a schema action (see FleetOpsController).
|
|
15
|
+
*
|
|
16
|
+
* @var array<string, string|string[]>
|
|
17
|
+
*/
|
|
18
|
+
protected array $methodPermissions = [
|
|
19
|
+
'markProcessed' => 'update device-event',
|
|
20
|
+
];
|
|
21
|
+
|
|
12
22
|
/**
|
|
13
23
|
* The resource to query.
|
|
14
24
|
*
|
|
@@ -51,6 +61,7 @@ class DeviceEventController extends FleetOpsController
|
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
|
|
64
|
+
#[SkipAuthorizationCheck]
|
|
54
65
|
public function markProcessed(string $id): JsonResponse
|
|
55
66
|
{
|
|
56
67
|
$deviceEvent = DeviceEvent::where('company_uuid', session('company'))
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Attributes\SkipAuthorizationCheck;
|
|
5
6
|
use Fleetbase\Exceptions\FleetbaseRequestValidationException;
|
|
6
7
|
use Fleetbase\FleetOps\Exceptions\ProfileIdentityConflictException;
|
|
7
8
|
use Fleetbase\FleetOps\Exports\DriverExport;
|
|
@@ -33,6 +34,20 @@ use Maatwebsite\Excel\Facades\Excel;
|
|
|
33
34
|
class DriverController extends FleetOpsController
|
|
34
35
|
{
|
|
35
36
|
use Traits\DriverSchedulingTrait;
|
|
37
|
+
/**
|
|
38
|
+
* Permissions for methods AuthorizationGuard cannot map to a schema action (see FleetOpsController).
|
|
39
|
+
*
|
|
40
|
+
* @var array<string, string|string[]>
|
|
41
|
+
*/
|
|
42
|
+
protected array $methodPermissions = [
|
|
43
|
+
'sendCredentials' => 'update-user-for driver',
|
|
44
|
+
'resetCredentials' => 'update-user-for driver',
|
|
45
|
+
'deactivateLogin' => 'update-user-for driver',
|
|
46
|
+
'reactivateLogin' => 'update-user-for driver',
|
|
47
|
+
'unassignOrders' => 'assign-order-for driver',
|
|
48
|
+
'unassignOrder' => 'assign-order-for driver',
|
|
49
|
+
'unassignVehicle' => 'assign-vehicle-for driver',
|
|
50
|
+
];
|
|
36
51
|
/**
|
|
37
52
|
* The resource to query.
|
|
38
53
|
*
|
|
@@ -200,6 +215,7 @@ class DriverController extends FleetOpsController
|
|
|
200
215
|
*
|
|
201
216
|
* @return JsonResponse
|
|
202
217
|
*/
|
|
218
|
+
#[SkipAuthorizationCheck]
|
|
203
219
|
public function sendCredentials(string $id)
|
|
204
220
|
{
|
|
205
221
|
[$driver, $user, $error] = $this->resolveDriverLogin($id);
|
|
@@ -221,6 +237,7 @@ class DriverController extends FleetOpsController
|
|
|
221
237
|
*
|
|
222
238
|
* @return JsonResponse
|
|
223
239
|
*/
|
|
240
|
+
#[SkipAuthorizationCheck]
|
|
224
241
|
public function resetCredentials(Request $request, string $id)
|
|
225
242
|
{
|
|
226
243
|
$password = $request->input('password');
|
|
@@ -255,6 +272,7 @@ class DriverController extends FleetOpsController
|
|
|
255
272
|
*
|
|
256
273
|
* @return JsonResponse
|
|
257
274
|
*/
|
|
275
|
+
#[SkipAuthorizationCheck]
|
|
258
276
|
public function deactivateLogin(string $id)
|
|
259
277
|
{
|
|
260
278
|
[$driver, $user, $error] = $this->resolveDriverLogin($id);
|
|
@@ -275,6 +293,7 @@ class DriverController extends FleetOpsController
|
|
|
275
293
|
*
|
|
276
294
|
* @return JsonResponse
|
|
277
295
|
*/
|
|
296
|
+
#[SkipAuthorizationCheck]
|
|
278
297
|
public function reactivateLogin(string $id)
|
|
279
298
|
{
|
|
280
299
|
[$driver, $user, $error] = $this->resolveDriverLogin($id);
|
|
@@ -430,6 +449,7 @@ class DriverController extends FleetOpsController
|
|
|
430
449
|
]);
|
|
431
450
|
}
|
|
432
451
|
|
|
452
|
+
#[SkipAuthorizationCheck]
|
|
433
453
|
public function unassignOrders(Request $request, string $id): JsonResponse
|
|
434
454
|
{
|
|
435
455
|
$request->validate([
|
|
@@ -462,6 +482,7 @@ class DriverController extends FleetOpsController
|
|
|
462
482
|
]);
|
|
463
483
|
}
|
|
464
484
|
|
|
485
|
+
#[SkipAuthorizationCheck]
|
|
465
486
|
public function unassignOrder(string $id): JsonResponse
|
|
466
487
|
{
|
|
467
488
|
$driver = $this->findDriver($id);
|
|
@@ -498,6 +519,7 @@ class DriverController extends FleetOpsController
|
|
|
498
519
|
]);
|
|
499
520
|
}
|
|
500
521
|
|
|
522
|
+
#[SkipAuthorizationCheck]
|
|
501
523
|
public function unassignVehicle(string $id): JsonResponse
|
|
502
524
|
{
|
|
503
525
|
$driver = $this->findDriver($id);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Http\Controllers\Internal\v1;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Attributes\SkipAuthorizationCheck;
|
|
5
6
|
use Fleetbase\FleetOps\Http\Controllers\FleetOpsController;
|
|
6
7
|
use Fleetbase\FleetOps\Jobs\SyncFuelProviderTransactionsJob;
|
|
7
8
|
use Fleetbase\FleetOps\Models\FuelProviderConnection;
|
|
@@ -13,6 +14,16 @@ use Illuminate\Validation\ValidationException;
|
|
|
13
14
|
|
|
14
15
|
class FuelProviderConnectionController extends FleetOpsController
|
|
15
16
|
{
|
|
17
|
+
/**
|
|
18
|
+
* Permissions for methods AuthorizationGuard cannot map to a schema action (see FleetOpsController).
|
|
19
|
+
*
|
|
20
|
+
* @var array<string, string|string[]>
|
|
21
|
+
*/
|
|
22
|
+
protected array $methodPermissions = [
|
|
23
|
+
'testCredentials' => 'create fuel-provider-connection',
|
|
24
|
+
'testConnection' => 'update fuel-provider-connection',
|
|
25
|
+
];
|
|
26
|
+
|
|
16
27
|
public $resource = 'fuel_provider_connection';
|
|
17
28
|
|
|
18
29
|
public function __construct(protected FuelProviderService $fuelProviderService)
|
|
@@ -38,6 +49,7 @@ class FuelProviderConnectionController extends FleetOpsController
|
|
|
38
49
|
$this->normalizeConnectionInput($input, $connection);
|
|
39
50
|
}
|
|
40
51
|
|
|
52
|
+
#[SkipAuthorizationCheck]
|
|
41
53
|
public function testCredentials(Request $request, string $provider): JsonResponse
|
|
42
54
|
{
|
|
43
55
|
$request->validate([
|
|
@@ -54,6 +66,7 @@ class FuelProviderConnectionController extends FleetOpsController
|
|
|
54
66
|
return response()->json($result, data_get($result, 'success') ? 200 : 422);
|
|
55
67
|
}
|
|
56
68
|
|
|
69
|
+
#[SkipAuthorizationCheck]
|
|
57
70
|
public function testConnection(Request $request, string $id): JsonResponse
|
|
58
71
|
{
|
|
59
72
|
$connection = $this->findConnection($id);
|