import { ILoggedInUser , ValidateDeviceOwnershipQuery } from '@energyweb/origin-backend-core' ; import { Injectable } from '@nestjs/common' ; import { QueryBus } from '@nestjs/cqrs' ; import { InjectRepository } from '@nestjs/typeorm' ; import { FindManyOptions , Repository } from 'typeorm' ; import { OriginDevice } from './origin-device.entity' ; import { ExternalDeviceAlreadyUsedError , SmartMeterAlreadyUsedError , UnableToVerifyOwnershipError } from './errors' ; import { NewDeviceDTO } from './dto/new-device.dto' ; @ Injectable ( ) export class DeviceRegistryService { constructor ( @ InjectRepository ( OriginDevice ) private readonly repository , private readonly queryBus ) { } public async find ( options ? ) { return this . repository . find ( options ) ; } async findOne ( id ) { return this . repository . findOne ( id ) ; } public async register ( user , newDevice ) { await this . validateRegistration ( user , newDevice ) ; const deviceToStore = new OriginDevice ( { ... NewDeviceDTO . sanitize ( newDevice ) , owner : user . ownerId } ) ; const storedDevice = await this . repository . save ( deviceToStore ) ; return storedDevice . id ; } private async validateRegistration ( user , { externalRegistryId , smartMeterId } ) { const isExternalRegistryIdAlreadyUsed = await this . isExternalRegistryIdAlreadyUsed ( externalRegistryId ) ; if ( isExternalRegistryIdAlreadyUsed ) { throw new ExternalDeviceAlreadyUsedError ( externalRegistryId ) ; } const isSmartMeterIdAlreadyUsed = await this . isSmartMeterIdAlreadyUsed ( smartMeterId ) ; if ( isSmartMeterIdAlreadyUsed ) { throw new SmartMeterAlreadyUsedError ( smartMeterId ) ; } const isOwnerOfTheDevice = await this . queryBus . execute < ValidateDeviceOwnershipQuery , boolean > ( new ValidateDeviceOwnershipQuery ( user . ownerId , externalRegistryId ) ) ; if ( ! isOwnerOfTheDevice ) { throw new UnableToVerifyOwnershipError ( user . ownerId , externalRegistryId ) ; } } private async isExternalRegistryIdAlreadyUsed ( externalRegistryId ) { const count = await this . repository . createQueryBuilder ( ) . where ( { externalRegistryId } ) . getCount ( ) ; return count > 0 ; } private async isSmartMeterIdAlreadyUsed ( smartMeterId ) { const count = await this . repository . createQueryBuilder ( ) . where ( { smartMeterId } ) . getCount ( ) ; return count > 0 ; } }