From 74145790b4b9dac63753326b274b667b7f76bfe3 Mon Sep 17 00:00:00 2001 From: Ha Minh Chien Date: Thu, 25 Jan 2024 17:26:55 +0700 Subject: [PATCH] feat: sample-type and instrument --- .../src/domain/auth/action.ts | 4 + .../src/domain/auth/subject.ts | 14 +++- .../src/domain/entity/index.ts | 2 + .../src/domain/entity/instrument/auth.ts | 14 ++++ .../src/domain/entity/instrument/entity.ts | 10 +++ .../src/domain/entity/instrument/example.ts | 17 +++++ .../src/domain/entity/instrument/index.ts | 3 + .../src/domain/entity/sample-type/auth.ts | 14 ++++ .../src/domain/entity/sample-type/entity.ts | 10 +++ .../src/domain/entity/sample-type/example.ts | 17 +++++ .../src/domain/entity/sample-type/index.ts | 3 + .../src/domain/interface/repository/index.ts | 2 + .../domain/interface/repository/instrument.ts | 6 ++ .../interface/repository/sample-type.ts | 6 ++ .../src/domain/use-case/index.ts | 18 +++++ .../use-case/instrument/assert-exists.ts | 27 +++++++ .../instrument/authorize-populates.ts | 30 ++++++++ .../src/domain/use-case/instrument/create.ts | 37 ++++++++++ .../src/domain/use-case/instrument/delete.ts | 39 ++++++++++ .../domain/use-case/instrument/find-one.ts | 39 ++++++++++ .../src/domain/use-case/instrument/search.ts | 44 +++++++++++ .../src/domain/use-case/instrument/update.ts | 38 ++++++++++ .../domain/use-case/instrument/validate.ts | 32 ++++++++ .../src/domain/use-case/module.ts | 36 +++++++++ .../use-case/sample-type/assert-exists.ts | 27 +++++++ .../sample-type/authorize-populates.ts | 30 ++++++++ .../src/domain/use-case/sample-type/create.ts | 37 ++++++++++ .../src/domain/use-case/sample-type/delete.ts | 39 ++++++++++ .../domain/use-case/sample-type/find-one.ts | 39 ++++++++++ .../src/domain/use-case/sample-type/search.ts | 44 +++++++++++ .../src/domain/use-case/sample-type/update.ts | 38 ++++++++++ .../domain/use-case/sample-type/validate.ts | 32 ++++++++ .../mongo/collection-classes.ts | 5 +- .../src/infrastructure/mongo/collections.ts | 3 +- .../infrastructure/mongo/instrument/index.ts | 2 + .../mongo/instrument/repository.ts | 17 +++++ .../infrastructure/mongo/instrument/schema.ts | 32 ++++++++ .../src/infrastructure/mongo/module.ts | 14 ++++ .../infrastructure/mongo/sample-type/index.ts | 2 + .../mongo/sample-type/repository.ts | 17 +++++ .../mongo/sample-type/schema.ts | 32 ++++++++ .../http/v1/instrument/controller.ts | 66 +++++++++++++++++ .../v1/instrument/dto/create.request-dto.ts | 25 +++++++ .../http/v1/instrument/dto/response-dto.ts | 19 +++++ .../v1/instrument/dto/search.request-dto.ts | 5 ++ .../v1/instrument/dto/search.response-dto.ts | 7 ++ .../v1/instrument/dto/update.request-dto.ts | 7 ++ .../presentation/http/v1/instrument/routes.ts | 73 +++++++++++++++++++ .../src/presentation/http/v1/module.ts | 4 + .../http/v1/sample-type/controller.ts | 66 +++++++++++++++++ .../v1/sample-type/dto/create.request-dto.ts | 25 +++++++ .../http/v1/sample-type/dto/response-dto.ts | 19 +++++ .../v1/sample-type/dto/search.request-dto.ts | 5 ++ .../v1/sample-type/dto/search.response-dto.ts | 7 ++ .../v1/sample-type/dto/update.request-dto.ts | 7 ++ .../http/v1/sample-type/routes.ts | 31 +++----- .../dtos/create-sample-type.request-dto.ts | 18 ----- .../dtos/sample-type.response-dto.ts | 23 ------ .../dtos/search-sample-type.request-dto.ts | 4 - .../dtos/search-sample-type.response-dto.ts | 6 -- .../dtos/update-sample-type.request-dto.ts | 7 -- .../sample-types/sample-type.controller.ts | 46 ------------ resources/sample-types/sample-type.module.ts | 14 ---- resources/sample-types/sample-type.schema.ts | 16 ---- resources/sample-types/sample-type.service.ts | 13 ---- 65 files changed, 1215 insertions(+), 170 deletions(-) create mode 100644 apps/hcdc-access-service/src/domain/entity/instrument/auth.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/instrument/entity.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/instrument/example.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/instrument/index.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/sample-type/auth.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/sample-type/entity.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/sample-type/example.ts create mode 100644 apps/hcdc-access-service/src/domain/entity/sample-type/index.ts create mode 100644 apps/hcdc-access-service/src/domain/interface/repository/instrument.ts create mode 100644 apps/hcdc-access-service/src/domain/interface/repository/sample-type.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/assert-exists.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/authorize-populates.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/create.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/delete.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/find-one.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/search.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/update.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/instrument/validate.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/assert-exists.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/authorize-populates.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/create.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/delete.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/find-one.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/search.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/update.ts create mode 100644 apps/hcdc-access-service/src/domain/use-case/sample-type/validate.ts create mode 100644 apps/hcdc-access-service/src/infrastructure/mongo/instrument/index.ts create mode 100644 apps/hcdc-access-service/src/infrastructure/mongo/instrument/repository.ts create mode 100644 apps/hcdc-access-service/src/infrastructure/mongo/instrument/schema.ts create mode 100644 apps/hcdc-access-service/src/infrastructure/mongo/sample-type/index.ts create mode 100644 apps/hcdc-access-service/src/infrastructure/mongo/sample-type/repository.ts create mode 100644 apps/hcdc-access-service/src/infrastructure/mongo/sample-type/schema.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/controller.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/create.request-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/response-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.request-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.response-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/update.request-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/instrument/routes.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/sample-type/controller.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/create.request-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/response-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.request-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.response-dto.ts create mode 100644 apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/update.request-dto.ts rename resources/sample-types/sample-type.routes.ts => apps/hcdc-access-service/src/presentation/http/v1/sample-type/routes.ts (59%) delete mode 100644 resources/sample-types/dtos/create-sample-type.request-dto.ts delete mode 100644 resources/sample-types/dtos/sample-type.response-dto.ts delete mode 100644 resources/sample-types/dtos/search-sample-type.request-dto.ts delete mode 100644 resources/sample-types/dtos/search-sample-type.response-dto.ts delete mode 100644 resources/sample-types/dtos/update-sample-type.request-dto.ts delete mode 100644 resources/sample-types/sample-type.controller.ts delete mode 100644 resources/sample-types/sample-type.module.ts delete mode 100644 resources/sample-types/sample-type.schema.ts delete mode 100644 resources/sample-types/sample-type.service.ts diff --git a/apps/hcdc-access-service/src/domain/auth/action.ts b/apps/hcdc-access-service/src/domain/auth/action.ts index 9aaf77f0..9c94eb0a 100644 --- a/apps/hcdc-access-service/src/domain/auth/action.ts +++ b/apps/hcdc-access-service/src/domain/auth/action.ts @@ -4,7 +4,9 @@ import { AuthSubject, AuthSubjectUnionType } from './subject' import { BioProductAction, BranchAction, + InstrumentAction, RoleAction, + SampleTypeAction, TestCategoryAction, UserAction, } from '../entity' @@ -16,6 +18,8 @@ export const AuthAction = { Branch: stringEnumValues(BranchAction), Role: stringEnumValues(RoleAction), User: stringEnumValues(UserAction), + Instrument: stringEnumValues(InstrumentAction), + SampleType: stringEnumValues(SampleTypeAction), } satisfies Record export const AuthActionValues = [ diff --git a/apps/hcdc-access-service/src/domain/auth/subject.ts b/apps/hcdc-access-service/src/domain/auth/subject.ts index 986cc364..140d7088 100644 --- a/apps/hcdc-access-service/src/domain/auth/subject.ts +++ b/apps/hcdc-access-service/src/domain/auth/subject.ts @@ -1,6 +1,14 @@ import { RecordTypes } from '@casl/mongoose' -import { BioProduct, Branch, Role, TestCategory, User } from '../entity' +import { + BioProduct, + Branch, + Instrument, + Role, + SampleType, + TestCategory, + User, +} from '../entity' import { AUTH_SUBJECT_ALL } from './constants' // key-value must be identical for working with '@casl/mongoose'.accessibleBy() @@ -10,6 +18,8 @@ export const AuthSubject = { Branch: 'Branch', Role: 'Role', User: 'User', + Instrument: 'Instrument', + SampleType: 'SampleType', } satisfies Record export type AuthSubjectUnionType = keyof typeof AuthSubject @@ -25,4 +35,6 @@ export type SubjectEntityMapping = { Branch: Branch Role: Role User: User + Instrument: Instrument + SampleType: SampleType } diff --git a/apps/hcdc-access-service/src/domain/entity/index.ts b/apps/hcdc-access-service/src/domain/entity/index.ts index 6704ef9e..3d819610 100644 --- a/apps/hcdc-access-service/src/domain/entity/index.ts +++ b/apps/hcdc-access-service/src/domain/entity/index.ts @@ -1,6 +1,8 @@ export * from './base-entity' export * from './bio-product' +export * from './instrument' +export * from './sample-type' export * from './test-category' export * from './role' export * from './user' diff --git a/apps/hcdc-access-service/src/domain/entity/instrument/auth.ts b/apps/hcdc-access-service/src/domain/entity/instrument/auth.ts new file mode 100644 index 00000000..a10d3753 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/instrument/auth.ts @@ -0,0 +1,14 @@ +import '@casl/mongoose' + +export enum InstrumentAction { + Create = 'Create', + Read = 'Read', + Update = 'Update', + Delete = 'Delete', +} + +declare module '@casl/mongoose' { + interface RecordTypes { + Instrument: true + } +} diff --git a/apps/hcdc-access-service/src/domain/entity/instrument/entity.ts b/apps/hcdc-access-service/src/domain/entity/instrument/entity.ts new file mode 100644 index 00000000..c9aa66d4 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/instrument/entity.ts @@ -0,0 +1,10 @@ +import { BaseEntity } from '../base-entity' +import { Branch } from '../branch' + +export type Instrument = BaseEntity & { + displayIndex: number + name: string + + branchId: string + branch?: Branch | null +} diff --git a/apps/hcdc-access-service/src/domain/entity/instrument/example.ts b/apps/hcdc-access-service/src/domain/entity/instrument/example.ts new file mode 100644 index 00000000..465a3ca9 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/instrument/example.ts @@ -0,0 +1,17 @@ +import { exampleMongoObjectId } from '@diut/nest-core' + +import { EntityDataExample } from '../base-entity' +import { Instrument } from './entity' + +export const exampleInstrument = { + displayIndex: { + example: 1, + }, + name: { + example: 'máy xét nghiệm A', + }, + branchId: exampleMongoObjectId, + branch: { + required: false, + }, +} satisfies EntityDataExample diff --git a/apps/hcdc-access-service/src/domain/entity/instrument/index.ts b/apps/hcdc-access-service/src/domain/entity/instrument/index.ts new file mode 100644 index 00000000..3b1b1117 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/instrument/index.ts @@ -0,0 +1,3 @@ +export * from './entity' +export * from './example' +export * from './auth' diff --git a/apps/hcdc-access-service/src/domain/entity/sample-type/auth.ts b/apps/hcdc-access-service/src/domain/entity/sample-type/auth.ts new file mode 100644 index 00000000..89997333 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/sample-type/auth.ts @@ -0,0 +1,14 @@ +import '@casl/mongoose' + +export enum SampleTypeAction { + Create = 'Create', + Read = 'Read', + Update = 'Update', + Delete = 'Delete', +} + +declare module '@casl/mongoose' { + interface RecordTypes { + SampleType: true + } +} diff --git a/apps/hcdc-access-service/src/domain/entity/sample-type/entity.ts b/apps/hcdc-access-service/src/domain/entity/sample-type/entity.ts new file mode 100644 index 00000000..45270059 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/sample-type/entity.ts @@ -0,0 +1,10 @@ +import { BaseEntity } from '../base-entity' +import { Branch } from '../branch' + +export type SampleType = BaseEntity & { + displayIndex: number + name: string + + branchId: string + branch?: Branch | null +} diff --git a/apps/hcdc-access-service/src/domain/entity/sample-type/example.ts b/apps/hcdc-access-service/src/domain/entity/sample-type/example.ts new file mode 100644 index 00000000..c8eca447 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/sample-type/example.ts @@ -0,0 +1,17 @@ +import { exampleMongoObjectId } from '@diut/nest-core' + +import { EntityDataExample } from '../base-entity' +import { SampleType } from './entity' + +export const exampleSampleType = { + displayIndex: { + example: 1, + }, + name: { + example: 'máu', + }, + branchId: exampleMongoObjectId, + branch: { + required: false, + }, +} satisfies EntityDataExample diff --git a/apps/hcdc-access-service/src/domain/entity/sample-type/index.ts b/apps/hcdc-access-service/src/domain/entity/sample-type/index.ts new file mode 100644 index 00000000..3b1b1117 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/entity/sample-type/index.ts @@ -0,0 +1,3 @@ +export * from './entity' +export * from './example' +export * from './auth' diff --git a/apps/hcdc-access-service/src/domain/interface/repository/index.ts b/apps/hcdc-access-service/src/domain/interface/repository/index.ts index d93803c3..10b2f0ae 100644 --- a/apps/hcdc-access-service/src/domain/interface/repository/index.ts +++ b/apps/hcdc-access-service/src/domain/interface/repository/index.ts @@ -5,3 +5,5 @@ export * from './test-category' export * from './user' export * from './branch' export * from './role' +export * from './instrument' +export * from './sample-type' diff --git a/apps/hcdc-access-service/src/domain/interface/repository/instrument.ts b/apps/hcdc-access-service/src/domain/interface/repository/instrument.ts new file mode 100644 index 00000000..a8b0cc00 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/interface/repository/instrument.ts @@ -0,0 +1,6 @@ +import { Instrument } from 'src/domain/entity' +import { IRepository } from './interface' + +export const InstrumentRepositoryToken = Symbol('InstrumentRepository') + +export interface IInstrumentRepository extends IRepository {} diff --git a/apps/hcdc-access-service/src/domain/interface/repository/sample-type.ts b/apps/hcdc-access-service/src/domain/interface/repository/sample-type.ts new file mode 100644 index 00000000..e11f2533 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/interface/repository/sample-type.ts @@ -0,0 +1,6 @@ +import { SampleType } from 'src/domain/entity' +import { IRepository } from './interface' + +export const SampleTypeRepositoryToken = Symbol('SampleTypeRepository') + +export interface ISampleTypeRepository extends IRepository {} diff --git a/apps/hcdc-access-service/src/domain/use-case/index.ts b/apps/hcdc-access-service/src/domain/use-case/index.ts index 513dc658..eb6fb59d 100644 --- a/apps/hcdc-access-service/src/domain/use-case/index.ts +++ b/apps/hcdc-access-service/src/domain/use-case/index.ts @@ -13,6 +13,24 @@ export * from './bio-product/assert-exists' export * from './bio-product/validate' export * from './bio-product/authorize-populates' +export * from './instrument/create' +export * from './instrument/find-one' +export * from './instrument/update' +export * from './instrument/delete' +export * from './instrument/search' +export * from './instrument/assert-exists' +export * from './instrument/validate' +export * from './instrument/authorize-populates' + +export * from './sample-type/create' +export * from './sample-type/find-one' +export * from './sample-type/update' +export * from './sample-type/delete' +export * from './sample-type/search' +export * from './sample-type/assert-exists' +export * from './sample-type/validate' +export * from './sample-type/authorize-populates' + export * from './test-category/create' export * from './test-category/find-one' export * from './test-category/update' diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/assert-exists.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/assert-exists.ts new file mode 100644 index 00000000..36c81295 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/assert-exists.ts @@ -0,0 +1,27 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { Instrument } from 'src/domain/entity' +import { EEntityNotFound } from 'src/domain/exception' +import { + InstrumentRepositoryToken, + EntityFindOneOptions, + IInstrumentRepository, +} from 'src/domain/interface' + +@Injectable() +export class InstrumentAssertExistsUseCase { + constructor( + @Inject(InstrumentRepositoryToken) + private readonly instrumentRepository: IInstrumentRepository, + ) {} + + async execute(input: EntityFindOneOptions['filter']) { + const rv = await this.instrumentRepository.findOne({ filter: input }) + + if (rv === null) { + throw new EEntityNotFound(`Instrument ${JSON.stringify(input)}`) + } + + return rv + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/authorize-populates.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/authorize-populates.ts new file mode 100644 index 00000000..b2b5ebb6 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/authorize-populates.ts @@ -0,0 +1,30 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { AuthSubject, authorizePopulates } from 'src/domain/auth' +import { BranchAction, Instrument } from 'src/domain/entity' +import { EEntityPopulatePathUnknown } from 'src/domain/exception' +import { + AuthContextToken, + EntityFindOneOptions, + IAuthContext, +} from 'src/domain/interface' + +@Injectable() +export class InstrumentAuthorizePopulatesUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + ) {} + execute(input: EntityFindOneOptions['populates']) { + const { ability } = this.authContext.getData() + + return authorizePopulates(ability, input, (path) => { + switch (path) { + case 'branch': + return { subject: AuthSubject.Branch, action: BranchAction.Read } + default: + throw new EEntityPopulatePathUnknown(path) + } + }) + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/create.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/create.ts new file mode 100644 index 00000000..901c74a8 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/create.ts @@ -0,0 +1,37 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { + AuthContextToken, + InstrumentRepositoryToken, + IAuthContext, + IInstrumentRepository, +} from 'src/domain/interface' +import { Instrument, InstrumentAction, EntityData } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { InstrumentValidateUseCase } from './validate' + +@Injectable() +export class InstrumentCreateUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + @Inject(InstrumentRepositoryToken) + private readonly instrumentRepository: IInstrumentRepository, + private readonly instrumentValidateUseCase: InstrumentValidateUseCase, + ) {} + + async execute(input: EntityData) { + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.Instrument, + InstrumentAction.Create, + input, + ) + await this.instrumentValidateUseCase.execute(input) + + const entity = await this.instrumentRepository.create(input) + + return entity + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/delete.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/delete.ts new file mode 100644 index 00000000..efcc8127 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/delete.ts @@ -0,0 +1,39 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { InstrumentAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { + AuthContextToken, + InstrumentRepositoryToken, + IAuthContext, + IInstrumentRepository, +} from 'src/domain/interface' +import { InstrumentAssertExistsUseCase } from './assert-exists' + +@Injectable() +export class InstrumentDeleteUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + @Inject(InstrumentRepositoryToken) + private readonly instrumentRepository: IInstrumentRepository, + private readonly instrumentAssertExistsUseCase: InstrumentAssertExistsUseCase, + ) {} + + async execute(input: { id: string }) { + const entity = await this.instrumentAssertExistsUseCase.execute({ + _id: input.id, + }) + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.Instrument, + InstrumentAction.Delete, + entity, + ) + + await this.instrumentRepository.deleteById(input.id) + + return entity + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/find-one.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/find-one.ts new file mode 100644 index 00000000..1a2dde3f --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/find-one.ts @@ -0,0 +1,39 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { Instrument, InstrumentAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { + AuthContextToken, + InstrumentRepositoryToken, + EntityFindOneOptions, + IAuthContext, + IInstrumentRepository, +} from 'src/domain/interface' +import { InstrumentAuthorizePopulatesUseCase } from './authorize-populates' + +@Injectable() +export class InstrumentFindOneUseCase { + constructor( + @Inject(InstrumentRepositoryToken) + private readonly instrumentRepository: IInstrumentRepository, + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly instrumentAuthorizePopulatesUseCase: InstrumentAuthorizePopulatesUseCase, + ) {} + + async execute(input: EntityFindOneOptions) { + input.populates = this.instrumentAuthorizePopulatesUseCase.execute( + input.populates, + ) + const entity = await this.instrumentRepository.findOne(input) + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.Instrument, + InstrumentAction.Read, + entity, + ) + + return entity + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/search.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/search.ts new file mode 100644 index 00000000..627d1134 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/search.ts @@ -0,0 +1,44 @@ +import { Inject, Injectable } from '@nestjs/common' +import { accessibleBy } from '@casl/mongoose' + +import { + AuthContextToken, + InstrumentRepositoryToken, + IAuthContext, + IInstrumentRepository, + EntitySearchOptions, +} from 'src/domain/interface' +import { Instrument, InstrumentAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { InstrumentAuthorizePopulatesUseCase } from './authorize-populates' + +@Injectable() +export class InstrumentSearchUseCase { + constructor( + @Inject(InstrumentRepositoryToken) + private readonly instrumentRepository: IInstrumentRepository, + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly instrumentAuthorizePopulatesUseCase: InstrumentAuthorizePopulatesUseCase, + ) {} + + async execute(input: EntitySearchOptions) { + const { ability } = this.authContext.getData() + assertPermission(ability, AuthSubject.Instrument, InstrumentAction.Read) + input.populates = this.instrumentAuthorizePopulatesUseCase.execute( + input.populates, + ) + + const paginationResult = await this.instrumentRepository.search({ + ...input, + filter: { + $and: [ + input.filter ?? {}, + accessibleBy(ability, InstrumentAction.Read).Instrument, + ], + }, + }) + + return paginationResult + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/update.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/update.ts new file mode 100644 index 00000000..9c6b0784 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/update.ts @@ -0,0 +1,38 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { InstrumentAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { + AuthContextToken, + InstrumentRepositoryToken, + IAuthContext, + IInstrumentRepository, +} from 'src/domain/interface' +import { InstrumentAssertExistsUseCase } from './assert-exists' +import { InstrumentValidateUseCase } from './validate' + +@Injectable() +export class InstrumentUpdateUseCase { + constructor( + @Inject(InstrumentRepositoryToken) + private readonly instrumentRepository: IInstrumentRepository, + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly instrumentAssertExistsUseCase: InstrumentAssertExistsUseCase, + private readonly instrumentValidateUseCase: InstrumentValidateUseCase, + ) {} + + async execute(...input: Parameters) { + const entity = await this.instrumentAssertExistsUseCase.execute(input[0]) + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.Instrument, + InstrumentAction.Update, + entity, + ) + await this.instrumentValidateUseCase.execute(input[1]) + + return this.instrumentRepository.update(...input) + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/instrument/validate.ts b/apps/hcdc-access-service/src/domain/use-case/instrument/validate.ts new file mode 100644 index 00000000..a521b162 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/instrument/validate.ts @@ -0,0 +1,32 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { Instrument, BranchAction, EntityData } from 'src/domain/entity' +import { BranchAssertExistsUseCase } from '../branch/assert-exists' +import { AuthContextToken, IAuthContext } from 'src/domain/interface' +import { AuthSubject, assertPermission } from 'src/domain/auth' + +@Injectable() +export class InstrumentValidateUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly branchAssertExistsUseCase: BranchAssertExistsUseCase, + ) {} + + async execute(input: Partial>) { + const { ability } = this.authContext.getData() + const { branchId } = input + + if (branchId !== undefined) { + const branch = await this.branchAssertExistsUseCase.execute({ + _id: branchId, + }) + assertPermission( + ability, + AuthSubject.Branch, + BranchAction.AssignToSubject, + branch, + ) + } + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/module.ts b/apps/hcdc-access-service/src/domain/use-case/module.ts index 1d7dfc26..cd6955aa 100644 --- a/apps/hcdc-access-service/src/domain/use-case/module.ts +++ b/apps/hcdc-access-service/src/domain/use-case/module.ts @@ -9,6 +9,24 @@ import { BioProductSearchUseCase } from './bio-product/search' import { BioProductAssertExistsUseCase } from './bio-product/assert-exists' import { BioProductAuthorizePopulatesUseCase } from './bio-product/authorize-populates' +import { SampleTypeCreateUseCase } from './sample-type/create' +import { SampleTypeUpdateUseCase } from './sample-type/update' +import { SampleTypeValidateUseCase } from './sample-type/validate' +import { SampleTypeFindOneUseCase } from './sample-type/find-one' +import { SampleTypeDeleteUseCase } from './sample-type/delete' +import { SampleTypeSearchUseCase } from './sample-type/search' +import { SampleTypeAssertExistsUseCase } from './sample-type/assert-exists' +import { SampleTypeAuthorizePopulatesUseCase } from './sample-type/authorize-populates' + +import { InstrumentCreateUseCase } from './instrument/create' +import { InstrumentUpdateUseCase } from './instrument/update' +import { InstrumentValidateUseCase } from './instrument/validate' +import { InstrumentFindOneUseCase } from './instrument/find-one' +import { InstrumentDeleteUseCase } from './instrument/delete' +import { InstrumentSearchUseCase } from './instrument/search' +import { InstrumentAssertExistsUseCase } from './instrument/assert-exists' +import { InstrumentAuthorizePopulatesUseCase } from './instrument/authorize-populates' + import { TestCategoryCreateUseCase } from './test-category/create' import { TestCategoryUpdateUseCase } from './test-category/update' import { TestCategoryValidateUseCase } from './test-category/validate' @@ -67,6 +85,24 @@ export const useCaseMetadata: ModuleMetadata = { BioProductValidateUseCase, BioProductAuthorizePopulatesUseCase, + SampleTypeCreateUseCase, + SampleTypeFindOneUseCase, + SampleTypeUpdateUseCase, + SampleTypeDeleteUseCase, + SampleTypeSearchUseCase, + SampleTypeAssertExistsUseCase, + SampleTypeValidateUseCase, + SampleTypeAuthorizePopulatesUseCase, + + InstrumentCreateUseCase, + InstrumentFindOneUseCase, + InstrumentUpdateUseCase, + InstrumentDeleteUseCase, + InstrumentSearchUseCase, + InstrumentAssertExistsUseCase, + InstrumentValidateUseCase, + InstrumentAuthorizePopulatesUseCase, + TestCategoryCreateUseCase, TestCategoryFindOneUseCase, TestCategoryUpdateUseCase, diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/assert-exists.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/assert-exists.ts new file mode 100644 index 00000000..22cc5f64 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/assert-exists.ts @@ -0,0 +1,27 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { SampleType } from 'src/domain/entity' +import { EEntityNotFound } from 'src/domain/exception' +import { + SampleTypeRepositoryToken, + EntityFindOneOptions, + ISampleTypeRepository, +} from 'src/domain/interface' + +@Injectable() +export class SampleTypeAssertExistsUseCase { + constructor( + @Inject(SampleTypeRepositoryToken) + private readonly sampleTypeRepository: ISampleTypeRepository, + ) {} + + async execute(input: EntityFindOneOptions['filter']) { + const rv = await this.sampleTypeRepository.findOne({ filter: input }) + + if (rv === null) { + throw new EEntityNotFound(`SampleType ${JSON.stringify(input)}`) + } + + return rv + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/authorize-populates.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/authorize-populates.ts new file mode 100644 index 00000000..4c23b323 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/authorize-populates.ts @@ -0,0 +1,30 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { AuthSubject, authorizePopulates } from 'src/domain/auth' +import { BranchAction, SampleType } from 'src/domain/entity' +import { EEntityPopulatePathUnknown } from 'src/domain/exception' +import { + AuthContextToken, + EntityFindOneOptions, + IAuthContext, +} from 'src/domain/interface' + +@Injectable() +export class SampleTypeAuthorizePopulatesUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + ) {} + execute(input: EntityFindOneOptions['populates']) { + const { ability } = this.authContext.getData() + + return authorizePopulates(ability, input, (path) => { + switch (path) { + case 'branch': + return { subject: AuthSubject.Branch, action: BranchAction.Read } + default: + throw new EEntityPopulatePathUnknown(path) + } + }) + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/create.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/create.ts new file mode 100644 index 00000000..80c0b159 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/create.ts @@ -0,0 +1,37 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { + AuthContextToken, + SampleTypeRepositoryToken, + IAuthContext, + ISampleTypeRepository, +} from 'src/domain/interface' +import { SampleType, SampleTypeAction, EntityData } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { SampleTypeValidateUseCase } from './validate' + +@Injectable() +export class SampleTypeCreateUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + @Inject(SampleTypeRepositoryToken) + private readonly sampleTypeRepository: ISampleTypeRepository, + private readonly sampleTypeValidateUseCase: SampleTypeValidateUseCase, + ) {} + + async execute(input: EntityData) { + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.SampleType, + SampleTypeAction.Create, + input, + ) + await this.sampleTypeValidateUseCase.execute(input) + + const entity = await this.sampleTypeRepository.create(input) + + return entity + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/delete.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/delete.ts new file mode 100644 index 00000000..5137f733 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/delete.ts @@ -0,0 +1,39 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { SampleTypeAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { + AuthContextToken, + SampleTypeRepositoryToken, + IAuthContext, + ISampleTypeRepository, +} from 'src/domain/interface' +import { SampleTypeAssertExistsUseCase } from './assert-exists' + +@Injectable() +export class SampleTypeDeleteUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + @Inject(SampleTypeRepositoryToken) + private readonly sampleTypeRepository: ISampleTypeRepository, + private readonly sampleTypeAssertExistsUseCase: SampleTypeAssertExistsUseCase, + ) {} + + async execute(input: { id: string }) { + const entity = await this.sampleTypeAssertExistsUseCase.execute({ + _id: input.id, + }) + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.SampleType, + SampleTypeAction.Delete, + entity, + ) + + await this.sampleTypeRepository.deleteById(input.id) + + return entity + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/find-one.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/find-one.ts new file mode 100644 index 00000000..bb1e1655 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/find-one.ts @@ -0,0 +1,39 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { SampleType, SampleTypeAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { + AuthContextToken, + SampleTypeRepositoryToken, + EntityFindOneOptions, + IAuthContext, + ISampleTypeRepository, +} from 'src/domain/interface' +import { SampleTypeAuthorizePopulatesUseCase } from './authorize-populates' + +@Injectable() +export class SampleTypeFindOneUseCase { + constructor( + @Inject(SampleTypeRepositoryToken) + private readonly sampleTypeRepository: ISampleTypeRepository, + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly sampleTypeAuthorizePopulatesUseCase: SampleTypeAuthorizePopulatesUseCase, + ) {} + + async execute(input: EntityFindOneOptions) { + input.populates = this.sampleTypeAuthorizePopulatesUseCase.execute( + input.populates, + ) + const entity = await this.sampleTypeRepository.findOne(input) + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.SampleType, + SampleTypeAction.Read, + entity, + ) + + return entity + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/search.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/search.ts new file mode 100644 index 00000000..b33c3c45 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/search.ts @@ -0,0 +1,44 @@ +import { Inject, Injectable } from '@nestjs/common' +import { accessibleBy } from '@casl/mongoose' + +import { + AuthContextToken, + SampleTypeRepositoryToken, + IAuthContext, + ISampleTypeRepository, + EntitySearchOptions, +} from 'src/domain/interface' +import { SampleType, SampleTypeAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { SampleTypeAuthorizePopulatesUseCase } from './authorize-populates' + +@Injectable() +export class SampleTypeSearchUseCase { + constructor( + @Inject(SampleTypeRepositoryToken) + private readonly sampleTypeRepository: ISampleTypeRepository, + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly sampleTypeAuthorizePopulatesUseCase: SampleTypeAuthorizePopulatesUseCase, + ) {} + + async execute(input: EntitySearchOptions) { + const { ability } = this.authContext.getData() + assertPermission(ability, AuthSubject.SampleType, SampleTypeAction.Read) + input.populates = this.sampleTypeAuthorizePopulatesUseCase.execute( + input.populates, + ) + + const paginationResult = await this.sampleTypeRepository.search({ + ...input, + filter: { + $and: [ + input.filter ?? {}, + accessibleBy(ability, SampleTypeAction.Read).SampleType, + ], + }, + }) + + return paginationResult + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/update.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/update.ts new file mode 100644 index 00000000..8e5bbb80 --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/update.ts @@ -0,0 +1,38 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { SampleTypeAction } from 'src/domain/entity' +import { AuthSubject, assertPermission } from 'src/domain/auth' +import { + AuthContextToken, + SampleTypeRepositoryToken, + IAuthContext, + ISampleTypeRepository, +} from 'src/domain/interface' +import { SampleTypeAssertExistsUseCase } from './assert-exists' +import { SampleTypeValidateUseCase } from './validate' + +@Injectable() +export class SampleTypeUpdateUseCase { + constructor( + @Inject(SampleTypeRepositoryToken) + private readonly sampleTypeRepository: ISampleTypeRepository, + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly sampleTypeAssertExistsUseCase: SampleTypeAssertExistsUseCase, + private readonly sampleTypeValidateUseCase: SampleTypeValidateUseCase, + ) {} + + async execute(...input: Parameters) { + const entity = await this.sampleTypeAssertExistsUseCase.execute(input[0]) + const { ability } = this.authContext.getData() + assertPermission( + ability, + AuthSubject.SampleType, + SampleTypeAction.Update, + entity, + ) + await this.sampleTypeValidateUseCase.execute(input[1]) + + return this.sampleTypeRepository.update(...input) + } +} diff --git a/apps/hcdc-access-service/src/domain/use-case/sample-type/validate.ts b/apps/hcdc-access-service/src/domain/use-case/sample-type/validate.ts new file mode 100644 index 00000000..d9773b4b --- /dev/null +++ b/apps/hcdc-access-service/src/domain/use-case/sample-type/validate.ts @@ -0,0 +1,32 @@ +import { Inject, Injectable } from '@nestjs/common' + +import { SampleType, BranchAction, EntityData } from 'src/domain/entity' +import { BranchAssertExistsUseCase } from '../branch/assert-exists' +import { AuthContextToken, IAuthContext } from 'src/domain/interface' +import { AuthSubject, assertPermission } from 'src/domain/auth' + +@Injectable() +export class SampleTypeValidateUseCase { + constructor( + @Inject(AuthContextToken) + private readonly authContext: IAuthContext, + private readonly branchAssertExistsUseCase: BranchAssertExistsUseCase, + ) {} + + async execute(input: Partial>) { + const { ability } = this.authContext.getData() + const { branchId } = input + + if (branchId !== undefined) { + const branch = await this.branchAssertExistsUseCase.execute({ + _id: branchId, + }) + assertPermission( + ability, + AuthSubject.Branch, + BranchAction.AssignToSubject, + branch, + ) + } + } +} diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/collection-classes.ts b/apps/hcdc-access-service/src/infrastructure/mongo/collection-classes.ts index 528e1c1f..40321a96 100644 --- a/apps/hcdc-access-service/src/infrastructure/mongo/collection-classes.ts +++ b/apps/hcdc-access-service/src/infrastructure/mongo/collection-classes.ts @@ -6,16 +6,19 @@ import { TestCategorySchema } from './test-category' import { UserSchema } from './user' import { BranchSchema } from './branch' import { RoleSchema } from './role' +import { InstrumentSchema } from './instrument' +import { SampleTypeSchema } from './sample-type' export const COLLECTION_CLASS: Record = { [COLLECTION.BIO_PRODUCT]: BioProductSchema, + [COLLECTION.INSTRUMENT]: InstrumentSchema, [COLLECTION.ROLE]: RoleSchema, // [COLLECTION.DOCTOR]: Doctor, // [COLLECTION.INDICATION]: Indication, // [COLLECTION.PATIENT]: Patient, // [COLLECTION.PATIENT_TYPE]: PatientType, // [COLLECTION.SAMPLE]: Sample, - // [COLLECTION.SAMPLE_TYPE]: SampleType, + [COLLECTION.SAMPLE_TYPE]: SampleTypeSchema, // [COLLECTION.TEST]: Test, [COLLECTION.TEST_CATEGORY]: TestCategorySchema, // [COLLECTION.TEST_COMBO]: TestCombo, diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/collections.ts b/apps/hcdc-access-service/src/infrastructure/mongo/collections.ts index 0964e9c8..2fcb5c50 100644 --- a/apps/hcdc-access-service/src/infrastructure/mongo/collections.ts +++ b/apps/hcdc-access-service/src/infrastructure/mongo/collections.ts @@ -10,7 +10,8 @@ export enum COLLECTION { // INDICATION = 'indication', // SAMPLE = 'sample', BIO_PRODUCT = 'bio_product', - // SAMPLE_TYPE = 'sample_type', + INSTRUMENT = 'instrument', + SAMPLE_TYPE = 'sample_type', // TEST_COMBO = 'test_combo', // PRINT_FORM = 'print_form', // SAMPLE_ORIGIN = 'sample_origin', diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/instrument/index.ts b/apps/hcdc-access-service/src/infrastructure/mongo/instrument/index.ts new file mode 100644 index 00000000..ea70ac25 --- /dev/null +++ b/apps/hcdc-access-service/src/infrastructure/mongo/instrument/index.ts @@ -0,0 +1,2 @@ +export * from './repository' +export * from './schema' diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/instrument/repository.ts b/apps/hcdc-access-service/src/infrastructure/mongo/instrument/repository.ts new file mode 100644 index 00000000..ded3ed3e --- /dev/null +++ b/apps/hcdc-access-service/src/infrastructure/mongo/instrument/repository.ts @@ -0,0 +1,17 @@ +import { InjectModel } from '@nestjs/mongoose' +import { MongoRepository } from '@diut/nest-core' +import { Model } from 'mongoose' + +import { IInstrumentRepository } from 'src/domain' +import { InstrumentSchema } from './schema' + +export class InstrumentRepository + extends MongoRepository + implements IInstrumentRepository +{ + constructor( + @InjectModel(InstrumentSchema.name) model: Model, + ) { + super(model) + } +} diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/instrument/schema.ts b/apps/hcdc-access-service/src/infrastructure/mongo/instrument/schema.ts new file mode 100644 index 00000000..f112dac3 --- /dev/null +++ b/apps/hcdc-access-service/src/infrastructure/mongo/instrument/schema.ts @@ -0,0 +1,32 @@ +import { Prop, Schema } from '@nestjs/mongoose' +import { BaseSchema, baseSchemaOptions } from '@diut/nest-core' +import { Types } from 'mongoose' + +import { COLLECTION } from '../collections' +import { BranchSchema } from '../branch' + +@Schema({ + ...baseSchemaOptions, + collection: COLLECTION.INSTRUMENT, + virtuals: { + branch: { + options: { + ref: BranchSchema.name, + localField: 'branchId', + foreignField: '_id', + justOne: true, + }, + }, + }, +}) +export class InstrumentSchema extends BaseSchema { + @Prop({ required: true }) + displayIndex: number + + @Prop({ required: true }) + name: string + + @Prop({ required: true, type: Types.ObjectId }) + branchId: string + branch?: BranchSchema | null +} diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/module.ts b/apps/hcdc-access-service/src/infrastructure/mongo/module.ts index ba3205e3..2427485a 100644 --- a/apps/hcdc-access-service/src/infrastructure/mongo/module.ts +++ b/apps/hcdc-access-service/src/infrastructure/mongo/module.ts @@ -5,7 +5,9 @@ import { MongoConfig, loadMongoConfig } from 'src/config' import { BioProductRepositoryToken, BranchRepositoryToken, + InstrumentRepositoryToken, RoleRepositoryToken, + SampleTypeRepositoryToken, TestCategoryRepositoryToken, UserRepositoryToken, } from 'src/domain' @@ -14,6 +16,8 @@ import { TestCategoryRepository, TestCategorySchema } from './test-category' import { UserRepository, UserSchema } from './user' import { BranchRepository, BranchSchema } from './branch' import { RoleRepository, RoleSchema } from './role' +import { InstrumentRepository, InstrumentSchema } from './instrument' +import { SampleTypeRepository, SampleTypeSchema } from './sample-type' export const mongoMetadata: ModuleMetadata = { imports: [ @@ -29,12 +33,22 @@ export const mongoMetadata: ModuleMetadata = { MongoModule.forFeature(UserSchema), MongoModule.forFeature(BranchSchema), MongoModule.forFeature(RoleSchema), + MongoModule.forFeature(InstrumentSchema), + MongoModule.forFeature(SampleTypeSchema), ], providers: [ { provide: BioProductRepositoryToken, useClass: BioProductRepository, }, + { + provide: InstrumentRepositoryToken, + useClass: InstrumentRepository, + }, + { + provide: SampleTypeRepositoryToken, + useClass: SampleTypeRepository, + }, { provide: TestCategoryRepositoryToken, useClass: TestCategoryRepository, diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/index.ts b/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/index.ts new file mode 100644 index 00000000..ea70ac25 --- /dev/null +++ b/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/index.ts @@ -0,0 +1,2 @@ +export * from './repository' +export * from './schema' diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/repository.ts b/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/repository.ts new file mode 100644 index 00000000..164bacc7 --- /dev/null +++ b/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/repository.ts @@ -0,0 +1,17 @@ +import { InjectModel } from '@nestjs/mongoose' +import { MongoRepository } from '@diut/nest-core' +import { Model } from 'mongoose' + +import { ISampleTypeRepository } from 'src/domain' +import { SampleTypeSchema } from './schema' + +export class SampleTypeRepository + extends MongoRepository + implements ISampleTypeRepository +{ + constructor( + @InjectModel(SampleTypeSchema.name) model: Model, + ) { + super(model) + } +} diff --git a/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/schema.ts b/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/schema.ts new file mode 100644 index 00000000..0c6ec419 --- /dev/null +++ b/apps/hcdc-access-service/src/infrastructure/mongo/sample-type/schema.ts @@ -0,0 +1,32 @@ +import { Prop, Schema } from '@nestjs/mongoose' +import { BaseSchema, baseSchemaOptions } from '@diut/nest-core' +import { Types } from 'mongoose' + +import { COLLECTION } from '../collections' +import { BranchSchema } from '../branch' + +@Schema({ + ...baseSchemaOptions, + collection: COLLECTION.SAMPLE_TYPE, + virtuals: { + branch: { + options: { + ref: BranchSchema.name, + localField: 'branchId', + foreignField: '_id', + justOne: true, + }, + }, + }, +}) +export class SampleTypeSchema extends BaseSchema { + @Prop({ required: true }) + displayIndex: number + + @Prop({ required: true }) + name: string + + @Prop({ required: true, type: Types.ObjectId }) + branchId: string + branch?: BranchSchema | null +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/controller.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/controller.ts new file mode 100644 index 00000000..3023f7f8 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/controller.ts @@ -0,0 +1,66 @@ +import { Body, Param } from '@nestjs/common' +import { ObjectIdPipe } from '@diut/nest-core' + +import { instrumentRoutes } from './routes' +import { + InstrumentCreateUseCase, + InstrumentDeleteUseCase, + InstrumentSearchUseCase, + InstrumentUpdateUseCase, + InstrumentFindOneUseCase, + EEntityNotFound, +} from 'src/domain' +import { InstrumentCreateRequestDto } from './dto/create.request-dto' +import { InstrumentUpdateRequestDto } from './dto/update.request-dto' +import { InstrumentSearchRequestDto } from './dto/search.request-dto' +import { HttpController, HttpRoute } from '../../common' + +@HttpController({ + basePath: 'v1/instruments', +}) +export class InstrumentController { + constructor( + private readonly instrumentCreateUseCase: InstrumentCreateUseCase, + private readonly instrumentUpdateUseCase: InstrumentUpdateUseCase, + private readonly instrumentDeleteUseCase: InstrumentDeleteUseCase, + private readonly instrumentSearchUseCase: InstrumentSearchUseCase, + private readonly instrumentFindOneUseCase: InstrumentFindOneUseCase, + ) {} + + @HttpRoute(instrumentRoutes.search) + search(@Body() body: InstrumentSearchRequestDto) { + return this.instrumentSearchUseCase.execute(body) + } + + @HttpRoute(instrumentRoutes.create) + create(@Body() body: InstrumentCreateRequestDto) { + return this.instrumentCreateUseCase.execute(body) + } + + @HttpRoute(instrumentRoutes.findById) + async findById(@Param('id', ObjectIdPipe) id: string) { + const rv = await this.instrumentFindOneUseCase.execute({ + filter: { _id: id }, + populates: [{ path: 'branch' }], + }) + + if (rv === null) { + throw new EEntityNotFound(`Instrument id=${id}`) + } + + return rv + } + + @HttpRoute(instrumentRoutes.updateById) + updateById( + @Param('id', ObjectIdPipe) id: string, + @Body() body: InstrumentUpdateRequestDto, + ) { + return this.instrumentUpdateUseCase.execute({ _id: id }, body) + } + + @HttpRoute(instrumentRoutes.deleteById) + deleteById(@Param('id', ObjectIdPipe) id: string) { + return this.instrumentDeleteUseCase.execute({ id }) + } +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/create.request-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/create.request-dto.ts new file mode 100644 index 00000000..c096d30c --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/create.request-dto.ts @@ -0,0 +1,25 @@ +import { IsObjectId } from '@diut/nest-core' +import { ApiProperty } from '@nestjs/swagger' +import { Expose } from 'class-transformer' +import { IsNotEmpty, IsNumber, IsString, Min } from 'class-validator' + +import { exampleInstrument } from 'src/domain' + +export class InstrumentCreateRequestDto { + @Expose() + @ApiProperty(exampleInstrument.displayIndex) + @IsNumber() + @Min(1) + displayIndex: number + + @Expose() + @ApiProperty(exampleInstrument.name) + @IsString() + @IsNotEmpty() + name: string + + @Expose() + @ApiProperty(exampleInstrument.branchId) + @IsObjectId() + branchId: string +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/response-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/response-dto.ts new file mode 100644 index 00000000..2cbc821c --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/response-dto.ts @@ -0,0 +1,19 @@ +import { ApiProperty, IntersectionType } from '@nestjs/swagger' +import { BaseResourceResponseDto } from '@diut/nest-core' +import { Expose, Type } from 'class-transformer' +import { ValidateNested } from 'class-validator' + +import { InstrumentCreateRequestDto } from './create.request-dto' +import { Branch, exampleInstrument } from 'src/domain' +import { BranchResponseDto } from '../../branch/dto/response-dto' + +export class InstrumentResponseDto extends IntersectionType( + BaseResourceResponseDto, + InstrumentCreateRequestDto, +) { + @Expose() + @ApiProperty({ ...exampleInstrument.branch, type: () => BranchResponseDto }) + @ValidateNested({ each: true }) + @Type(() => BranchResponseDto) + branch?: Branch +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.request-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.request-dto.ts new file mode 100644 index 00000000..e4ca700e --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.request-dto.ts @@ -0,0 +1,5 @@ +import { SearchRequestDto } from '@diut/nest-core' + +import { Instrument } from 'src/domain' + +export class InstrumentSearchRequestDto extends SearchRequestDto {} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.response-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.response-dto.ts new file mode 100644 index 00000000..5847a452 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/search.response-dto.ts @@ -0,0 +1,7 @@ +import { PaginatedResponse } from '@diut/nest-core' + +import { InstrumentResponseDto } from './response-dto' + +export class InstrumentSearchResponseDto extends PaginatedResponse( + InstrumentResponseDto, +) {} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/update.request-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/update.request-dto.ts new file mode 100644 index 00000000..ab005cf7 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/dto/update.request-dto.ts @@ -0,0 +1,7 @@ +import { PartialType } from '@nestjs/swagger' + +import { InstrumentCreateRequestDto } from './create.request-dto' + +export class InstrumentUpdateRequestDto extends PartialType( + InstrumentCreateRequestDto, +) {} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/instrument/routes.ts b/apps/hcdc-access-service/src/presentation/http/v1/instrument/routes.ts new file mode 100644 index 00000000..9f60f015 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/instrument/routes.ts @@ -0,0 +1,73 @@ +import { HttpStatus, RequestMethod } from '@nestjs/common' +import { CustomHttpRouteOptions } from '@diut/nest-core' + +import { InstrumentSearchResponseDto } from './dto/search.response-dto' +import { InstrumentResponseDto } from './dto/response-dto' + +export const instrumentRoutes = { + search: { + path: 'search', + method: RequestMethod.POST, + code: HttpStatus.OK, + serialize: InstrumentSearchResponseDto, + openApi: { + responses: [ + { + type: InstrumentSearchResponseDto, + }, + ], + }, + }, + + create: { + method: RequestMethod.POST, + serialize: InstrumentResponseDto, + openApi: { + responses: [ + { + type: InstrumentResponseDto, + status: HttpStatus.CREATED, + }, + ], + }, + }, + + updateById: { + path: ':id', + method: RequestMethod.PATCH, + serialize: InstrumentResponseDto, + openApi: { + responses: [ + { + type: InstrumentResponseDto, + }, + ], + }, + }, + + findById: { + path: ':id', + method: RequestMethod.GET, + serialize: InstrumentResponseDto, + openApi: { + responses: [ + { + type: InstrumentResponseDto, + }, + ], + }, + }, + + deleteById: { + path: ':id', + method: RequestMethod.DELETE, + serialize: InstrumentResponseDto, + openApi: { + responses: [ + { + type: InstrumentResponseDto, + }, + ], + }, + }, +} satisfies Record diff --git a/apps/hcdc-access-service/src/presentation/http/v1/module.ts b/apps/hcdc-access-service/src/presentation/http/v1/module.ts index d20a53b3..cf2c4ec1 100644 --- a/apps/hcdc-access-service/src/presentation/http/v1/module.ts +++ b/apps/hcdc-access-service/src/presentation/http/v1/module.ts @@ -6,10 +6,14 @@ import { RoleController } from './role/controller' import { BranchController } from './branch/controller' import { UserController } from './user/controller' import { TestCategoryController } from './test-category/controller' +import { InstrumentController } from './instrument/controller' +import { SampleTypeController } from './sample-type/controller' export const httpControllerV1Metadata: ModuleMetadata = { controllers: [ BioProductController, + InstrumentController, + SampleTypeController, AuthController, RoleController, BranchController, diff --git a/apps/hcdc-access-service/src/presentation/http/v1/sample-type/controller.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/controller.ts new file mode 100644 index 00000000..a9dca9a5 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/controller.ts @@ -0,0 +1,66 @@ +import { Body, Param } from '@nestjs/common' +import { ObjectIdPipe } from '@diut/nest-core' + +import { sampleTypeRoutes } from './routes' +import { + SampleTypeCreateUseCase, + SampleTypeDeleteUseCase, + SampleTypeSearchUseCase, + SampleTypeUpdateUseCase, + SampleTypeFindOneUseCase, + EEntityNotFound, +} from 'src/domain' +import { SampleTypeCreateRequestDto } from './dto/create.request-dto' +import { SampleTypeUpdateRequestDto } from './dto/update.request-dto' +import { SampleTypeSearchRequestDto } from './dto/search.request-dto' +import { HttpController, HttpRoute } from '../../common' + +@HttpController({ + basePath: 'v1/sample-types', +}) +export class SampleTypeController { + constructor( + private readonly sampleTypeCreateUseCase: SampleTypeCreateUseCase, + private readonly sampleTypeUpdateUseCase: SampleTypeUpdateUseCase, + private readonly sampleTypeDeleteUseCase: SampleTypeDeleteUseCase, + private readonly sampleTypeSearchUseCase: SampleTypeSearchUseCase, + private readonly sampleTypeFindOneUseCase: SampleTypeFindOneUseCase, + ) {} + + @HttpRoute(sampleTypeRoutes.search) + search(@Body() body: SampleTypeSearchRequestDto) { + return this.sampleTypeSearchUseCase.execute(body) + } + + @HttpRoute(sampleTypeRoutes.create) + create(@Body() body: SampleTypeCreateRequestDto) { + return this.sampleTypeCreateUseCase.execute(body) + } + + @HttpRoute(sampleTypeRoutes.findById) + async findById(@Param('id', ObjectIdPipe) id: string) { + const rv = await this.sampleTypeFindOneUseCase.execute({ + filter: { _id: id }, + populates: [{ path: 'branch' }], + }) + + if (rv === null) { + throw new EEntityNotFound(`SampleType id=${id}`) + } + + return rv + } + + @HttpRoute(sampleTypeRoutes.updateById) + updateById( + @Param('id', ObjectIdPipe) id: string, + @Body() body: SampleTypeUpdateRequestDto, + ) { + return this.sampleTypeUpdateUseCase.execute({ _id: id }, body) + } + + @HttpRoute(sampleTypeRoutes.deleteById) + deleteById(@Param('id', ObjectIdPipe) id: string) { + return this.sampleTypeDeleteUseCase.execute({ id }) + } +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/create.request-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/create.request-dto.ts new file mode 100644 index 00000000..a39a635b --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/create.request-dto.ts @@ -0,0 +1,25 @@ +import { IsObjectId } from '@diut/nest-core' +import { ApiProperty } from '@nestjs/swagger' +import { Expose } from 'class-transformer' +import { IsNotEmpty, IsNumber, IsString, Min } from 'class-validator' + +import { exampleSampleType } from 'src/domain' + +export class SampleTypeCreateRequestDto { + @Expose() + @ApiProperty(exampleSampleType.displayIndex) + @IsNumber() + @Min(1) + displayIndex: number + + @Expose() + @ApiProperty(exampleSampleType.name) + @IsString() + @IsNotEmpty() + name: string + + @Expose() + @ApiProperty(exampleSampleType.branchId) + @IsObjectId() + branchId: string +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/response-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/response-dto.ts new file mode 100644 index 00000000..cd179cdf --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/response-dto.ts @@ -0,0 +1,19 @@ +import { ApiProperty, IntersectionType } from '@nestjs/swagger' +import { BaseResourceResponseDto } from '@diut/nest-core' +import { Expose, Type } from 'class-transformer' +import { ValidateNested } from 'class-validator' + +import { SampleTypeCreateRequestDto } from './create.request-dto' +import { Branch, exampleSampleType } from 'src/domain' +import { BranchResponseDto } from '../../branch/dto/response-dto' + +export class SampleTypeResponseDto extends IntersectionType( + BaseResourceResponseDto, + SampleTypeCreateRequestDto, +) { + @Expose() + @ApiProperty({ ...exampleSampleType.branch, type: () => BranchResponseDto }) + @ValidateNested({ each: true }) + @Type(() => BranchResponseDto) + branch?: Branch +} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.request-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.request-dto.ts new file mode 100644 index 00000000..1b9d7227 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.request-dto.ts @@ -0,0 +1,5 @@ +import { SearchRequestDto } from '@diut/nest-core' + +import { SampleType } from 'src/domain' + +export class SampleTypeSearchRequestDto extends SearchRequestDto {} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.response-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.response-dto.ts new file mode 100644 index 00000000..259244f6 --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/search.response-dto.ts @@ -0,0 +1,7 @@ +import { PaginatedResponse } from '@diut/nest-core' + +import { SampleTypeResponseDto } from './response-dto' + +export class SampleTypeSearchResponseDto extends PaginatedResponse( + SampleTypeResponseDto, +) {} diff --git a/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/update.request-dto.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/update.request-dto.ts new file mode 100644 index 00000000..8514446c --- /dev/null +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/dto/update.request-dto.ts @@ -0,0 +1,7 @@ +import { PartialType } from '@nestjs/swagger' + +import { SampleTypeCreateRequestDto } from './create.request-dto' + +export class SampleTypeUpdateRequestDto extends PartialType( + SampleTypeCreateRequestDto, +) {} diff --git a/resources/sample-types/sample-type.routes.ts b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/routes.ts similarity index 59% rename from resources/sample-types/sample-type.routes.ts rename to apps/hcdc-access-service/src/presentation/http/v1/sample-type/routes.ts index f8f68c92..b24771cf 100644 --- a/resources/sample-types/sample-type.routes.ts +++ b/apps/hcdc-access-service/src/presentation/http/v1/sample-type/routes.ts @@ -1,32 +1,25 @@ -import { Permission } from '@diut/hcdc-common' import { HttpStatus, RequestMethod } from '@nestjs/common' +import { CustomHttpRouteOptions } from '@diut/nest-core' -import { AppControllerOptions } from '@diut/nest-core' -import { AppRouteOptions } from 'src/common/route.decorator' -import { SearchSampleTypeResponseDto } from './dtos/search-sample-type.response-dto' -import { SampleTypeResponseDto } from './dtos/sample-type.response-dto' +import { SampleTypeSearchResponseDto } from './dto/search.response-dto' +import { SampleTypeResponseDto } from './dto/response-dto' export const sampleTypeRoutes = { - controller: { - basePath: 'sample-types', - }, - - search: { + search: { path: 'search', method: RequestMethod.POST, code: HttpStatus.OK, - serialize: SearchSampleTypeResponseDto, + serialize: SampleTypeSearchResponseDto, openApi: { responses: [ { - type: SearchSampleTypeResponseDto, + type: SampleTypeSearchResponseDto, }, ], }, }, - create: { - permissionAnyOf: [Permission.Admin], + create: { method: RequestMethod.POST, serialize: SampleTypeResponseDto, openApi: { @@ -39,8 +32,7 @@ export const sampleTypeRoutes = { }, }, - updateById: { - permissionAnyOf: [Permission.Admin], + updateById: { path: ':id', method: RequestMethod.PATCH, serialize: SampleTypeResponseDto, @@ -53,7 +45,7 @@ export const sampleTypeRoutes = { }, }, - findById: { + findById: { path: ':id', method: RequestMethod.GET, serialize: SampleTypeResponseDto, @@ -66,8 +58,7 @@ export const sampleTypeRoutes = { }, }, - deleteById: { - permissionAnyOf: [Permission.Admin], + deleteById: { path: ':id', method: RequestMethod.DELETE, serialize: SampleTypeResponseDto, @@ -79,4 +70,4 @@ export const sampleTypeRoutes = { ], }, }, -} +} satisfies Record diff --git a/resources/sample-types/dtos/create-sample-type.request-dto.ts b/resources/sample-types/dtos/create-sample-type.request-dto.ts deleted file mode 100644 index 888c4def..00000000 --- a/resources/sample-types/dtos/create-sample-type.request-dto.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { IsNotEmpty, IsNumber, IsString, Min } from 'class-validator' - -export class CreateSampleTypeRequestDto { - @ApiProperty({ - example: 'Máu', - }) - @IsString() - @IsNotEmpty() - name: string - - @ApiProperty({ - example: 2, - }) - @IsNumber() - @Min(1) - index: number -} diff --git a/resources/sample-types/dtos/sample-type.response-dto.ts b/resources/sample-types/dtos/sample-type.response-dto.ts deleted file mode 100644 index 3f254c9a..00000000 --- a/resources/sample-types/dtos/sample-type.response-dto.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { Expose } from 'class-transformer' -import { IsNotEmpty, IsNumber, IsString, Min } from 'class-validator' - -import { BaseResourceResponseDto } from '@diut/nest-core' - -export class SampleTypeResponseDto extends BaseResourceResponseDto { - @Expose() - @ApiProperty({ - example: 'Máu', - }) - @IsString() - @IsNotEmpty() - name: string - - @Expose() - @ApiProperty({ - example: 2, - }) - @IsNumber() - @Min(1) - index: number -} diff --git a/resources/sample-types/dtos/search-sample-type.request-dto.ts b/resources/sample-types/dtos/search-sample-type.request-dto.ts deleted file mode 100644 index 11ba29cd..00000000 --- a/resources/sample-types/dtos/search-sample-type.request-dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { SearchRequestDto } from '@diut/nest-core' -import { SampleType } from '../sample-type.schema' - -export class SearchSampleTypeRequestDto extends SearchRequestDto {} diff --git a/resources/sample-types/dtos/search-sample-type.response-dto.ts b/resources/sample-types/dtos/search-sample-type.response-dto.ts deleted file mode 100644 index 5926feb7..00000000 --- a/resources/sample-types/dtos/search-sample-type.response-dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { PaginatedResponse } from '@diut/nest-core' -import { SampleTypeResponseDto } from './sample-type.response-dto' - -export class SearchSampleTypeResponseDto extends PaginatedResponse( - SampleTypeResponseDto, -) {} diff --git a/resources/sample-types/dtos/update-sample-type.request-dto.ts b/resources/sample-types/dtos/update-sample-type.request-dto.ts deleted file mode 100644 index 6462298e..00000000 --- a/resources/sample-types/dtos/update-sample-type.request-dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { PartialType } from '@nestjs/swagger' - -import { CreateSampleTypeRequestDto } from './create-sample-type.request-dto' - -export class UpdateSampleTypeRequestDto extends PartialType( - CreateSampleTypeRequestDto, -) {} diff --git a/resources/sample-types/sample-type.controller.ts b/resources/sample-types/sample-type.controller.ts deleted file mode 100644 index 58417285..00000000 --- a/resources/sample-types/sample-type.controller.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Body, Logger, Param } from '@nestjs/common' -import { AppController, ObjectIdPipe } from '@diut/nest-core' - -import { AppRoute } from 'src/common/route.decorator' -import { CreateSampleTypeRequestDto } from './dtos/create-sample-type.request-dto' -import { SearchSampleTypeRequestDto } from './dtos/search-sample-type.request-dto' -import { UpdateSampleTypeRequestDto } from './dtos/update-sample-type.request-dto' -import { sampleTypeRoutes } from './sample-type.routes' -import { SampleTypeService } from './sample-type.service' - -@AppController(sampleTypeRoutes.controller) -export class SampleTypeController { - private logger: Logger - - constructor(private sampleTypeService: SampleTypeService) { - this.logger = new Logger(SampleTypeController.name) - } - - @AppRoute(sampleTypeRoutes.search) - search(@Body() body: SearchSampleTypeRequestDto) { - return this.sampleTypeService.search(body) - } - - @AppRoute(sampleTypeRoutes.create) - create(@Body() body: CreateSampleTypeRequestDto) { - return this.sampleTypeService.create(body) - } - - @AppRoute(sampleTypeRoutes.updateById) - updateById( - @Param('id', ObjectIdPipe) id: string, - @Body() body: UpdateSampleTypeRequestDto, - ) { - return this.sampleTypeService.updateById(id, body) - } - - @AppRoute(sampleTypeRoutes.findById) - findById(@Param('id', ObjectIdPipe) id: string) { - return this.sampleTypeService.findById(id) - } - - @AppRoute(sampleTypeRoutes.deleteById) - deleteById(@Param('id', ObjectIdPipe) id: string) { - return this.sampleTypeService.deleteById(id) - } -} diff --git a/resources/sample-types/sample-type.module.ts b/resources/sample-types/sample-type.module.ts deleted file mode 100644 index 16aceff3..00000000 --- a/resources/sample-types/sample-type.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from '@nestjs/common' - -import { MongoModule } from '@diut/nest-core' -import { SampleTypeController } from './sample-type.controller' -import { SampleType } from './sample-type.schema' -import { SampleTypeService } from './sample-type.service' - -@Module({ - imports: [MongoModule.forFeature(SampleType)], - providers: [SampleTypeService], - controllers: [SampleTypeController], - exports: [SampleTypeService], -}) -export class SampleTypeModule {} diff --git a/resources/sample-types/sample-type.schema.ts b/resources/sample-types/sample-type.schema.ts deleted file mode 100644 index b7ebef19..00000000 --- a/resources/sample-types/sample-type.schema.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Prop, Schema } from '@nestjs/mongoose' - -import { BaseSchema, baseSchemaOptions } from '@diut/nest-core' -import { COLLECTION } from 'src/infrastructure/mongo/collections' - -@Schema({ - ...baseSchemaOptions, - collection: COLLECTION.SAMPLE_TYPE, -}) -export class SampleType extends BaseSchema { - @Prop({ required: true }) - name: string - - @Prop({ required: true }) - index: number -} diff --git a/resources/sample-types/sample-type.service.ts b/resources/sample-types/sample-type.service.ts deleted file mode 100644 index 445d2ace..00000000 --- a/resources/sample-types/sample-type.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common' -import { InjectModel } from '@nestjs/mongoose' -import { Model } from 'mongoose' - -import { MongoRepository } from '@diut/nest-core' -import { SampleType } from './sample-type.schema' - -@Injectable() -export class SampleTypeService extends MongoRepository { - constructor(@InjectModel(SampleType.name) model: Model) { - super(model) - } -}