Migrate away from legacy component and piece models

This commit is contained in:
MatthieuTD
2025-10-02 15:44:02 +02:00
parent 44fd4bb8c7
commit c23ba3a587
34 changed files with 1821 additions and 1825 deletions

View File

@@ -16,7 +16,6 @@ export const COMPONENT_WITH_RELATIONS_INCLUDE = {
customFields: true,
},
},
composantModel: true,
typeMachineComponentRequirement: {
include: {
typeComposant: {
@@ -40,7 +39,6 @@ export const COMPONENT_WITH_RELATIONS_INCLUDE = {
},
},
constructeur: true,
pieceModel: true,
typeMachinePieceRequirement: {
include: {
typePiece: {

View File

@@ -1,4 +1,8 @@
import { ModelTypeMapper } from './model-type.mapper';
import {
ComponentModelStructureSchema,
PieceModelStructureSchema,
} from '../../shared/schemas/inventory';
describe('ModelTypeMapper', () => {
it('should map component create input', () => {
@@ -8,9 +12,30 @@ describe('ModelTypeMapper', () => {
customFields: [
{ name: 'Field', type: 'string', required: false, options: [] },
],
structure: {
pieces: [
{
familyCode: 'bolt',
role: 'Fixation',
},
],
customFields: [
{
key: 'color',
value: 'red',
},
],
subcomponents: [
{
familyCode: 'sub-family',
alias: 'Secondary',
},
],
},
} as any;
const input = ModelTypeMapper.toComponentCreateInput(dto, 'code');
const skeleton = ComponentModelStructureSchema.parse(dto.structure);
const input = ModelTypeMapper.toComponentCreateInput(dto, 'code', skeleton);
expect(input).toMatchObject({
name: 'Comp',
@@ -19,6 +44,72 @@ describe('ModelTypeMapper', () => {
notes: 'Desc',
});
expect(input.customFields?.create?.[0]).toMatchObject({ name: 'Field' });
expect((input as any).componentSkeleton).toEqual({
pieces: [
{
familyCode: 'bolt',
role: 'Fixation',
},
],
customFields: [
{
key: 'color',
value: 'red',
},
],
subcomponents: [
{
familyCode: 'sub-family',
alias: 'Secondary',
},
],
});
});
it('should map piece create input with skeleton', () => {
const dto = {
name: 'Piece type',
description: 'Desc',
customFields: [],
structure: {
customFields: [
{
name: 'Length',
value: 12,
type: 'number',
required: true,
},
{
key: 'color',
value: 'blue',
optionsText: 'blue\nred',
},
],
typePieceId: ' piece-id ',
standard: 'ISO',
},
} as any;
const skeleton = PieceModelStructureSchema.parse(dto.structure);
const input = ModelTypeMapper.toPieceCreateInput(dto, 'code', skeleton);
expect((input as any).pieceSkeleton).toEqual({
customFields: [
{
name: 'Length',
value: 12,
type: 'number',
required: true,
},
{
name: 'color',
value: 'blue',
options: ['blue', 'red'],
},
],
typePieceId: 'piece-id',
standard: 'ISO',
});
});
it('should map piece model type to DTO shape', () => {
@@ -26,7 +117,7 @@ describe('ModelTypeMapper', () => {
id: '1',
name: 'Piece',
pieceCustomFields: [{ id: 'cf' }],
pieceModels: [{ id: 'model' }],
pieceSkeleton: { customFields: [{ name: 'Length' }] },
pieceRequirements: [{ id: 'req' }],
pieces: [{ id: 'piece' }],
});
@@ -34,18 +125,21 @@ describe('ModelTypeMapper', () => {
expect(mapped).toMatchObject({
id: '1',
customFields: [{ id: 'cf' }],
models: [{ id: 'model' }],
pieceRequirements: [{ id: 'req' }],
pieces: [{ id: 'piece' }],
structure: { customFields: [{ name: 'Length' }] },
});
});
it('should map piece update input', () => {
const input = ModelTypeMapper.toPieceUpdateInput({
const dto: any = {
name: 'New',
description: 'D',
customFields: [],
} as any);
structure: { customFields: [{ name: 'Length' }] },
};
const skeleton = PieceModelStructureSchema.parse(dto.structure);
const input = ModelTypeMapper.toPieceUpdateInput(dto, skeleton);
expect(input).toMatchObject({
name: 'New',
@@ -53,5 +147,36 @@ describe('ModelTypeMapper', () => {
notes: 'D',
});
expect(input.pieceCustomFields).toBeUndefined();
expect((input as any).pieceSkeleton).toEqual({
customFields: [
{
name: 'Length',
},
],
});
});
it('should map component update input with skeleton', () => {
const dto: any = {
name: 'Updated',
structure: {
pieces: [{ typePieceId: 'piece-1' }],
customFields: [],
subcomponents: [],
},
};
const skeleton = ComponentModelStructureSchema.parse(dto.structure);
const input = ModelTypeMapper.toComponentUpdateInput(dto, skeleton);
expect(input).toMatchObject({ name: 'Updated' });
expect((input as any).componentSkeleton).toEqual({
pieces: [
{
typePieceId: 'piece-1',
},
],
customFields: [],
subcomponents: [],
});
});
});

View File

@@ -5,17 +5,19 @@ import {
UpdateTypeComposantDto,
UpdateTypePieceDto,
} from '../../shared/dto/type.dto';
import type {
ComponentModelStructure,
PieceModelStructure,
} from '../../shared/types/inventory';
import { CUSTOM_FIELD_SELECT } from '../constants/custom-field.constant';
export const COMPONENT_TYPE_INCLUDE: Prisma.ModelTypeInclude = {
customFields: { select: CUSTOM_FIELD_SELECT },
composants: true,
models: true,
};
export const PIECE_TYPE_INCLUDE: Prisma.ModelTypeInclude = {
pieceCustomFields: { select: CUSTOM_FIELD_SELECT },
pieceModels: true,
pieceRequirements: true,
pieces: true,
};
@@ -29,6 +31,7 @@ export class ModelTypeMapper {
static toComponentCreateInput(
dto: CreateTypeComposantDto,
code: string,
skeleton?: ComponentModelStructure,
): ModelTypeCreateWithoutCategory {
const { customFields, description, name } = dto;
@@ -47,11 +50,13 @@ export class ModelTypeMapper {
})),
}
: undefined,
...(skeleton ? { componentSkeleton: skeleton as Prisma.InputJsonValue } : {}),
};
}
static toComponentUpdateInput(
dto: UpdateTypeComposantDto,
skeleton?: ComponentModelStructure,
): Prisma.ModelTypeUpdateInput {
const { customFields, description, name } = dto;
const data: Prisma.ModelTypeUpdateInput = {};
@@ -69,12 +74,17 @@ export class ModelTypeMapper {
data.customFields = undefined;
}
if (skeleton !== undefined) {
data.componentSkeleton = skeleton as Prisma.InputJsonValue;
}
return data;
}
static toPieceCreateInput(
dto: CreateTypePieceDto,
code: string,
skeleton?: PieceModelStructure,
): ModelTypeCreateWithoutCategory {
const { customFields, description, name } = dto;
@@ -93,11 +103,13 @@ export class ModelTypeMapper {
})),
}
: undefined,
...(skeleton ? { pieceSkeleton: skeleton as Prisma.InputJsonValue } : {}),
};
}
static toPieceUpdateInput(
dto: UpdateTypePieceDto,
skeleton?: PieceModelStructure,
): Prisma.ModelTypeUpdateInput {
const { customFields, description, name } = dto;
const data: Prisma.ModelTypeUpdateInput = {};
@@ -115,6 +127,10 @@ export class ModelTypeMapper {
data.pieceCustomFields = undefined;
}
if (skeleton !== undefined) {
data.pieceSkeleton = skeleton as Prisma.InputJsonValue;
}
return data;
}
@@ -125,18 +141,18 @@ export class ModelTypeMapper {
const {
pieceCustomFields,
pieceModels,
pieceRequirements,
pieces,
pieceSkeleton,
...rest
} = modelType;
return {
...rest,
customFields: pieceCustomFields ?? [],
models: pieceModels ?? [],
pieceRequirements: pieceRequirements ?? [],
pieces: pieces ?? [],
structure: pieceSkeleton ?? null,
};
}

View File

@@ -1,58 +0,0 @@
import { Injectable } from '@nestjs/common';
import { Prisma, PrismaClient } from '@prisma/client';
import { PrismaService } from '../../prisma/prisma.service';
@Injectable()
export class ComposantModelsRepository {
constructor(private readonly prisma: PrismaService) {}
private get client(): PrismaClient {
return this.prisma;
}
async create(
data: Prisma.ComposantModelCreateInput,
include?: Prisma.ComposantModelInclude,
) {
return this.client.composantModel.create({
data,
include,
});
}
async findAll(
typeComposantId?: string,
include?: Prisma.ComposantModelInclude,
) {
return this.client.composantModel.findMany({
where: typeComposantId ? { typeComposantId } : undefined,
include,
orderBy: { name: 'asc' },
});
}
async findOne(id: string, include?: Prisma.ComposantModelInclude) {
return this.client.composantModel.findUnique({
where: { id },
include,
});
}
async update(
id: string,
data: Prisma.ComposantModelUpdateInput,
include?: Prisma.ComposantModelInclude,
) {
return this.client.composantModel.update({
where: { id },
data,
include,
});
}
async delete(id: string) {
return this.client.composantModel.delete({
where: { id },
});
}
}

View File

@@ -1,55 +0,0 @@
import { Injectable } from '@nestjs/common';
import { Prisma, PrismaClient } from '@prisma/client';
import { PrismaService } from '../../prisma/prisma.service';
@Injectable()
export class PieceModelsRepository {
constructor(private readonly prisma: PrismaService) {}
private get client(): PrismaClient {
return this.prisma;
}
async create(
data: Prisma.PieceModelCreateInput,
include?: Prisma.PieceModelInclude,
) {
return this.client.pieceModel.create({
data,
include,
});
}
async findAll(typePieceId?: string, include?: Prisma.PieceModelInclude) {
return this.client.pieceModel.findMany({
where: typePieceId ? { typePieceId } : undefined,
include,
orderBy: { name: 'asc' },
});
}
async findOne(id: string, include?: Prisma.PieceModelInclude) {
return this.client.pieceModel.findUnique({
where: { id },
include,
});
}
async update(
id: string,
data: Prisma.PieceModelUpdateInput,
include?: Prisma.PieceModelInclude,
) {
return this.client.pieceModel.update({
where: { id },
data,
include,
});
}
async delete(id: string) {
return this.client.pieceModel.delete({
where: { id },
});
}
}