Migrate away from legacy component and piece models
This commit is contained in:
@@ -32,10 +32,6 @@ export class CreateComposantDto {
|
||||
|
||||
@IsString()
|
||||
typeMachineComponentRequirementId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
composantModelId?: string;
|
||||
}
|
||||
|
||||
export class UpdateComposantDto {
|
||||
@@ -59,8 +55,4 @@ export class UpdateComposantDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typeComposantId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
composantModelId?: string;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export class MachineComponentSelectionDto {
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
componentModelId?: string;
|
||||
typeComposantId?: string;
|
||||
|
||||
@IsOptional()
|
||||
definition?: any;
|
||||
@@ -18,8 +18,12 @@ export class MachinePieceSelectionDto {
|
||||
@IsString()
|
||||
requirementId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
pieceModelId: string;
|
||||
typePieceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
definition?: any;
|
||||
}
|
||||
|
||||
export class CreateMachineDto {
|
||||
|
||||
@@ -32,10 +32,6 @@ export class CreatePieceDto {
|
||||
|
||||
@IsString()
|
||||
typeMachinePieceRequirementId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
pieceModelId?: string;
|
||||
}
|
||||
|
||||
export class UpdatePieceDto {
|
||||
@@ -59,8 +55,4 @@ export class UpdatePieceDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typePieceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
pieceModelId?: string;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@ import {
|
||||
} from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { ValidateNested } from 'class-validator';
|
||||
import type { ComponentModelStructure } from '../types/inventory';
|
||||
import type {
|
||||
ComponentModelStructure,
|
||||
PieceModelStructure,
|
||||
} from '../types/inventory';
|
||||
|
||||
export enum CustomFieldType {
|
||||
TEXT = 'text',
|
||||
@@ -197,6 +200,10 @@ export class CreateTypeComposantDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
structure?: ComponentModelStructure;
|
||||
}
|
||||
|
||||
export class UpdateTypeComposantDto {
|
||||
@@ -211,6 +218,10 @@ export class UpdateTypeComposantDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
structure?: ComponentModelStructure;
|
||||
}
|
||||
|
||||
export class CreateTypePieceDto {
|
||||
@@ -224,6 +235,10 @@ export class CreateTypePieceDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
structure?: PieceModelStructure;
|
||||
}
|
||||
|
||||
export class UpdateTypePieceDto {
|
||||
@@ -238,68 +253,9 @@ export class UpdateTypePieceDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
structure?: PieceModelStructure;
|
||||
}
|
||||
|
||||
export class CreateComposantModelDto {
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsString()
|
||||
typeComposantId: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: ComponentModelStructure;
|
||||
}
|
||||
|
||||
export class UpdateComposantModelDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typeComposantId?: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: ComponentModelStructure;
|
||||
}
|
||||
|
||||
export class CreatePieceModelDto {
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsString()
|
||||
typePieceId: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: any;
|
||||
}
|
||||
|
||||
export class UpdatePieceModelDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typePieceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: any;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { normalizeComponentModelStructure } from '../../component-models/structure.normalizer';
|
||||
import type { ComponentModelStructure } from '../types/inventory';
|
||||
import type {
|
||||
ComponentModelStructure,
|
||||
PieceModelCustomField,
|
||||
PieceModelStructure,
|
||||
} from '../types/inventory';
|
||||
|
||||
export class ComponentModelStructureValidationError extends Error {
|
||||
constructor(message: string) {
|
||||
@@ -150,3 +154,109 @@ export const ComponentModelStructureSchema = {
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export class PieceModelStructureValidationError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'PieceModelStructureValidationError';
|
||||
}
|
||||
}
|
||||
|
||||
function toStringOrNull(value: unknown): string | null {
|
||||
if (value === undefined || value === null) {
|
||||
return null;
|
||||
}
|
||||
const trimmed = String(value).trim();
|
||||
return trimmed ? trimmed : null;
|
||||
}
|
||||
|
||||
function normalizePieceModelCustomFields(
|
||||
customFields: unknown,
|
||||
): PieceModelCustomField[] {
|
||||
if (!Array.isArray(customFields)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const normalized: PieceModelCustomField[] = [];
|
||||
|
||||
customFields.forEach((entry, index) => {
|
||||
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const record = entry as Record<string, unknown>;
|
||||
const rawName =
|
||||
(typeof record.name === 'string' ? record.name : undefined) ??
|
||||
(typeof record.key === 'string' ? record.key : undefined) ??
|
||||
undefined;
|
||||
|
||||
const name = rawName ? rawName.trim() : '';
|
||||
|
||||
if (!name) {
|
||||
throw new PieceModelStructureValidationError(
|
||||
`customFields[${index}].name doit être une chaîne non vide`,
|
||||
);
|
||||
}
|
||||
|
||||
const field: PieceModelCustomField = { name };
|
||||
|
||||
if ('value' in record) {
|
||||
field.value = record.value;
|
||||
}
|
||||
|
||||
if (typeof record.type === 'string') {
|
||||
field.type = record.type;
|
||||
}
|
||||
|
||||
if ('required' in record) {
|
||||
field.required = Boolean(record.required);
|
||||
}
|
||||
|
||||
if (Array.isArray(record.options)) {
|
||||
field.options = record.options;
|
||||
} else if (typeof record.optionsText === 'string') {
|
||||
const options = record.optionsText
|
||||
.split(/\r?\n/)
|
||||
.map((option) => option.trim())
|
||||
.filter((option) => option.length > 0);
|
||||
if (options.length > 0) {
|
||||
field.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
normalized.push(field);
|
||||
});
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export const PieceModelStructureSchema = {
|
||||
parse(input: unknown): PieceModelStructure {
|
||||
if (input === undefined || input === null) {
|
||||
return { customFields: [] };
|
||||
}
|
||||
|
||||
if (typeof input !== 'object' || Array.isArray(input)) {
|
||||
throw new PieceModelStructureValidationError(
|
||||
'La structure de pièce doit être un objet JSON.',
|
||||
);
|
||||
}
|
||||
|
||||
const record = input as Record<string, unknown>;
|
||||
|
||||
const structure: PieceModelStructure = { ...record };
|
||||
const customFields = normalizePieceModelCustomFields(record.customFields);
|
||||
if (customFields.length > 0 || 'customFields' in record) {
|
||||
structure.customFields = customFields;
|
||||
}
|
||||
|
||||
const normalizedTypePiece = toStringOrNull(record.typePieceId);
|
||||
if (normalizedTypePiece) {
|
||||
structure.typePieceId = normalizedTypePiece;
|
||||
} else if ('typePieceId' in record) {
|
||||
delete (structure as Record<string, unknown>).typePieceId;
|
||||
}
|
||||
|
||||
return structure;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -39,3 +39,16 @@ export type ComponentModelStructure = {
|
||||
}
|
||||
>;
|
||||
};
|
||||
|
||||
export type PieceModelCustomField = {
|
||||
name: string;
|
||||
value?: unknown;
|
||||
type?: string;
|
||||
required?: boolean;
|
||||
options?: unknown;
|
||||
};
|
||||
|
||||
export type PieceModelStructure = {
|
||||
customFields?: PieceModelCustomField[];
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user