This repository has been archived on 2026-04-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Inventory_backend/prisma/seed.ts
2025-09-30 15:58:45 +02:00

380 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* eslint-disable no-console */
import { PrismaClient, ModelCategory } from '@prisma/client';
const prisma = new PrismaClient();
// --------- Helpers -----------------------------------------------------------
async function findOrCreateModelType(params: {
code: string;
name: string;
category: ModelCategory;
description?: string | null;
notes?: string | null;
}) {
const { code, name, category, description = null, notes = null } = params;
const existing = await prisma.modelType.findUnique({ where: { code } }).catch(() => null);
if (existing) return existing;
return prisma.modelType.create({
data: { code, name, category, description, notes },
});
}
async function findOrCreateComposantModel(params: {
code: string;
name: string;
typeCode: string; // ModelType (category: COMPONENT)
manufacturerName?: string | null;
description?: string | null;
}) {
const { code, name, typeCode, manufacturerName = null, description = null } = params;
const existing = await prisma.composantModel.findUnique({ where: { code } }).catch(() => null);
if (existing) return existing;
const type = await prisma.modelType.findUnique({ where: { code: typeCode } });
if (!type) throw new Error(`ComposantModel: type '${typeCode}' introuvable`);
const manufacturer = manufacturerName
? await prisma.constructeur.upsert({
where: { name: manufacturerName },
create: { name: manufacturerName },
update: {},
})
: null;
return prisma.composantModel.create({
data: {
code,
name,
description,
typeComposant: { connect: { id: type.id } },
...(manufacturer ? { constructeur: { connect: { id: manufacturer.id } } } : {}),
},
});
}
async function findOrCreatePieceModel(params: {
code: string;
name: string;
typeCode: string; // ModelType (category: PIECE)
manufacturerName?: string | null;
description?: string | null;
}) {
const { code, name, typeCode, manufacturerName = null, description = null } = params;
const existing = await prisma.pieceModel.findUnique({ where: { code } }).catch(() => null);
if (existing) return existing;
const type = await prisma.modelType.findUnique({ where: { code: typeCode } });
if (!type) throw new Error(`PieceModel: type '${typeCode}' introuvable`);
const manufacturer = manufacturerName
? await prisma.constructeur.upsert({
where: { name: manufacturerName },
create: { name: manufacturerName },
update: {},
})
: null;
return prisma.pieceModel.create({
data: {
code,
name,
description,
typePiece: { connect: { id: type.id } },
...(manufacturer ? { constructeur: { connect: { id: manufacturer.id } } } : {}),
},
});
}
async function upsertTypeMachine(params: {
code: string;
name: string;
category?: string | null;
description?: string | null;
}) {
const { code, name, category = 'Convoyage', description = null } = params;
// Beaucoup de schémas mettent un unique sur name OU code. On essaye les deux.
const existingByCode = await prisma.typeMachine.findUnique({ where: { code } }).catch(() => null);
if (existingByCode) return existingByCode;
const existingByName = await prisma.typeMachine.findUnique({ where: { name } }).catch(() => null);
if (existingByName) return existingByName;
return prisma.typeMachine.create({
data: {
code,
name,
category,
description,
},
});
}
async function addTypeMachineCustomFields(typeMachineId: string) {
// upsert par (typeMachineId, name) si le schéma le permet, sinon find/create
const defs = [
{ name: 'capacite_t_h', type: 'NUMBER', required: false, options: null },
{ name: 'hauteur_m', type: 'NUMBER', required: false, options: null },
{ name: 'sens', type: 'SELECT', required: false, options: ['montant', 'descendant'] },
{ name: 'vitesse_m_s', type: 'NUMBER', required: false, options: null },
];
for (const d of defs) {
const already = await prisma.customField.findFirst({
where: { name: d.name, typeMachineId },
});
if (!already) {
await prisma.customField.create({
data: {
name: d.name,
type: d.type as any,
required: d.required,
options: d.options as any,
typeMachine: { connect: { id: typeMachineId } },
},
});
}
}
}
async function addRequirements(params: {
typeMachineId: string;
components: Array<{
label: string;
typeCode: string; // ModelType (COMPONENT)
minCount?: number;
maxCount?: number | null;
required?: boolean;
allowNewModels?: boolean;
}>;
pieces: Array<{
label: string;
typeCode: string; // ModelType (PIECE)
minCount?: number;
maxCount?: number | null;
required?: boolean;
allowNewModels?: boolean;
}>;
}) {
const { typeMachineId, components, pieces } = params;
// Composants
for (const r of components) {
const type = await prisma.modelType.findUnique({ where: { code: r.typeCode } });
if (!type) throw new Error(`Requirement component: type '${r.typeCode}' introuvable`);
// Évite les doublons simples par (typeMachineId, typeComposantId, label)
const exists = await prisma.typeMachineComponentRequirement.findFirst({
where: {
typeMachineId,
typeComposantId: type.id,
label: r.label,
},
});
if (!exists) {
await prisma.typeMachineComponentRequirement.create({
data: {
typeMachine: { connect: { id: typeMachineId } },
typeComposant: { connect: { id: type.id } },
label: r.label,
minCount: r.minCount ?? 0,
maxCount: r.maxCount ?? null,
required: r.required ?? true,
allowNewModels: r.allowNewModels ?? true,
},
});
}
}
// Pièces
for (const r of pieces) {
const type = await prisma.modelType.findUnique({ where: { code: r.typeCode } });
if (!type) throw new Error(`Requirement piece: type '${r.typeCode}' introuvable`);
const exists = await prisma.typeMachinePieceRequirement.findFirst({
where: {
typeMachineId,
typePieceId: type.id,
label: r.label,
},
});
if (!exists) {
await prisma.typeMachinePieceRequirement.create({
data: {
typeMachine: { connect: { id: typeMachineId } },
typePiece: { connect: { id: type.id } },
label: r.label,
minCount: r.minCount ?? 0,
maxCount: r.maxCount ?? null,
required: r.required ?? false,
allowNewModels: r.allowNewModels ?? true,
},
});
}
}
}
// --------- Seed principal ----------------------------------------------------
async function main() {
// 1) Quelques constructeurs de base
await prisma.constructeur.upsert({
where: { name: 'SEW' },
update: {},
create: { name: 'SEW' },
});
await prisma.constructeur.upsert({
where: { name: 'NORD' },
update: {},
create: { name: 'NORD' },
});
await prisma.constructeur.upsert({
where: { name: 'SKF' },
update: {},
create: { name: 'SKF' },
});
// 2) Familles (ModelType)
// COMPONENT
const compTypes = [
{ code: 'elev-tete', name: 'Tête', category: ModelCategory.COMPONENT },
{ code: 'elev-pied', name: 'Pied', category: ModelCategory.COMPONENT },
{ code: 'elev-gaine', name: 'Gaine', category: ModelCategory.COMPONENT },
{ code: 'elev-entrainement', name: 'Entraînement', category: ModelCategory.COMPONENT },
{ code: 'elev-retour', name: 'Retour', category: ModelCategory.COMPONENT },
{ code: 'elev-sangle-chaine', name: 'Sangle / Chaîne', category: ModelCategory.COMPONENT },
{ code: 'elev-godets-comp', name: 'Rangée de godets', category: ModelCategory.COMPONENT },
];
// PIECE
const pieceTypes = [
{ code: 'roulement', name: 'Roulement', category: ModelCategory.PIECE },
{ code: 'courroie', name: 'Courroie', category: ModelCategory.PIECE },
{ code: 'visserie', name: 'Visserie', category: ModelCategory.PIECE },
{ code: 'joint', name: 'Joint', category: ModelCategory.PIECE },
{ code: 'capteur', name: 'Capteur', category: ModelCategory.PIECE },
{ code: 'moteur', name: 'Moteur électrique', category: ModelCategory.PIECE },
{ code: 'reducteur', name: 'Réducteur', category: ModelCategory.PIECE },
{ code: 'godet', name: 'Godet', category: ModelCategory.PIECE },
{ code: 'sangle', name: 'Sangle', category: ModelCategory.PIECE },
{ code: 'chaine', name: 'Chaîne', category: ModelCategory.PIECE },
];
for (const t of [...compTypes, ...pieceTypes]) {
await findOrCreateModelType(t);
}
// 3) Modèles (catalogues)
// Composants
await findOrCreateComposantModel({
code: 'tete-standard-500',
name: 'Tête standard 500',
typeCode: 'elev-tete',
manufacturerName: null,
description: 'Sortie latérale, trappe inspection, tambour dentraînement',
});
await findOrCreateComposantModel({
code: 'pied-standard-500',
name: 'Pied standard 500',
typeCode: 'elev-pied',
description: 'Trémie dalimentation, tambour de retour',
});
await findOrCreateComposantModel({
code: 'gaine-1m',
name: 'Gaine 1 m',
typeCode: 'elev-gaine',
});
await findOrCreateComposantModel({
code: 'drive-unit-sew',
name: 'Groupe moto-réducteur SEW',
typeCode: 'elev-entrainement',
manufacturerName: 'SEW',
});
await findOrCreateComposantModel({
code: 'belt-assembly',
name: 'Ensemble sangle + jonction',
typeCode: 'elev-sangle-chaine',
});
// Pièces
await findOrCreatePieceModel({
code: 'roulement-2208-skf',
name: 'Roulement 2208',
typeCode: 'roulement',
manufacturerName: 'SKF',
});
await findOrCreatePieceModel({
code: 'moteur-5-5kw',
name: 'Moteur 5.5 kW',
typeCode: 'moteur',
manufacturerName: 'SEW',
});
await findOrCreatePieceModel({
code: 'reducteur-sew-k',
name: 'Réducteur K',
typeCode: 'reducteur',
manufacturerName: 'SEW',
});
await findOrCreatePieceModel({
code: 'godet-2l-poly',
name: 'Godet 2 L poly',
typeCode: 'godet',
});
await findOrCreatePieceModel({
code: 'sangle-500mm-ep500',
name: 'Sangle 500 mm EP500',
typeCode: 'sangle',
});
// 4) TypeMachine “Élévateur à godets”
const elevType = await upsertTypeMachine({
code: 'elevateur_godets',
name: 'Élévateur à godets',
category: 'Convoyage',
description: 'Élévateur à godets vertical',
});
// Champs personnalisés du type
await addTypeMachineCustomFields(elevType.id);
// Requirements (groupes logiques implicites via label)
await addRequirements({
typeMachineId: elevType.id,
components: [
{ label: 'Tête', typeCode: 'elev-tete', minCount: 1, maxCount: 1, required: true },
{ label: 'Pied', typeCode: 'elev-pied', minCount: 1, maxCount: 1, required: true },
{ label: 'Gaines', typeCode: 'elev-gaine', minCount: 1, maxCount: null, required: true },
{ label: 'Entraînement', typeCode: 'elev-entrainement', minCount: 1, maxCount: 1, required: true, allowNewModels: true },
{ label: 'Retour', typeCode: 'elev-retour', minCount: 1, maxCount: 1, required: false },
{ label: 'Sangle/Chaîne', typeCode: 'elev-sangle-chaine', minCount: 1, maxCount: 1, required: true },
{ label: 'Rangée de godets', typeCode: 'elev-godets-comp', minCount: 1, maxCount: null, required: true },
],
pieces: [
{ label: 'Roulements darbres', typeCode: 'roulement', minCount: 2, maxCount: null, required: true },
{ label: 'Moteur', typeCode: 'moteur', minCount: 1, maxCount: 1, required: true },
{ label: 'Réducteur', typeCode: 'reducteur', minCount: 1, maxCount: 1, required: true },
{ label: 'Godets', typeCode: 'godet', minCount: 1, maxCount: null, required: true },
{ label: 'Sangle (si sangle)', typeCode: 'sangle', minCount: 1, maxCount: 1, required: false },
{ label: 'Chaîne (si chaîne)', typeCode: 'chaine', minCount: 1, maxCount: 2, required: false },
{ label: 'Capteurs', typeCode: 'capteur', minCount: 0, maxCount: 4, required: false },
{ label: 'Visserie', typeCode: 'visserie', minCount: 0, maxCount: null, required: false },
],
});
console.log('✅ Seed terminé.');
}
main()
.catch((e) => {
console.error('❌ Seed error:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});