- extend Prisma schema with products, product constructs and link tables\n- introduce product service, DTOs and includes with constructeur support\n- integrate product selections across model type skeletons, composants, pièces and machines\n- validate product requirements when building machine skeletons and payloads
785 lines
20 KiB
TypeScript
785 lines
20 KiB
TypeScript
import { PrismaClient, Prisma } from '@prisma/client';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
type CreatedFields = Record<string, string>;
|
||
|
||
async function deleteExistingData() {
|
||
await prisma.machineComponentLink.deleteMany();
|
||
await prisma.machinePieceLink.deleteMany();
|
||
await prisma.machine.deleteMany();
|
||
await prisma.customFieldValue.deleteMany();
|
||
await prisma.product.deleteMany();
|
||
await prisma.composant.deleteMany();
|
||
await prisma.piece.deleteMany();
|
||
await prisma.typeMachineProductRequirement.deleteMany();
|
||
|
||
await prisma.modelType.deleteMany({
|
||
where: {
|
||
code: {
|
||
in: [
|
||
'hydraulic-pump',
|
||
'hydraulic-reservoir',
|
||
'cooling-fan',
|
||
'cooling-module',
|
||
'structural-frame',
|
||
'hydraulic-power-unit',
|
||
'hydraulic-product',
|
||
],
|
||
},
|
||
},
|
||
});
|
||
}
|
||
|
||
async function createPieceType(
|
||
name: string,
|
||
code: string,
|
||
description: string,
|
||
fields: Array<{
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}>,
|
||
skeleton?: Record<string, unknown>,
|
||
) {
|
||
const type = await prisma.modelType.create({
|
||
data: {
|
||
name,
|
||
code,
|
||
category: 'PIECE',
|
||
description,
|
||
pieceSkeleton: skeleton
|
||
? (skeleton as Prisma.InputJsonValue)
|
||
: Prisma.JsonNull,
|
||
pieceCustomFields: {
|
||
create: fields.map((field) => ({
|
||
name: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
options: field.options ?? [],
|
||
})),
|
||
},
|
||
},
|
||
});
|
||
|
||
const customFields = await prisma.customField.findMany({
|
||
where: { typePieceId: type.id },
|
||
});
|
||
|
||
const fieldMap: CreatedFields = {};
|
||
customFields.forEach((field) => {
|
||
fieldMap[field.name] = field.id;
|
||
});
|
||
|
||
return { type, fieldMap };
|
||
}
|
||
|
||
async function createComponentType(
|
||
name: string,
|
||
code: string,
|
||
description: string,
|
||
fields: Array<{
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}>,
|
||
skeleton?: Record<string, unknown>,
|
||
) {
|
||
const type = await prisma.modelType.create({
|
||
data: {
|
||
name,
|
||
code,
|
||
category: 'COMPONENT',
|
||
description,
|
||
componentSkeleton: skeleton
|
||
? (skeleton as Prisma.InputJsonValue)
|
||
: Prisma.JsonNull,
|
||
customFields: {
|
||
create: fields.map((field) => ({
|
||
name: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
options: field.options ?? [],
|
||
})),
|
||
},
|
||
},
|
||
});
|
||
|
||
const customFields = await prisma.customField.findMany({
|
||
where: { typeComposantId: type.id },
|
||
});
|
||
|
||
const fieldMap: CreatedFields = {};
|
||
customFields.forEach((field) => {
|
||
fieldMap[field.name] = field.id;
|
||
});
|
||
|
||
return { type, fieldMap };
|
||
}
|
||
|
||
async function createPiece(options: {
|
||
name: string;
|
||
reference: string;
|
||
price: number;
|
||
constructeurIds?: string[] | null;
|
||
typeId: string;
|
||
fieldValues: Record<string, string>;
|
||
}) {
|
||
const customFields = await prisma.customField.findMany({
|
||
where: { typePieceId: options.typeId },
|
||
});
|
||
|
||
const customFieldValues = Object.entries(options.fieldValues).map(
|
||
([fieldName, value]) => {
|
||
const target = customFields.find((field) => field.name === fieldName);
|
||
if (!target) {
|
||
throw new Error(
|
||
`Custom field "${fieldName}" introuvable pour le type de pièce ${options.typeId}`,
|
||
);
|
||
}
|
||
return {
|
||
value,
|
||
customFieldId: target.id,
|
||
};
|
||
},
|
||
);
|
||
|
||
const constructeurIds = Array.isArray(options.constructeurIds)
|
||
? Array.from(
|
||
new Set(
|
||
options.constructeurIds
|
||
.filter((value): value is string => typeof value === 'string')
|
||
.map((value) => value.trim())
|
||
.filter((value) => value.length > 0),
|
||
),
|
||
)
|
||
: [];
|
||
|
||
const data: any = {
|
||
name: options.name,
|
||
reference: options.reference,
|
||
prix: new Prisma.Decimal(options.price),
|
||
typePieceId: options.typeId,
|
||
customFieldValues: {
|
||
create: customFieldValues,
|
||
},
|
||
};
|
||
|
||
if (constructeurIds.length) {
|
||
data.constructeurs = {
|
||
connect: constructeurIds.map((id) => ({ id })),
|
||
};
|
||
}
|
||
|
||
return prisma.piece.create({
|
||
data,
|
||
});
|
||
}
|
||
|
||
async function createComponent(options: {
|
||
name: string;
|
||
reference: string;
|
||
price: number;
|
||
constructeurIds?: string[] | null;
|
||
typeId: string;
|
||
fieldValues: Record<string, string>;
|
||
structure?: Prisma.InputJsonValue;
|
||
}) {
|
||
const customFields = await prisma.customField.findMany({
|
||
where: { typeComposantId: options.typeId },
|
||
});
|
||
|
||
const customFieldValues = Object.entries(options.fieldValues).map(
|
||
([fieldName, value]) => {
|
||
const target = customFields.find((field) => field.name === fieldName);
|
||
if (!target) {
|
||
throw new Error(
|
||
`Custom field "${fieldName}" introuvable pour le type de composant ${options.typeId}`,
|
||
);
|
||
}
|
||
return {
|
||
value,
|
||
customFieldId: target.id,
|
||
};
|
||
},
|
||
);
|
||
|
||
const constructeurIds = Array.isArray(options.constructeurIds)
|
||
? Array.from(
|
||
new Set(
|
||
options.constructeurIds
|
||
.filter((value): value is string => typeof value === 'string')
|
||
.map((value) => value.trim())
|
||
.filter((value) => value.length > 0),
|
||
),
|
||
)
|
||
: [];
|
||
|
||
const data: any = {
|
||
name: options.name,
|
||
reference: options.reference,
|
||
prix: new Prisma.Decimal(options.price),
|
||
typeComposantId: options.typeId,
|
||
structure:
|
||
options.structure === undefined
|
||
? Prisma.JsonNull
|
||
: options.structure ?? Prisma.JsonNull,
|
||
customFieldValues: {
|
||
create: customFieldValues,
|
||
},
|
||
};
|
||
|
||
if (constructeurIds.length) {
|
||
data.constructeurs = {
|
||
connect: constructeurIds.map((id) => ({ id })),
|
||
};
|
||
}
|
||
|
||
return prisma.composant.create({
|
||
data,
|
||
});
|
||
}
|
||
|
||
async function createProductType(
|
||
name: string,
|
||
code: string,
|
||
description: string,
|
||
fields: Array<{
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}>,
|
||
skeleton?: Record<string, unknown>,
|
||
) {
|
||
const type = await prisma.modelType.create({
|
||
data: {
|
||
name,
|
||
code,
|
||
category: 'PRODUCT',
|
||
description,
|
||
productSkeleton: skeleton
|
||
? (skeleton as Prisma.InputJsonValue)
|
||
: Prisma.JsonNull,
|
||
productCustomFields: {
|
||
create: fields.map((field, index) => ({
|
||
name: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
options: field.options ?? [],
|
||
orderIndex: index,
|
||
})),
|
||
},
|
||
},
|
||
});
|
||
|
||
const customFields = await prisma.customField.findMany({
|
||
where: { typeProductId: type.id },
|
||
});
|
||
|
||
const fieldMap: CreatedFields = {};
|
||
customFields.forEach((field) => {
|
||
fieldMap[field.name] = field.id;
|
||
});
|
||
|
||
return { type, fieldMap };
|
||
}
|
||
|
||
async function createProduct(options: {
|
||
name: string;
|
||
reference?: string;
|
||
supplierPrice?: number | null;
|
||
constructeurIds?: string[] | null;
|
||
typeId?: string | null;
|
||
fieldValues?: Record<string, string>;
|
||
}) {
|
||
const fieldValues = options.fieldValues ?? {};
|
||
|
||
const customFields = options.typeId
|
||
? await prisma.customField.findMany({
|
||
where: { typeProductId: options.typeId },
|
||
})
|
||
: [];
|
||
|
||
const customFieldValues = Object.entries(fieldValues).flatMap(
|
||
([fieldName, value]) => {
|
||
if (typeof value !== 'string') {
|
||
return [];
|
||
}
|
||
|
||
const target = customFields.find((field) => field.name === fieldName);
|
||
if (!target) {
|
||
return [];
|
||
}
|
||
|
||
return [
|
||
{
|
||
value,
|
||
customFieldId: target.id,
|
||
},
|
||
];
|
||
},
|
||
);
|
||
|
||
const constructeurIds = Array.isArray(options.constructeurIds)
|
||
? Array.from(
|
||
new Set(
|
||
options.constructeurIds
|
||
.filter((value): value is string => typeof value === 'string')
|
||
.map((value) => value.trim())
|
||
.filter((value) => value.length > 0),
|
||
),
|
||
)
|
||
: [];
|
||
|
||
const data: Prisma.ProductCreateInput = {
|
||
name: options.name,
|
||
reference: options.reference ?? null,
|
||
supplierPrice:
|
||
options.supplierPrice === undefined || options.supplierPrice === null
|
||
? null
|
||
: new Prisma.Decimal(options.supplierPrice),
|
||
};
|
||
|
||
if (options.typeId) {
|
||
data.typeProduct = {
|
||
connect: { id: options.typeId },
|
||
};
|
||
}
|
||
|
||
if (constructeurIds.length) {
|
||
data.constructeurs = {
|
||
connect: constructeurIds.map((id) => ({ id })),
|
||
};
|
||
}
|
||
|
||
if (customFieldValues.length) {
|
||
data.customFieldValues = {
|
||
create: customFieldValues.map((entry) => ({
|
||
value: entry.value,
|
||
customField: {
|
||
connect: { id: entry.customFieldId },
|
||
},
|
||
})),
|
||
};
|
||
}
|
||
|
||
return prisma.product.create({
|
||
data,
|
||
});
|
||
}
|
||
|
||
async function main() {
|
||
console.log('Nettoyage des données existantes…');
|
||
await deleteExistingData();
|
||
|
||
console.log('Création des types de pièces…');
|
||
const pumpPieceFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Pression nominale (bar)', type: 'number', required: true },
|
||
{ name: 'Débit nominal (L/min)', type: 'number', required: true },
|
||
{ name: 'Puissance (kW)', type: 'number', required: true },
|
||
{ name: 'Indice de protection', type: 'text' },
|
||
{ name: 'Vitesse max (rpm)', type: 'number' },
|
||
] as const;
|
||
|
||
const pumpPieceType = await createPieceType(
|
||
'Pompe hydraulique',
|
||
'hydraulic-pump',
|
||
'Pompes à pistons pour unités hydrauliques',
|
||
pumpPieceFields,
|
||
{
|
||
customFields: pumpPieceFields.map((field) => ({
|
||
name: field.name,
|
||
key: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
})),
|
||
},
|
||
);
|
||
|
||
const reservoirPieceFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Pression nominale (bar)', type: 'number', required: true },
|
||
{ name: 'Débit nominal (L/min)', type: 'number', required: true },
|
||
{ name: 'Capacité (L)', type: 'number', required: true },
|
||
{ name: 'Type d’huile', type: 'text', required: true },
|
||
{ name: 'Filtration', type: 'text' },
|
||
] as const;
|
||
|
||
const reservoirPieceType = await createPieceType(
|
||
'Réservoir hydraulique',
|
||
'hydraulic-reservoir',
|
||
'Réservoirs haute capacité pour fluide hydraulique',
|
||
reservoirPieceFields,
|
||
{
|
||
customFields: reservoirPieceFields.map((field) => ({
|
||
name: field.name,
|
||
key: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
})),
|
||
},
|
||
);
|
||
|
||
const fanPieceFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Diamètre (mm)', type: 'number', required: true },
|
||
{ name: 'Débit air (m³/h)', type: 'number', required: true },
|
||
{ name: 'Consommation (A)', type: 'number' },
|
||
{ name: 'Tension (V)', type: 'number', required: true },
|
||
{ name: 'Niveau sonore (dB)', type: 'number' },
|
||
] as const;
|
||
|
||
const fanPieceType = await createPieceType(
|
||
'Ventilateur de refroidissement',
|
||
'cooling-fan',
|
||
'Ventilateurs axiaux pour modules de refroidissement',
|
||
fanPieceFields,
|
||
{
|
||
customFields: fanPieceFields.map((field) => ({
|
||
name: field.name,
|
||
key: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
})),
|
||
},
|
||
);
|
||
|
||
console.log('Création des pièces…');
|
||
const pumpPiece = await createPiece({
|
||
name: 'Pompe à pistons PX-300',
|
||
reference: 'PX-300',
|
||
price: 1850,
|
||
typeId: pumpPieceType.type.id,
|
||
fieldValues: {
|
||
'Pression nominale (bar)': '180',
|
||
'Débit nominal (L/min)': '260',
|
||
'Puissance (kW)': '45',
|
||
'Indice de protection': 'IP55',
|
||
'Vitesse max (rpm)': '3200',
|
||
},
|
||
});
|
||
|
||
const reservoirPiece = await createPiece({
|
||
name: 'Réservoir 120L Inox',
|
||
reference: 'RES-120-INX',
|
||
price: 720,
|
||
typeId: reservoirPieceType.type.id,
|
||
fieldValues: {
|
||
'Pression nominale (bar)': '12',
|
||
'Débit nominal (L/min)': '280',
|
||
'Capacité (L)': '120',
|
||
'Type d’huile': 'HLP46',
|
||
Filtration: '10µ absolu',
|
||
},
|
||
});
|
||
|
||
const fanPiece = await createPiece({
|
||
name: 'Ventilateur axial VE-450',
|
||
reference: 'VE-450',
|
||
price: 390,
|
||
typeId: fanPieceType.type.id,
|
||
fieldValues: {
|
||
'Diamètre (mm)': '450',
|
||
'Débit air (m³/h)': '5200',
|
||
'Consommation (A)': '3.2',
|
||
'Tension (V)': '400',
|
||
'Niveau sonore (dB)': '68',
|
||
},
|
||
});
|
||
|
||
console.log('Création des types de produits…');
|
||
const hydraulicProductFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Fournisseur', type: 'text', required: true },
|
||
{ name: 'Garantie (mois)', type: 'number', required: true },
|
||
{
|
||
name: 'Délai d’approvisionnement (jours)',
|
||
type: 'number',
|
||
},
|
||
];
|
||
|
||
const hydraulicProductType = await createProductType(
|
||
'Produit hydraulique standard',
|
||
'hydraulic-product',
|
||
'Produits compatibles avec les centrales hydrauliques',
|
||
hydraulicProductFields,
|
||
);
|
||
|
||
console.log('Création des produits…');
|
||
const pumpProduct = await createProduct({
|
||
name: 'Pompe PX-300 Fournisseur A',
|
||
reference: 'PRD-PX-300-A',
|
||
supplierPrice: 1520,
|
||
typeId: hydraulicProductType.type.id,
|
||
fieldValues: {
|
||
Fournisseur: 'HydrauParts',
|
||
'Garantie (mois)': '24',
|
||
'Délai d’approvisionnement (jours)': '21',
|
||
},
|
||
});
|
||
|
||
const coolingProduct = await createProduct({
|
||
name: 'Module de refroidissement AC-50 - OEM',
|
||
reference: 'PRD-AC-50',
|
||
supplierPrice: 1980,
|
||
typeId: hydraulicProductType.type.id,
|
||
fieldValues: {
|
||
Fournisseur: 'ThermoTech',
|
||
'Garantie (mois)': '18',
|
||
'Délai d’approvisionnement (jours)': '28',
|
||
},
|
||
});
|
||
|
||
console.log('Association des produits aux pièces…');
|
||
await prisma.piece.update({
|
||
where: { id: pumpPiece.id },
|
||
data: {
|
||
product: {
|
||
connect: { id: pumpProduct.id },
|
||
},
|
||
},
|
||
});
|
||
|
||
console.log('Création des types de composants…');
|
||
const coolingComponentFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Type de fluide', type: 'text', required: true },
|
||
{ name: 'Puissance thermique (kW)', type: 'number', required: true },
|
||
{ name: 'Température max (°C)', type: 'number' },
|
||
{ name: 'Débit eau (L/min)', type: 'number' },
|
||
];
|
||
|
||
const coolingComponentType = await createComponentType(
|
||
'Module de refroidissement',
|
||
'cooling-module',
|
||
'Modules compacts pour dissipation thermique du circuit hydraulique',
|
||
coolingComponentFields,
|
||
{
|
||
customFields: coolingComponentFields.map((field) => ({
|
||
name: field.name,
|
||
key: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
})),
|
||
pieces: [
|
||
{
|
||
typePieceId: fanPieceType.type.id,
|
||
role: 'Ventilation principale',
|
||
},
|
||
],
|
||
subcomponents: [],
|
||
},
|
||
);
|
||
|
||
const frameComponentFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Matière', type: 'text', required: true },
|
||
{ name: 'Charge admissible (kg)', type: 'number', required: true },
|
||
{ name: 'Revêtement', type: 'text' },
|
||
{ name: 'Points de levage', type: 'number' },
|
||
];
|
||
|
||
const frameComponentType = await createComponentType(
|
||
'Châssis structurel',
|
||
'structural-frame',
|
||
'Châssis mécano-soudé pour unités hydrauliques',
|
||
frameComponentFields,
|
||
{
|
||
customFields: frameComponentFields.map((field) => ({
|
||
name: field.name,
|
||
key: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
})),
|
||
pieces: [],
|
||
subcomponents: [],
|
||
},
|
||
);
|
||
|
||
const powerUnitComponentFields: {
|
||
name: string;
|
||
type: 'text' | 'number' | 'select' | 'boolean' | 'date';
|
||
required?: boolean;
|
||
options?: string[];
|
||
}[] = [
|
||
{ name: 'Pression service (bar)', type: 'number', required: true },
|
||
{ name: 'Débit maxi (L/min)', type: 'number', required: true },
|
||
{ name: 'Niveau sonore (dB)', type: 'number' },
|
||
{ name: 'Indice de protection', type: 'text' },
|
||
];
|
||
|
||
const powerUnitComponentType = await createComponentType(
|
||
'Centrale hydraulique',
|
||
'hydraulic-power-unit',
|
||
'Unités hydrauliques complètes pour machines industrielles',
|
||
powerUnitComponentFields,
|
||
{
|
||
customFields: powerUnitComponentFields.map((field) => ({
|
||
name: field.name,
|
||
key: field.name,
|
||
type: field.type,
|
||
required: field.required ?? false,
|
||
})),
|
||
pieces: [
|
||
{
|
||
typePieceId: pumpPieceType.type.id,
|
||
role: 'Pompe principale',
|
||
},
|
||
{
|
||
typePieceId: reservoirPieceType.type.id,
|
||
role: 'Réservoir d’huile',
|
||
},
|
||
],
|
||
subcomponents: [
|
||
{
|
||
typeComposantId: coolingComponentType.type.id,
|
||
alias: 'Module de refroidissement',
|
||
},
|
||
{
|
||
typeComposantId: frameComponentType.type.id,
|
||
alias: 'Châssis structurel',
|
||
},
|
||
],
|
||
},
|
||
);
|
||
|
||
console.log('Création des composants (sous-ensembles)…');
|
||
const coolingModule = await createComponent({
|
||
name: 'Module de refroidissement AquaCool 50',
|
||
reference: 'AC-50',
|
||
price: 2450,
|
||
typeId: coolingComponentType.type.id,
|
||
fieldValues: {
|
||
'Type de fluide': 'Huile minérale',
|
||
'Puissance thermique (kW)': '35',
|
||
'Température max (°C)': '85',
|
||
'Débit eau (L/min)': '65',
|
||
},
|
||
structure: {
|
||
path: 'root',
|
||
pieces: [
|
||
{
|
||
path: 'root:piece-0',
|
||
definition: {
|
||
typePieceId: fanPieceType.type.id,
|
||
},
|
||
selectedPieceId: fanPiece.id,
|
||
},
|
||
],
|
||
subcomponents: [],
|
||
} as Prisma.InputJsonValue,
|
||
});
|
||
|
||
await prisma.composant.update({
|
||
where: { id: coolingModule.id },
|
||
data: {
|
||
product: {
|
||
connect: { id: coolingProduct.id },
|
||
},
|
||
},
|
||
});
|
||
|
||
const structuralFrame = await createComponent({
|
||
name: 'Châssis structurel XC-800',
|
||
reference: 'FRAME-XC800',
|
||
price: 1280,
|
||
typeId: frameComponentType.type.id,
|
||
fieldValues: {
|
||
Matière: 'Acier S355',
|
||
'Charge admissible (kg)': '1800',
|
||
Revêtement: 'Peinture epoxy',
|
||
'Points de levage': '4',
|
||
},
|
||
});
|
||
|
||
console.log('Création du composant principal…');
|
||
await createComponent({
|
||
name: 'Centrale hydraulique HX-500',
|
||
reference: 'HX-500',
|
||
price: 12900,
|
||
typeId: powerUnitComponentType.type.id,
|
||
fieldValues: {
|
||
'Pression service (bar)': '210',
|
||
'Débit maxi (L/min)': '320',
|
||
'Niveau sonore (dB)': '72',
|
||
'Indice de protection': 'IP54',
|
||
},
|
||
structure: {
|
||
path: 'root',
|
||
pieces: [
|
||
{
|
||
path: 'root:piece-0',
|
||
definition: {
|
||
typePieceId: pumpPieceType.type.id,
|
||
},
|
||
selectedPieceId: pumpPiece.id,
|
||
},
|
||
{
|
||
path: 'root:piece-1',
|
||
definition: {
|
||
typePieceId: reservoirPieceType.type.id,
|
||
},
|
||
selectedPieceId: reservoirPiece.id,
|
||
},
|
||
],
|
||
subcomponents: [
|
||
{
|
||
path: 'root:sub-0',
|
||
definition: {
|
||
alias: 'Module de refroidissement',
|
||
typeComposantId: coolingComponentType.type.id,
|
||
},
|
||
selectedComponentId: coolingModule.id,
|
||
},
|
||
{
|
||
path: 'root:sub-1',
|
||
definition: {
|
||
alias: 'Châssis structurel',
|
||
typeComposantId: frameComponentType.type.id,
|
||
},
|
||
selectedComponentId: structuralFrame.id,
|
||
},
|
||
],
|
||
} as Prisma.InputJsonValue,
|
||
});
|
||
|
||
console.log('Population terminée ✅');
|
||
}
|
||
|
||
main()
|
||
.catch((error) => {
|
||
console.error(error);
|
||
process.exit(1);
|
||
})
|
||
.finally(async () => {
|
||
await prisma.$disconnect();
|
||
});
|