Normalize component model structures in industrial seed
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { PrismaClient, Prisma, ModelCategory } from '@prisma/client';
|
||||
import { normalizeComponentModelStructure } from '../src/component-models/structure.normalizer';
|
||||
import type { ComponentModelStructure } from '../src/shared/types/inventory';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -32,12 +34,33 @@ type PieceModelDefinition = {
|
||||
structure?: Prisma.InputJsonValue;
|
||||
};
|
||||
|
||||
type ComponentModelStructureDraft =
|
||||
| ComponentModelStructure
|
||||
| ({
|
||||
recommendedCustomFields?: Record<string, unknown>;
|
||||
customFields?: Array<{ key?: string; name?: string; value?: unknown }>;
|
||||
pieceTemplates?: Array<{
|
||||
typeCode?: string;
|
||||
modelCode?: string;
|
||||
quantity?: number;
|
||||
usage?: string;
|
||||
notes?: string;
|
||||
role?: string;
|
||||
}>;
|
||||
subComponentTemplates?: Array<{
|
||||
typeCode?: string;
|
||||
suggestedModelCodes?: string[];
|
||||
alias?: string;
|
||||
notes?: string;
|
||||
}>;
|
||||
} & Record<string, unknown>);
|
||||
|
||||
type ComponentModelDefinition = {
|
||||
code: string;
|
||||
name: string;
|
||||
description: string;
|
||||
typeCode: string;
|
||||
structure?: Prisma.InputJsonValue;
|
||||
structure?: ComponentModelStructureDraft | Prisma.InputJsonValue;
|
||||
};
|
||||
|
||||
type ConstructeurDefinition = {
|
||||
@@ -4207,8 +4230,164 @@ async function createPieceModels(
|
||||
return Object.fromEntries(entries) as Record<string, { id: string }>;
|
||||
}
|
||||
|
||||
function buildComponentModelStructure(
|
||||
structure: ComponentModelStructureDraft | Prisma.InputJsonValue | undefined,
|
||||
componentTypes: Record<string, { id: string }>,
|
||||
pieceTypes: Record<string, { id: string }>,
|
||||
): Prisma.InputJsonValue | undefined {
|
||||
if (!structure) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (typeof structure !== 'object' || structure === null) {
|
||||
return structure as Prisma.InputJsonValue;
|
||||
}
|
||||
|
||||
const candidate = structure as Record<string, unknown>;
|
||||
|
||||
const asCleanString = (value: unknown): string | undefined => {
|
||||
if (value === undefined || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
const text = String(value).trim().replace(/\s+/g, ' ');
|
||||
return text ? text : undefined;
|
||||
};
|
||||
|
||||
if (
|
||||
Array.isArray((candidate as any).pieces) ||
|
||||
Array.isArray((candidate as any).customFields) ||
|
||||
Array.isArray((candidate as any).subcomponents) ||
|
||||
Array.isArray((candidate as any).subComponents)
|
||||
) {
|
||||
return normalizeComponentModelStructure(candidate) as Prisma.InputJsonValue;
|
||||
}
|
||||
|
||||
const customFieldEntries = new Map<string, unknown>();
|
||||
|
||||
const presetCustomFields = Array.isArray((candidate as any).customFields)
|
||||
? ((candidate as any).customFields as Array<Record<string, unknown>>)
|
||||
: [];
|
||||
|
||||
for (const entry of presetCustomFields) {
|
||||
const key = String(entry?.key ?? entry?.name ?? '').trim();
|
||||
if (!key) {
|
||||
continue;
|
||||
}
|
||||
if (!customFieldEntries.has(key)) {
|
||||
customFieldEntries.set(key, entry?.value ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
const recommended = (candidate as any).recommendedCustomFields as
|
||||
| Record<string, unknown>
|
||||
| undefined;
|
||||
|
||||
if (recommended) {
|
||||
for (const [key, value] of Object.entries(recommended)) {
|
||||
const trimmedKey = String(key).trim();
|
||||
if (!trimmedKey) {
|
||||
continue;
|
||||
}
|
||||
if (!customFieldEntries.has(trimmedKey)) {
|
||||
customFieldEntries.set(trimmedKey, value ?? null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pieces: ComponentModelStructure['pieces'] = [];
|
||||
const subcomponents: ComponentModelStructure['subcomponents'] = [];
|
||||
|
||||
const pieceTemplates = Array.isArray((candidate as any).pieceTemplates)
|
||||
? ((candidate as any).pieceTemplates as Array<Record<string, unknown>>)
|
||||
: [];
|
||||
|
||||
for (const template of pieceTemplates) {
|
||||
const typeCode = String(template?.typeCode ?? '').trim();
|
||||
if (!typeCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const normalizedRole = asCleanString(
|
||||
template?.usage ?? template?.role ?? template?.notes ?? null,
|
||||
);
|
||||
|
||||
if (pieceTypes[typeCode]) {
|
||||
pieces.push(
|
||||
normalizedRole
|
||||
? { familyCode: typeCode, role: normalizedRole }
|
||||
: { familyCode: typeCode },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (componentTypes[typeCode]) {
|
||||
subcomponents.push(
|
||||
normalizedRole
|
||||
? { familyCode: typeCode, alias: normalizedRole }
|
||||
: { familyCode: typeCode },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
pieces.push(
|
||||
normalizedRole
|
||||
? { familyCode: typeCode, role: normalizedRole }
|
||||
: { familyCode: typeCode },
|
||||
);
|
||||
}
|
||||
|
||||
const subComponentTemplates = Array.isArray((candidate as any).subComponentTemplates)
|
||||
? ((candidate as any).subComponentTemplates as Array<Record<string, unknown>>)
|
||||
: [];
|
||||
|
||||
for (const template of subComponentTemplates) {
|
||||
const typeCode = String(template?.typeCode ?? '').trim();
|
||||
const normalizedAlias = asCleanString(template?.alias ?? template?.notes ?? null);
|
||||
const suggestedModels = Array.isArray(template?.suggestedModelCodes)
|
||||
? (template?.suggestedModelCodes as string[])
|
||||
: [];
|
||||
|
||||
if (suggestedModels.length > 0) {
|
||||
suggestedModels.forEach((modelCode, index) => {
|
||||
const hint =
|
||||
normalizedAlias && suggestedModels.length > 1
|
||||
? `${normalizedAlias} #${index + 1}`
|
||||
: normalizedAlias;
|
||||
const fallbackFamily = typeCode || String(modelCode ?? '').trim() || 'UNKNOWN';
|
||||
subcomponents.push(
|
||||
hint
|
||||
? { familyCode: fallbackFamily, alias: hint }
|
||||
: { familyCode: fallbackFamily },
|
||||
);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeCode) {
|
||||
subcomponents.push(
|
||||
normalizedAlias
|
||||
? { familyCode: typeCode, alias: normalizedAlias }
|
||||
: { familyCode: typeCode },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const canonical: ComponentModelStructure = {
|
||||
pieces,
|
||||
subcomponents,
|
||||
customFields: Array.from(customFieldEntries.entries()).map(([key, value]) => ({
|
||||
key,
|
||||
value: value ?? null,
|
||||
})),
|
||||
};
|
||||
|
||||
return normalizeComponentModelStructure(canonical) as Prisma.InputJsonValue;
|
||||
}
|
||||
|
||||
async function createComponentModels(
|
||||
componentTypes: Record<string, { id: string }>,
|
||||
pieceTypes: Record<string, { id: string }>,
|
||||
) {
|
||||
console.log('🛠️ Création des modèles de composants...');
|
||||
|
||||
@@ -4224,7 +4403,11 @@ async function createComponentModels(
|
||||
name: definition.name,
|
||||
description: definition.description,
|
||||
typeComposant: { connect: { id: type.id } },
|
||||
structure: definition.structure,
|
||||
structure: buildComponentModelStructure(
|
||||
definition.structure,
|
||||
componentTypes,
|
||||
pieceTypes,
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -4519,7 +4702,7 @@ async function main() {
|
||||
const { componentTypes, pieceTypes } = await createModelTypes();
|
||||
const [pieceModels, componentModels, typeMachines] = await Promise.all([
|
||||
createPieceModels(pieceTypes),
|
||||
createComponentModels(componentTypes),
|
||||
createComponentModels(componentTypes, pieceTypes),
|
||||
createTypeMachines(componentTypes, pieceTypes),
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user