velody/backend/src/modules/devices/devices.service.ts
2026-05-28 17:43:00 +02:00

71 lines
1.9 KiB
TypeScript

import { Injectable, NotFoundException } from '@nestjs/common';
import { createHash, randomBytes } from 'node:crypto';
import { PrismaService } from '../../infrastructure/database/prisma.service';
import { DefaultUserService } from '../users/default-user.service';
import {
DeviceHeartbeatRequestDto,
DeviceHeartbeatResponseDto,
RegisterDeviceRequestDto,
RegisterDeviceResponseDto,
} from './devices.dto';
@Injectable()
export class DevicesService {
constructor(
private readonly prismaService: PrismaService,
private readonly defaultUserService: DefaultUserService,
) {}
async register(
body: RegisterDeviceRequestDto,
): Promise<RegisterDeviceResponseDto> {
const bootstrapToken = randomBytes(24).toString('hex');
const installTokenHash = createHash('sha256')
.update(bootstrapToken)
.digest('hex');
const defaultUser = await this.defaultUserService.getOrCreateDefaultUser();
const device = await this.prismaService.device.create({
data: {
userId: defaultUser.id,
platform: body.platform,
deviceName: body.deviceName,
appVersion: body.appVersion,
installTokenHash,
lastSeenAt: new Date(),
},
});
return {
deviceId: device.id,
bootstrapToken,
serverTime: new Date().toISOString(),
};
}
async heartbeat(
body: DeviceHeartbeatRequestDto,
): Promise<DeviceHeartbeatResponseDto> {
const existing = await this.prismaService.device.findUnique({
where: { id: body.deviceId },
});
if (!existing) {
throw new NotFoundException('Device not found');
}
await this.prismaService.device.update({
where: { id: body.deviceId },
data: {
appVersion: body.appVersion,
lastSeenAt: new Date(),
},
});
return {
ok: true,
serverTime: new Date().toISOString(),
};
}
}