Files
adam-acs/app/models/configuration.ts
T
Kevin L'HereecandCopilot aff8e14a63 feat: compliance report + auto-versioning for configurations
- Add ComplianceStatus.PENDING and configVersion to DeviceComplianceInfo
- Add ComplianceReport + ComplianceDeviceResult types to ConfigurationEngine
- Expose evaluateSpecific() as public (used by compliance + dry-run)
- Add complianceReport() method: filter matching devices, evaluate each
- Fix matchesCriteria: skip parameterCriteria entries with null/empty name
- Fix getDeviceParameterValue: fallback to plain object arrays (DeviceRecord)
- Fix findDevice: support lookup by both identifier and deviceId.id
- ConfigurationService.update: version is now auto-managed (no user input)
  - behavioral changes (criteria/params/policy/priority/…) → patch bump
  - bumpType field allows 'patch' | 'minor' | 'major'
  - cosmetic changes (name/tags) → no bump
- Add sanitizeCriteria: filter null/empty parameterCriteria names silently
- Add isBehavioralChange helper
- Add DeviceModel.resetComplianceForConfiguration call on behavioral update
- Add ConfigurationModel.distinctTags() + controller endpoint GET /tags
- Add controller endpoint GET /configurations/:id/compliance
- Add DeviceModel.getDistinctValues for inventory fields
- Fix unit tests: mock DeviceModel, remove obsolete version-validation test
- Add 14 new unit tests (engine: 5, service: 9)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-01 11:32:17 +02:00

44 lines
1.6 KiB
TypeScript

import { BaseModel } from '#database/base_model'
import { Configuration } from '../domain/configuration/configuration.js'
import { Filter, Sort } from 'mongodb'
export default class ConfigurationModel extends BaseModel {
static collectionName = 'configurations'
static async findByIdentifier(identifier: string): Promise<Configuration | null> {
return this.findOne({ identifier }) as Promise<Configuration | null>
}
static async findAllEnabled(sort: Sort = { priority: -1 }): Promise<Configuration[]> {
const collection = this.getCollection()
return collection.find({ enabled: true }).sort(sort).toArray() as unknown as Promise<Configuration[]>
}
static async paginateConfigurations(
page: number,
perPage: number,
filter: Filter<any> = {},
sort: Sort = { priority: -1 }
): Promise<{ data: Configuration[]; total: number; page: number; perPage: number; lastPage: number }> {
return this.paginate(page, perPage, filter, sort)
}
static async createIfNotExists(data: Partial<Configuration>): Promise<Configuration> {
const existing = await this.findOne({ identifier: data.identifier })
if (existing) {
throw new Error(`Configuration with identifier '${data.identifier}' already exists`)
}
return this.create(data) as Promise<Configuration>
}
static async distinctTags(): Promise<string[]> {
const collection = this.getCollection()
const tags = await collection.distinct('tags')
return (tags as string[]).filter(Boolean).sort()
}
static async deleteByIdentifier(identifier: string): Promise<boolean> {
return this.deleteOne({ identifier })
}
}