fix: sanitize device identifier and explicitly enable device

- Lowercase and strip non-alphanumeric chars from device ID
- Explicitly set disabled=false when creating device in Traccar
- Use the uniqueId returned by Traccar (ensures consistency)
- Add logging for debugging device creation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 20:13:30 +01:00
parent cbfb8c3f46
commit 1e162b4f7c
2 changed files with 21 additions and 7 deletions

View File

@@ -162,8 +162,10 @@ export class GpsService implements OnModuleInit {
throw new BadRequestException('Driver is already enrolled for GPS tracking'); throw new BadRequestException('Driver is already enrolled for GPS tracking');
} }
// Generate unique device identifier (no special characters for better compatibility) // Generate unique device identifier (lowercase alphanumeric only for compatibility)
const deviceIdentifier = `vipdriver${driverId.replace(/-/g, '').slice(0, 8)}`; const deviceIdentifier = `vipdriver${driverId.replace(/-/g, '').slice(0, 8)}`.toLowerCase();
this.logger.log(`Enrolling driver ${driver.name} with device identifier: ${deviceIdentifier}`);
// Create device in Traccar // Create device in Traccar
const traccarDevice = await this.traccarClient.createDevice( const traccarDevice = await this.traccarClient.createDevice(
@@ -172,12 +174,16 @@ export class GpsService implements OnModuleInit {
driver.phone || undefined, driver.phone || undefined,
); );
// Use the uniqueId returned by Traccar (in case it was modified)
const actualDeviceId = traccarDevice.uniqueId;
this.logger.log(`Traccar returned device with uniqueId: ${actualDeviceId}`);
// Create GPS device record (consent pre-approved by HR at hiring) // Create GPS device record (consent pre-approved by HR at hiring)
await this.prisma.gpsDevice.create({ await this.prisma.gpsDevice.create({
data: { data: {
driverId, driverId,
traccarDeviceId: traccarDevice.id, traccarDeviceId: traccarDevice.id,
deviceIdentifier, deviceIdentifier: actualDeviceId, // Use what Traccar actually stored
consentGiven: true, consentGiven: true,
consentGivenAt: new Date(), consentGivenAt: new Date(),
}, },
@@ -194,7 +200,7 @@ GPS Tracking Setup Instructions for ${driver.name}:
- Android: https://play.google.com/store/apps/details?id=org.traccar.client - Android: https://play.google.com/store/apps/details?id=org.traccar.client
2. Open the app and configure: 2. Open the app and configure:
- Device identifier: ${deviceIdentifier} - Device identifier: ${actualDeviceId}
- Server URL: ${serverUrl} - Server URL: ${serverUrl}
- Frequency: ${settings.updateIntervalSeconds} seconds - Frequency: ${settings.updateIntervalSeconds} seconds
- Location accuracy: High - Location accuracy: High
@@ -226,7 +232,7 @@ Note: GPS tracking is only active during shift hours (${settings.shiftStartHour}
return { return {
success: true, success: true,
deviceIdentifier, deviceIdentifier: actualDeviceId, // Return what Traccar actually stored
serverUrl, serverUrl,
instructions, instructions,
signalMessageSent, signalMessageSent,

View File

@@ -180,13 +180,21 @@ export class TraccarClientService implements OnModuleInit {
* Create a new device in Traccar * Create a new device in Traccar
*/ */
async createDevice(name: string, uniqueId: string, phone?: string): Promise<TraccarDevice> { async createDevice(name: string, uniqueId: string, phone?: string): Promise<TraccarDevice> {
// Sanitize uniqueId - trim whitespace, lowercase, remove any non-alphanumeric chars
const sanitizedUniqueId = uniqueId.trim().toLowerCase().replace(/[^a-z0-9]/g, '');
this.logger.log(`Creating Traccar device: name="${name}", uniqueId="${sanitizedUniqueId}"`);
const device = await this.request<TraccarDevice>('post', '/api/devices', { const device = await this.request<TraccarDevice>('post', '/api/devices', {
name, name,
uniqueId, uniqueId: sanitizedUniqueId,
phone, phone: phone || null,
category: 'person', category: 'person',
disabled: false, // Explicitly enable the device
}); });
this.logger.log(`Traccar device created: id=${device.id}, uniqueId="${device.uniqueId}", disabled=${device.disabled}`);
// Link device to all admin users so they can see it // Link device to all admin users so they can see it
await this.linkDeviceToAllAdmins(device.id); await this.linkDeviceToAllAdmins(device.id);