Files
Kevin L'Hereec f9e56c78b1 refactor: migrate all internal imports to package.json subpath aliases
- Add #domain, #protocol, #utils aliases to package.json imports map
- Replace all relative imports (./, ../, ../..) in app/ and
  database/mongo_migrations/ with the corresponding #alias imports,
  eliminating relative path traversal across the codebase
- Remove dead code: ConfigurationVersionModel.findByConfigurationIdentifier
  (unused, superseded by paginateVersions) and unused exception classes
  (NotFoundException, UnprocessableEntityException, DatabaseException)
  from app/exceptions/index.ts, keeping only BadRequestException
- Fix pre-existing syntax error in configuration_version.ts (mismatched
  parenthesis) that broke tsc
- Fix eqeqeq violation in configuration_service.ts and isNaN ->
  Number.isNaN in configuration_engine.ts / cwmp-1-0.ts / exchange_controller.ts
- Fix no-shadow violation in cwmp-1-0.ts EventStruct constructor
- Prettier formatting pass on touched files

Validated: tsc --noEmit clean, eslint app/ clean, full test suite green.
2026-07-22 11:45:14 +02:00

108 lines
3.6 KiB
TypeScript

import { BaseModel } from '#database/base_model'
import { type DeviceRecord } from '#domain/device/device_record'
import { type DeviceId } from '#domain/device/device_id'
import { type DeviceComplianceInfo } from '#domain/configuration/compliance'
import { type Filter, type Sort } from 'mongodb'
export default class DeviceModel extends BaseModel {
static collectionName = 'devices'
static async findByIdentifier(identifier: string): Promise<DeviceRecord | null> {
return this.findOne({ identifier })
}
static async findByDeviceId(deviceId: DeviceId): Promise<DeviceRecord | null> {
return this.findOne({
'deviceId.manufacturer': deviceId.manufacturer,
'deviceId.oui': deviceId.oui,
'deviceId.productClass': deviceId.productClass,
'deviceId.serialNumber': deviceId.serialNumber,
})
}
static async paginateDevices(
offset: number,
limit: number,
filter: Filter<any> = {}
): Promise<{ data: DeviceRecord[]; total: number }> {
const collection = this.getCollection()
// Only return documents created by the ACS (must have an identifier field)
const safeFilter: Filter<any> = { ...filter, identifier: { $exists: true, $ne: null } }
const total = await collection.countDocuments(safeFilter)
const data = (await collection
.find(safeFilter, { projection: { _id: 0 } })
.skip(offset)
.limit(limit)
.sort({ updatedAt: -1 } as Sort)
.toArray()) as unknown as DeviceRecord[]
return { data, total }
}
static async distinctCriteriaValues(): Promise<{
manufacturers: string[]
ouis: string[]
productClasses: string[]
}> {
const collection = this.getCollection()
const [manufacturers, ouis, productClasses] = await Promise.all([
collection.distinct('deviceId.manufacturer'),
collection.distinct('deviceId.oui'),
collection.distinct('deviceId.productClass'),
])
return {
manufacturers: manufacturers.filter((v: any) => v && typeof v === 'string').sort(),
ouis: ouis.filter((v: any) => v && typeof v === 'string').sort(),
productClasses: productClasses.filter((v: any) => v && typeof v === 'string').sort(),
}
}
static async createOrUpdate(device: Partial<DeviceRecord>): Promise<DeviceRecord> {
const collection = this.getCollection()
let filter: Filter<any> = {}
if (device.deviceId) {
filter = { deviceId: device.deviceId }
} else if (device.identifier) {
filter = { identifier: device.identifier }
} else {
throw new Error('Either identifier or deviceId must be provided')
}
const result = await collection.findOneAndUpdate(
filter,
{
$set: { ...device, updatedAt: new Date() },
$setOnInsert: { createdAt: new Date() },
},
{ upsert: true, returnDocument: 'after', projection: { _id: 0 } }
)
return result as unknown as DeviceRecord
}
static async updateCompliance(
identifier: string,
compliance: DeviceComplianceInfo
): Promise<void> {
await this.updateOne({ identifier }, { compliance })
}
static async updateProvisioningCode(identifier: string, provisioningCode: string): Promise<void> {
await this.updateOne({ identifier }, { provisioningCode })
}
static async resetComplianceForConfiguration(configurationIdentifier: string): Promise<void> {
const collection = this.getCollection()
await collection.updateMany(
{ 'compliance.configurationIdentifier': configurationIdentifier },
{
$set: {
'compliance.status': 'pending',
'compliance.lastError': null,
'updatedAt': new Date(),
},
}
)
}
}