WIP ad creation mapping

This commit is contained in:
Grégoire Chevalier 2023-05-22 17:23:46 +02:00
parent 954f26b2b3
commit bee5fef9ff
13 changed files with 348 additions and 227 deletions

View File

@ -11,7 +11,6 @@ import { Ad } from '../../domain/entities/ad';
import { CreateAdRequest } from '../../domain/dtos/create-ad.request';
import { CreateAdCommand } from '../../commands/create-ad.command';
import { DatabaseException } from '../../../database/exceptions/database.exception';
import { AddressDTO } from '../../domain/dtos/create.address.dto';
@UsePipes(
new RpcValidationPipe({
@ -43,9 +42,6 @@ export class AdController {
@GrpcMethod('AdsService', 'Create')
async createAd(data: CreateAdRequest): Promise<AdPresenter> {
try {
console.log('controler--------------------------------');
console.log(data);
console.log('-----------------------------------------');
const ad = await this._commandBus.execute(new CreateAdCommand(data));
return this._mapper.map(ad, Ad, AdPresenter);
} catch (e) {

View File

@ -1,34 +1,7 @@
import { Injectable } from '@nestjs/common';
import { AdRepository } from '../../../database/domain/ad-repository';
import { Ad } from '../../domain/entities/ad';
import { DatabaseException } from '../../../database/exceptions/database.exception';
import { Prisma } from '@prisma/client';
@Injectable()
export class AdsRepository extends AdRepository<Ad> {
protected _model = 'ad';
async create(entity: Partial<Ad> | any, include?: any): Promise<Ad> {
console.log('custom ad repo ');
console.log(entity);
console.log('*****************************************');
try {
const res = await this._prisma[this._model].create({
data: entity,
include: include,
});
return res;
} catch (e) {
console.log('repo error ');
console.log(e);
if (e instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseException(
Prisma.PrismaClientKnownRequestError.name,
e.code,
e.message,
);
} else {
throw new DatabaseException();
}
}
}
}

View File

@ -0,0 +1,125 @@
import { AutoMap } from '@automapper/classes';
import {
IsOptional,
IsString,
IsBoolean,
IsDate,
IsInt,
IsEnum,
ValidateNested,
IsUUID,
} from 'class-validator';
import { Frequency } from '../types/frequency.enum';
import { AddressCreation } from './address.creation';
export class AdCreation {
@IsUUID(4)
@AutoMap()
userUuid: string;
@IsBoolean()
@AutoMap()
driver: boolean;
@IsBoolean()
@AutoMap()
passenger: boolean;
@IsEnum(Frequency)
@AutoMap()
frequency: Frequency;
@IsDate()
@AutoMap()
fromDate: Date;
@IsDate()
@AutoMap()
toDate: Date;
@IsOptional()
@IsDate()
@AutoMap()
monTime?: string;
@IsOptional()
@IsString()
@AutoMap()
tueTime?: string;
@IsOptional()
@IsString()
@AutoMap()
wedTime?: string;
@IsOptional()
@IsString()
@AutoMap()
thuTime?: string;
@IsOptional()
@IsString()
@AutoMap()
friTime?: string;
@IsOptional()
@IsString()
@AutoMap()
satTime?: string;
@IsOptional()
@IsString()
@AutoMap()
sunTime?: string;
@IsInt()
@AutoMap()
monMargin: number;
@IsInt()
@AutoMap()
tueMargin: number;
@IsInt()
@AutoMap()
wedMargin: number;
@IsInt()
@AutoMap()
thuMargin: number;
@IsInt()
@AutoMap()
friMargin: number;
@IsInt()
@AutoMap()
satMargin: number;
@IsInt()
@AutoMap()
sunMargin: number;
@IsInt()
@AutoMap()
seatsDriver: number;
@IsInt()
@AutoMap()
seatsPassenger: number;
@IsBoolean()
@AutoMap()
strict: boolean;
@IsDate()
@AutoMap()
createdAt: Date;
@IsDate()
@AutoMap()
updatedAt?: Date;
@ValidateNested({ each: true })
@AutoMap()
addresses: { create: AddressCreation[] };
}

View File

@ -0,0 +1,32 @@
import { AutoMap } from '@automapper/classes';
import { IsInt } from 'class-validator';
export class AddressCreation {
@IsInt()
@AutoMap()
position: number;
@AutoMap()
lon: number;
@AutoMap()
lat: number;
@AutoMap()
name?: string;
@AutoMap()
houseNumber?: string;
@AutoMap()
street?: string;
@AutoMap()
locality: string;
@AutoMap()
postalCode: string;
@AutoMap()
country: string;
}

View File

@ -16,7 +16,7 @@ import { Transform, Type } from 'class-transformer';
import { mappingKeyToFrequency } from './utils/frequency.mapping';
import { MarginDTO } from './create.margin.dto';
import { ScheduleDTO } from './create.schedule.dto';
import { AddressDTO } from './create.address.dto';
import { AddressRequestDTO } from './create.address.request';
import { HasProperPassengerSeats } from './utils/has-passenger-seats.validator';
import { HasProperDriverSeats } from './utils/has-driver-seats.validator';
import { HasProperPositionIndexes } from './utils/address-position.validator';
@ -27,7 +27,6 @@ export class CreateAdRequest {
@AutoMap()
uuid?: string;
// TODO create validation rule to verify is user exists ??
@IsUUID(4)
@AutoMap()
userUuid: string;
@ -51,6 +50,7 @@ export class CreateAdRequest {
@AutoMap()
frequency: Frequency;
// TODO create a proper validator
@ValidateIf((ad) => ad.frequency === 'PUNCTUAL')
@Type(() => Date)
@IsDate()
@ -98,9 +98,9 @@ export class CreateAdRequest {
strict?: boolean;
@ArrayMinSize(2)
@Type(() => AddressDTO)
@Type(() => AddressRequestDTO)
@HasProperPositionIndexes()
@ValidateNested({ each: true })
@AutoMap()
addresses: AddressDTO[];
addresses: AddressRequestDTO[];
}

View File

@ -8,7 +8,7 @@ import {
IsUUID,
} from 'class-validator';
export class AddressDTO {
export class AddressRequestDTO {
@IsOptional()
@IsUUID(4)
@AutoMap()

View File

@ -1,7 +1,7 @@
import { ValidateBy, ValidationOptions, buildMessage } from 'class-validator';
import { AddressDTO } from '../create.address.dto';
import { AddressRequestDTO } from '../create.address.request';
export function hasProperPositionIndexes(value: AddressDTO[]) {
export function hasProperPositionIndexes(value: AddressRequestDTO[]) {
if (value.every((address) => address.position === undefined)) return true;
else if (value.every((address) => typeof address.position === 'number')) {
value.sort((a, b) => a.position - b.position);
@ -21,7 +21,7 @@ export function HasProperPositionIndexes(
name: '',
constraints: [],
validator: {
validate: (value: AddressDTO[]): boolean =>
validate: (value: AddressRequestDTO[]): boolean =>
hasProperPositionIndexes(value),
defaultMessage: buildMessage(
() =>

View File

@ -6,15 +6,16 @@ import { Messager } from '../../adapters/secondaries/messager';
import { AdsRepository } from '../../adapters/secondaries/ads.repository';
import { CreateAdCommand } from '../../commands/create-ad.command';
import { CreateAdRequest } from '../dtos/create-ad.request';
import { Ad } from '../entities/ad';
import { IProvideParams } from '../interfaces/param-provider.interface';
import { DefaultParams } from '../types/default-params.type';
import { Address } from '../entities/address';
import { AdCreation } from '../dtos/ad.creation';
import { Ad } from '../entities/ad';
@CommandHandler(CreateAdCommand)
export class CreateAdUseCase {
private readonly defaultParams: DefaultParams;
private ad: Ad;
private ad: AdCreation;
constructor(
private readonly _repository: AdsRepository,
private readonly _messager: Messager,
@ -26,50 +27,25 @@ export class CreateAdUseCase {
}
async execute(command: CreateAdCommand): Promise<Ad> {
console.log('before mapping ');
const entity: Ad = this._mapper.map(
this.ad = this._mapper.map(
command.createAdRequest,
CreateAdRequest,
Ad,
AdCreation,
);
typeof entity.monMargin === 'number'
? entity.monMargin
: (entity.monMargin = this.defaultParams.MON_MARGIN);
typeof entity.tueMargin === 'number'
? entity.tueMargin
: (entity.tueMargin = this.defaultParams.TUE_MARGIN);
typeof entity.wedMargin === 'number'
? entity.wedMargin
: (entity.wedMargin = this.defaultParams.WED_MARGIN);
typeof entity.thuMargin === 'number'
? entity.thuMargin
: (entity.thuMargin = this.defaultParams.THU_MARGIN);
typeof entity.friMargin === 'number'
? entity.friMargin
: (entity.friMargin = this.defaultParams.FRI_MARGIN);
typeof entity.satMargin === 'number'
? entity.satMargin
: (entity.satMargin = this.defaultParams.SAT_MARGIN);
typeof entity.sunMargin === 'number'
? entity.sunMargin
: (entity.sunMargin = this.defaultParams.SUN_MARGIN);
typeof entity.strict === 'boolean'
? entity.strict
: (entity.strict = this.defaultParams.STRICT);
this.setDefaultSchedule();
this.setDefaultAddressesPosition();
this.setDefaultDriverAndPassengerParameters();
this.setDefaultDistanceMargin();
if (typeof entity.addresses[0].position === 'undefined') {
for (let i = 0; i < entity.addresses.length; i++) {
entity.addresses[i].position = i;
}
}
try {
console.log('before ***********************************');
console.log(entity);
console.log('******************************************');
this.ad = await this._repository.create(entity);
// this._messager.publish('ad.create', JSON.stringify(ad));
// this._messager.publish('logging.ad.create.info', JSON.stringify(ad));
return this.ad;
console.log(this.ad);
const adCreated: Ad = await this._repository.create(this.ad);
this._messager.publish('ad.create', JSON.stringify(adCreated));
this._messager.publish(
'logging.ad.create.info',
JSON.stringify(adCreated),
);
return adCreated;
} catch (error) {
let key = 'logging.ad.create.crit';
if (error.message.includes('Already exists')) {
@ -85,107 +61,49 @@ export class CreateAdUseCase {
throw error;
}
}
setDefaultSchedule(): void {
if (this.ad.monMargin === undefined)
this.ad.monMargin = this.defaultParams.MON_MARGIN;
if (this.ad.tueMargin === undefined)
this.ad.tueMargin = this.defaultParams.TUE_MARGIN;
if (this.ad.wedMargin === undefined)
this.ad.wedMargin = this.defaultParams.WED_MARGIN;
if (this.ad.thuMargin === undefined)
this.ad.thuMargin = this.defaultParams.THU_MARGIN;
if (this.ad.friMargin === undefined)
this.ad.friMargin = this.defaultParams.FRI_MARGIN;
if (this.ad.satMargin === undefined)
this.ad.satMargin = this.defaultParams.SAT_MARGIN;
if (this.ad.sunMargin === undefined)
this.ad.sunMargin = this.defaultParams.SUN_MARGIN;
}
setDefaultDistanceMargin(): void {
if (this.ad.strict === undefined)
this.ad.strict = this.defaultParams.STRICT;
}
setDefaultDriverAndPassengerParameters(): void {
if (!this.ad.driver && !this.ad.passenger) {
this.ad.driver = this.defaultParams.DRIVER;
this.ad.seatsDriver = this.defaultParams.DRIVER_SEAT;
this.ad.passenger = this.defaultParams.PASSENGER;
this.ad.seatsPassenger = this.defaultParams.PASSENGER_SEATS;
} else {
if (!this.ad.driver) {
this.ad.driver = false;
this.ad.seatsDriver = 0;
}
if (!this.ad.passenger) {
this.ad.passenger = false;
this.ad.seatsPassenger = 0;
}
}
}
setDefaultAddressesPosition(): void {
if (this.ad.addresses.create[0].position === undefined) {
for (let i = 0; i < this.ad.addresses.create.length; i++) {
this.ad.addresses.create[i].position = i;
}
}
}
TransformPunctualToReccurent(): void {}
}
/*
repo error
PrismaClientValidationError:
Invalid `this._prisma[this._model].create()` invocation in
/usr/src/app/src/modules/ad/adapters/secondaries/ads.repository.ts:15:51
12 console.log(entity);
13 console.log('*****************************************');
14 try {
15 const res = await this._prisma[this._model].create({
data: {
uuid: undefined,
userUuid: '113e0000-0000-4000-a000-000000000000',
driver: true,
passenger: false,
frequency: 'RECURRENT',
fromDate: new Date('2023-01-15T00:00:00.000Z'),
toDate: new Date('2023-08-01T00:00:00.000Z'),
seatsDriver: 3,
seatsPassenger: 0,
strict: false,
monMargin: 800,
tueMargin: 900,
wedMargin: 900,
thuMargin: 900,
friMargin: 900,
satMargin: 900,
sunMargin: 900,
monTime: '04:40',
tueTime: undefined,
wedTime: undefined,
thuTime: undefined,
friTime: undefined,
satTime: undefined,
sunTime: undefined,
addresses: [
{
lon: 48.68944549560547,
lat: 6.176510334014893,
houseNumber: '5',
street: 'Avenue Foch',
locality: 'Nancy',
postalCode: '54000',
country: 'France',
position: 0
},
{
lon: 48.85660171508789,
lat: 2.3522000312805176,
locality: 'Paris',
postalCode: '75000',
country: 'France',
position: 1
}
]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
},
include: undefined
})
Argument addresses: Got invalid value
[
{
lon: 48.68944549560547,
lat: 6.176510334014893,
houseNumber: '5',
street: 'Avenue Foch',
locality: 'Nancy',
postalCode: '54000',
country: 'France',
position: 0
},
{
lon: 48.85660171508789,
lat: 2.3522000312805176,
locality: 'Paris',
postalCode: '75000',
country: 'France',
position: 1
}
]
on prisma.createOneAd. Provided List<Json>, expected AddressCreateNestedManyWithoutAdInput:
type AddressCreateNestedManyWithoutAdInput {
create?: AddressCreateWithoutAdInput | List<AddressCreateWithoutAdInput> | AddressUncheckedCreateWithoutAdInput | List<AddressUncheckedCreateWithoutAdInput>
connectOrCreate?: AddressCreateOrConnectWithoutAdInput | List<AddressCreateOrConnectWithoutAdInput>
createMany?: AddressCreateManyAdInputEnvelope
connect?: AddressWhereUniqueInput | List<AddressWhereUniqueInput>
}
at mi.validate (/usr/src/app/node_modules/@prisma/client/runtime/library.js:149:91)
at tn.createMessage (/usr/src/app/node_modules/@prisma/client/runtime/library.js:166:1205)
at /usr/src/app/node_modules/@prisma/client/runtime/library.js:179:10962
at runInChildSpan (/usr/src/app/node_modules/@prisma/client/runtime/library.js:70:25817)
at PrismaService._executeRequest (/usr/src/app/node_modules/@prisma/client/runtime/library.js:179:10951)
at PrismaService._request (/usr/src/app/node_modules/@prisma/client/runtime/library.js:179:10484)
at AdsRepository.create (/usr/src/app/src/modules/ad/adapters/secondaries/ads.repository.ts:15:19)
at CreateAdUseCase.execute (/usr/src/app/src/modules/ad/domain/usecases/create-ad.usecase.ts:69:17)
at AdController.createAd (/usr/src/app/src/modules/ad/adapters/primaries/ad.controller.ts:49:18)
at /usr/src/app/node_modules/@nestjs/microservices/context/rpc-proxy.js:11:32
at Object.Create (/usr/src/app/node_modules/@nestjs/microservices/server/server-grpc.js:148:40) {
clientVersion: '4.13.0'
*/

View File

@ -1,11 +1,17 @@
import { createMap, forMember, mapFrom, Mapper } from '@automapper/core';
import {
condition,
createMap,
forMember,
mapFrom,
Mapper,
} from '@automapper/core';
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
import { Injectable } from '@nestjs/common';
import { Ad } from '../domain/entities/ad';
import { AdPresenter } from '../adapters/primaries/ad.presenter';
import { CreateAdRequest } from '../domain/dtos/create-ad.request';
import { Address } from '../domain/entities/address';
import { AddressDTO } from '../domain/dtos/create.address.dto';
import { AdCreation } from '../domain/dtos/ad.creation';
import { Frequency } from '@prisma/client';
@Injectable()
export class AdProfile extends AutomapperProfile {
@ -15,12 +21,11 @@ export class AdProfile extends AutomapperProfile {
override get profile() {
return (mapper) => {
createMap(mapper, Address, AddressDTO);
createMap(mapper, Ad, AdPresenter);
createMap(
mapper,
CreateAdRequest,
Ad,
AdCreation,
forMember(
(destination) => destination.monMargin,
mapFrom((source) => source.marginDurations.mon),
@ -78,9 +83,17 @@ export class AdProfile extends AutomapperProfile {
mapFrom((source) => source.schedule.sun),
),
forMember(
(destination) => destination.addresses,
(destination) => destination.addresses.create,
mapFrom((source) => source.addresses),
),
//TODO use custom resolver
// forMember(
// (destination) => destination.fromDate,
// condition(
// (source) => source.frequency == Frequency.PUNCTUAL,
// source.departure,
// ),
// ),
);
};
}

View File

@ -0,0 +1,17 @@
import { Mapper, createMap } from '@automapper/core';
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
import { Injectable } from '@nestjs/common';
import { AddressRequestDTO } from '../domain/dtos/create.address.request';
import { AddressCreation } from '../domain/dtos/address.creation';
@Injectable()
export class AdProfile extends AutomapperProfile {
constructor(@InjectMapper() mapper: Mapper) {
super(mapper);
}
override get profile() {
return (mapper) => {
createMap(mapper, AddressRequestDTO, AddressCreation);
};
}
}

View File

@ -9,9 +9,11 @@ import { classes } from '@automapper/classes';
import { Frequency } from '../../domain/types/frequency.enum';
import { Ad } from '../../domain/entities/ad';
import { AdProfile } from '../../mappers/ad.profile';
import { AddressDTO } from '../../domain/dtos/create.address.dto';
import { AddressRequestDTO } from '../../domain/dtos/create.address.request';
import { AdCreation } from '../../domain/dtos/ad.creation';
import { AddressCreation } from '../../domain/dtos/address.creation';
const mockAddress1: AddressDTO = {
const mockAddress1: AddressRequestDTO = {
position: 0,
lon: 48.68944505415954,
lat: 6.176510296462267,
@ -21,7 +23,7 @@ const mockAddress1: AddressDTO = {
postalCode: '54000',
country: 'France',
};
const mockAddress2: AddressDTO = {
const mockAddress2: AddressRequestDTO = {
position: 1,
lon: 48.8566,
lat: 2.3522,
@ -29,25 +31,29 @@ const mockAddress2: AddressDTO = {
postalCode: '75000',
country: 'France',
};
const mockAddressWithoutPos1: AddressRequestDTO = {
lon: 43.2965,
lat: 5.3698,
locality: 'Marseille',
postalCode: '13000',
country: 'France',
};
const mockAddressWithoutPos2: AddressRequestDTO = {
lon: 43.7102,
lat: 7.262,
locality: 'Marseille',
postalCode: '06000',
country: 'France',
};
const minimalReccurentAdREquest: CreateAdRequest = {
userUuid: '224e0000-0000-4000-a000-000000000000',
driver: undefined,
passenger: undefined,
frequency: Frequency.RECURRENT,
fromDate: new Date('01-05-2023'),
toDate: new Date('01-05-2024'),
schedule: {
mon: '08:00',
},
marginDurations: {
mon: undefined,
tue: undefined,
wed: undefined,
thu: undefined,
fri: undefined,
sat: undefined,
sun: undefined,
},
marginDurations: {},
addresses: [mockAddress1, mockAddress2],
};
const newAdRequest: CreateAdRequest = {
@ -70,9 +76,26 @@ const newAdRequest: CreateAdRequest = {
sat: undefined,
sun: undefined,
},
seatsPassenger: 2,
seatsDriver: 2,
addresses: [mockAddress1, mockAddress2],
};
const newPunctualPassengerAdRequest: CreateAdRequest = {
userUuid: '113e0000-0000-4000-a000-000000000000',
passenger: true,
frequency: Frequency.PUNCTUAL,
departure: new Date('05-22-2023'),
marginDurations: {
mon: undefined,
tue: undefined,
wed: undefined,
thu: undefined,
fri: undefined,
sat: undefined,
sun: undefined,
},
seatsPassenger: 1,
addresses: [mockAddressWithoutPos1, mockAddressWithoutPos2],
};
const mockMessager = {
publish: jest.fn().mockImplementation(),
@ -109,7 +132,7 @@ let mockAdRepository = {
.mockImplementationOnce(() => {
throw new Error('Already exists');
})
.mockImplementation(),
.mockImplementation((command?: CreateAdCommand) => {}),
};
describe('CreateAdUseCase', () => {
let createAdUseCase: CreateAdUseCase;
@ -154,17 +177,48 @@ describe('CreateAdUseCase', () => {
});
describe('Ad parameter default setting ', () => {
const newAdCommand = new CreateAdCommand(minimalReccurentAdREquest);
beforeEach(() => {
mockAdRepository.create.mockClear();
});
it('should define mimimal ad as 1 passager add', async () => {
const newAd: Ad = await createAdUseCase.execute(newAdCommand);
expect(mockAdRepository).toBeCalledWith({
userUuid: '113e0000-0000-4000-a000-000000000000',
driver: true,
passenger: false,
frequency: Frequency.RECURRENT,
fromDate: new Date('01-05-2023'),
toDate: new Date('20-08-2023'),
});
const newAdCommand = new CreateAdCommand(minimalReccurentAdREquest);
await createAdUseCase.execute(newAdCommand);
const expectedAdCreation = {
userUuid: minimalReccurentAdREquest.userUuid,
frequency: minimalReccurentAdREquest.frequency,
fromDate: minimalReccurentAdREquest.fromDate,
toDate: minimalReccurentAdREquest.toDate,
monTime: minimalReccurentAdREquest.schedule.mon,
tueTime: undefined,
wedTime: undefined,
thuTime: undefined,
friTime: undefined,
satTime: undefined,
sunTime: undefined,
monMargin: mockDefaultParamsProvider.getParams().MON_MARGIN,
tueMargin: mockDefaultParamsProvider.getParams().TUE_MARGIN,
wedMargin: mockDefaultParamsProvider.getParams().WED_MARGIN,
thuMargin: mockDefaultParamsProvider.getParams().THU_MARGIN,
friMargin: mockDefaultParamsProvider.getParams().FRI_MARGIN,
satMargin: mockDefaultParamsProvider.getParams().SAT_MARGIN,
sunMargin: mockDefaultParamsProvider.getParams().SUN_MARGIN,
driver: mockDefaultParamsProvider.getParams().DRIVER,
seatsDriver: mockDefaultParamsProvider.getParams().DRIVER_SEAT,
passenger: mockDefaultParamsProvider.getParams().PASSENGER,
seatsPassenger: mockDefaultParamsProvider.getParams().PASSENGER_SEATS,
strict: mockDefaultParamsProvider.getParams().STRICT,
addresses: {
create: minimalReccurentAdREquest.addresses as AddressCreation[],
},
createdAt: undefined,
} as AdCreation;
expect(mockAdRepository.create).toBeCalledWith(expectedAdCreation);
});
it('should create an passengerAd with addresses without position ', async () => {
const newAdCommand = new CreateAdCommand(newPunctualPassengerAdRequest);
await createAdUseCase.execute(newAdCommand);
});
});
});

View File

@ -1,7 +1,7 @@
import { AddressDTO } from '../../domain/dtos/create.address.dto';
import { AddressRequestDTO } from '../../domain/dtos/create.address.request';
import { hasProperPositionIndexes } from '../../domain/dtos/utils/address-position.validator';
describe('addresses position validators', () => {
const mockAddress1: AddressDTO = {
const mockAddress1: AddressRequestDTO = {
lon: 48.68944505415954,
lat: 6.176510296462267,
houseNumber: '5',
@ -10,7 +10,7 @@ describe('addresses position validators', () => {
postalCode: '54000',
country: 'France',
};
const mockAddress2: AddressDTO = {
const mockAddress2: AddressRequestDTO = {
lon: 48.8566,
lat: 2.3522,
locality: 'Paris',
@ -18,7 +18,7 @@ describe('addresses position validators', () => {
country: 'France',
};
const mockAddress3: AddressDTO = {
const mockAddress3: AddressRequestDTO = {
lon: 49.2628,
lat: 4.0347,
locality: 'Reims',

View File

@ -80,20 +80,13 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
// TODO : using any is not good, but needed for nested entities
// TODO : Refactor for good clean architecture ?
async create(entity: Partial<T> | any, include?: any): Promise<T> {
console.log('repo entity ');
console.log(entity);
console.log('-----------------------------------------');
try {
const res = await this._prisma[this._model].create({
data: entity,
include: include,
});
console.log('result');
console.log(res);
return res;
} catch (e) {
console.log('repo error ');
console.log(e);
if (e instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseException(
Prisma.PrismaClientKnownRequestError.name,