Normalize component model structures in industrial seed

This commit is contained in:
MatthieuTD
2025-10-02 08:19:44 +02:00
parent bd439f6096
commit 6f52b27efc

View File

@@ -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),
]);