merge: demo catalogue fixtures
This commit is contained in:
@@ -51,14 +51,175 @@ function daysFromNow(n: number): Date {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
interface DemoCategories {
|
||||||
// Idempotence : on ne recharge pas si déjà présent.
|
ordinateur: number;
|
||||||
const witness = await prisma.utilisateur.findUnique({ where: { email: WITNESS_EMAIL } });
|
video: number;
|
||||||
if (witness) {
|
tablette: number;
|
||||||
console.log('[fixtures] deja chargees — rien a faire');
|
camera: number;
|
||||||
return;
|
audio: number;
|
||||||
|
cable: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DemoMateriel {
|
||||||
|
nom: string;
|
||||||
|
marque: string;
|
||||||
|
modele: string;
|
||||||
|
reference: string;
|
||||||
|
numeroInventaire: string;
|
||||||
|
numeroSerie: string;
|
||||||
|
etatGeneral: string;
|
||||||
|
categorieId: number;
|
||||||
|
accessoires?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assurerAccessoire(nom: string, description: string): Promise<number> {
|
||||||
|
const existant = await prisma.accessoire.findFirst({ where: { nom } });
|
||||||
|
if (existant) {
|
||||||
|
return existant.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const accessoire = await prisma.accessoire.create({ data: { nom, description } });
|
||||||
|
return accessoire.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assurerMaterielDemo(data: DemoMateriel, campusId: number): Promise<void> {
|
||||||
|
let materiel = await prisma.materiel.findFirst({ where: { reference: data.reference } });
|
||||||
|
|
||||||
|
if (!materiel) {
|
||||||
|
materiel = await prisma.materiel.create({
|
||||||
|
data: {
|
||||||
|
nom: data.nom,
|
||||||
|
marque: data.marque,
|
||||||
|
modele: data.modele,
|
||||||
|
reference: data.reference,
|
||||||
|
numeroInventaire: data.numeroInventaire,
|
||||||
|
numeroSerie: data.numeroSerie,
|
||||||
|
statut: 'DISPONIBLE',
|
||||||
|
etatGeneral: data.etatGeneral,
|
||||||
|
categorieId: data.categorieId,
|
||||||
|
campusId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const nomAccessoire of data.accessoires ?? []) {
|
||||||
|
const accessoireId = await assurerAccessoire(nomAccessoire, `Accessoire ${nomAccessoire}.`);
|
||||||
|
const liaison = await prisma.materielAccessoire.findFirst({
|
||||||
|
where: { materielId: materiel.id, accessoireId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!liaison) {
|
||||||
|
await prisma.materielAccessoire.create({
|
||||||
|
data: {
|
||||||
|
materielId: materiel.id,
|
||||||
|
accessoireId,
|
||||||
|
quantiteAttendue: 1,
|
||||||
|
obligatoire: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assurerCatalogueDemo(campusId: number, categories: DemoCategories): Promise<void> {
|
||||||
|
const materiels: DemoMateriel[] = [
|
||||||
|
{
|
||||||
|
nom: 'PC Lenovo ThinkPad E14',
|
||||||
|
marque: 'Lenovo',
|
||||||
|
modele: 'ThinkPad E14',
|
||||||
|
reference: 'REF-PC-003',
|
||||||
|
numeroInventaire: 'INV-PC-003',
|
||||||
|
numeroSerie: 'SN-LENOVO-003',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.ordinateur,
|
||||||
|
accessoires: ['Chargeur', 'Souris', 'Housse'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'MacBook Air M2',
|
||||||
|
marque: 'Apple',
|
||||||
|
modele: 'MacBook Air 13',
|
||||||
|
reference: 'REF-PC-004',
|
||||||
|
numeroInventaire: 'INV-PC-004',
|
||||||
|
numeroSerie: 'SN-MBA-004',
|
||||||
|
etatGeneral: 'Tres bon etat',
|
||||||
|
categorieId: categories.ordinateur,
|
||||||
|
accessoires: ['Chargeur USB-C', 'Housse'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'Microsoft Surface Pro',
|
||||||
|
marque: 'Microsoft',
|
||||||
|
modele: 'Surface Pro 9',
|
||||||
|
reference: 'REF-TAB-002',
|
||||||
|
numeroInventaire: 'INV-TAB-002',
|
||||||
|
numeroSerie: 'SN-SURFACE-002',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.tablette,
|
||||||
|
accessoires: ['Clavier Surface', 'Stylet'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'Vidéoprojecteur Epson EB-X49',
|
||||||
|
marque: 'Epson',
|
||||||
|
modele: 'EB-X49',
|
||||||
|
reference: 'REF-VP-002',
|
||||||
|
numeroInventaire: 'INV-VP-002',
|
||||||
|
numeroSerie: 'SN-EPSON-002',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.video,
|
||||||
|
accessoires: ['Telecommande', 'Cable HDMI'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'Caméra Canon EOS M50',
|
||||||
|
marque: 'Canon',
|
||||||
|
modele: 'EOS M50',
|
||||||
|
reference: 'REF-CAM-002',
|
||||||
|
numeroInventaire: 'INV-CAM-002',
|
||||||
|
numeroSerie: 'SN-CANON-002',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.camera,
|
||||||
|
accessoires: ['Batterie', 'Carte SD', 'Housse'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'Casque Jabra Evolve',
|
||||||
|
marque: 'Jabra',
|
||||||
|
modele: 'Evolve 40',
|
||||||
|
reference: 'REF-AUD-002',
|
||||||
|
numeroInventaire: 'INV-AUD-002',
|
||||||
|
numeroSerie: 'SN-JABRA-002',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.audio,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'Kit câbles HDMI / USB-C',
|
||||||
|
marque: 'ENSUP',
|
||||||
|
modele: 'Kit connectique',
|
||||||
|
reference: 'REF-CAB-001',
|
||||||
|
numeroInventaire: 'INV-CAB-001',
|
||||||
|
numeroSerie: 'SN-CABLE-001',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.cable,
|
||||||
|
accessoires: ['Cable HDMI', 'Adaptateur USB-C'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nom: 'Enceinte Bluetooth JBL',
|
||||||
|
marque: 'JBL',
|
||||||
|
modele: 'Flip 6',
|
||||||
|
reference: 'REF-AUD-003',
|
||||||
|
numeroInventaire: 'INV-AUD-003',
|
||||||
|
numeroSerie: 'SN-JBL-003',
|
||||||
|
etatGeneral: 'Bon etat',
|
||||||
|
categorieId: categories.audio,
|
||||||
|
accessoires: ['Cable USB-C'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const materiel of materiels) {
|
||||||
|
await assurerMaterielDemo(materiel, campusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[fixtures] ${materiels.length} materiels de catalogue assures`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main(): Promise<void> {
|
||||||
// Références (doivent exister via le seed).
|
// Références (doivent exister via le seed).
|
||||||
const roleEtudiant = required(
|
const roleEtudiant = required(
|
||||||
await prisma.role.findUnique({ where: { code: 'ETUDIANT' } }),
|
await prisma.role.findUnique({ where: { code: 'ETUDIANT' } }),
|
||||||
@@ -100,6 +261,28 @@ async function main(): Promise<void> {
|
|||||||
await prisma.categorieMateriel.findFirst({ where: { nom: 'Périphérique audio' } }),
|
await prisma.categorieMateriel.findFirst({ where: { nom: 'Périphérique audio' } }),
|
||||||
'Categorie Périphérique audio manquante',
|
'Categorie Périphérique audio manquante',
|
||||||
);
|
);
|
||||||
|
const catCable = required(
|
||||||
|
await prisma.categorieMateriel.findFirst({ where: { nom: 'Câble / Adaptateur' } }),
|
||||||
|
'Categorie Câble / Adaptateur manquante',
|
||||||
|
);
|
||||||
|
|
||||||
|
const demoCategories: DemoCategories = {
|
||||||
|
ordinateur: catOrdi.id,
|
||||||
|
video: catVideo.id,
|
||||||
|
tablette: catTablette.id,
|
||||||
|
camera: catCamera.id,
|
||||||
|
audio: catAudio.id,
|
||||||
|
cable: catCable.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Idempotence : si les fixtures de base existent déjà, on assure seulement
|
||||||
|
// les matériels de catalogue ajoutés après coup.
|
||||||
|
const witness = await prisma.utilisateur.findUnique({ where: { email: WITNESS_EMAIL } });
|
||||||
|
if (witness) {
|
||||||
|
await assurerCatalogueDemo(campus.id, demoCategories);
|
||||||
|
console.log('[fixtures] deja chargees — catalogue demo assure');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Utilisateurs : 3 étudiants (2 info @ensitech.eu, 1 autre @ensup.eu) + 1 responsable.
|
// Utilisateurs : 3 étudiants (2 info @ensitech.eu, 1 autre @ensup.eu) + 1 responsable.
|
||||||
const marie = await prisma.utilisateur.create({
|
const marie = await prisma.utilisateur.create({
|
||||||
@@ -280,6 +463,7 @@ async function main(): Promise<void> {
|
|||||||
{ materielId: camera.id, accessoireId: chargeur.id, quantiteAttendue: 1, obligatoire: true },
|
{ materielId: camera.id, accessoireId: chargeur.id, quantiteAttendue: 1, obligatoire: true },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
await assurerCatalogueDemo(campus.id, demoCategories);
|
||||||
|
|
||||||
// Emprunt 1 — EN_COURS (Marie / PC Dell) + checklist de départ.
|
// Emprunt 1 — EN_COURS (Marie / PC Dell) + checklist de départ.
|
||||||
const empruntEnCours = await prisma.emprunt.create({
|
const empruntEnCours = await prisma.emprunt.create({
|
||||||
|
|||||||
@@ -229,6 +229,13 @@ En terminal interactif (VS Code), `migrate dev` fonctionne normalement (taper `y
|
|||||||
- Confirmation alimentée par la réponse API (`id`, `dateEmprunt`, matériel renvoyé).
|
- Confirmation alimentée par la réponse API (`id`, `dateEmprunt`, matériel renvoyé).
|
||||||
- Testé sans mutation de données : `POST /api/emprunts` avec checklist vide renvoie bien 400 `La checklist de depart est obligatoire (RG11)`.
|
- Testé sans mutation de données : `POST /api/emprunts` avec checklist vide renvoie bien 400 `La checklist de depart est obligatoire (RG11)`.
|
||||||
|
|
||||||
|
### Étape 29 — Données de démonstration catalogue
|
||||||
|
- Branche dédiée `feat/demo-catalogue-fixtures` créée après merge de `feat/frontend-emprunt-api` dans `develop`.
|
||||||
|
- `prisma/fixtures.ts` enrichi avec un catalogue de démonstration idempotent : si les fixtures de base existent déjà, le script assure seulement les matériels de catalogue manquants.
|
||||||
|
- 8 matériels disponibles ajoutés : Lenovo ThinkPad, MacBook Air, Surface Pro, vidéoprojecteur Epson, caméra Canon, casque Jabra, kit câbles HDMI/USB-C, enceinte JBL.
|
||||||
|
- Accessoires associés assurés sans doublon logique par recherche de nom/référence avant création.
|
||||||
|
- Vérifié en réel : `npm run fixtures` OK ; `GET /api/materiels` pour Lucas renvoie 10 matériels disponibles.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Dernière mise à jour : 2026-07-07 — Catalogue, détail matériel et création d'emprunt frontend branchés sur l'API backend.*
|
*Dernière mise à jour : 2026-07-07 — Catalogue enrichi, détail matériel et création d'emprunt frontend branchés sur l'API backend.*
|
||||||
|
|||||||
Reference in New Issue
Block a user