Skip to content

Commit

Permalink
feat(sample): add isLocked property and lock/unlock use cases
Browse files Browse the repository at this point in the history
  • Loading branch information
wermarter committed Dec 20, 2024
1 parent 7ecd587 commit d9ece87
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
#!/usr/bin/env -S pnpm exec ts-node -r tsconfig-paths/register
import { Sample } from '@diut/hcdc'
import { SchemaFactory } from '@nestjs/mongoose'
import * as dotenv from 'dotenv'
import * as mongoose from 'mongoose'
import { COLLECTION } from 'src/infra/mongo'
import { TestSchema } from 'src/infra/mongo/test'
import { SampleSchema } from 'src/infra/mongo/sample'
dotenv.config()

async function main() {
const [destDB] = await Promise.all([
mongoose.createConnection(process.env.DEST_MONGO_URI!).asPromise(),
])
const testModel = destDB.model(
COLLECTION.TEST,
SchemaFactory.createForClass(TestSchema),
const model = destDB.model(
COLLECTION.SAMPLE,
SchemaFactory.createForClass(SampleSchema),
)

// ---------------

let counter = 1
const cursor = destDB
.collection(COLLECTION.TEST)
.collection(COLLECTION.SAMPLE)
.find()
.project({ _id: 1, printFormIds: 1 })
.project({ _id: 1, isLocked: 1 })

for await (const doc of cursor) {
console.log(counter++)
const entity = doc as Sample

if (doc.printFormIds?.[0] === null) {
await testModel.updateOne(
if (entity.isLocked === undefined) {
await model.updateOne(
{ _id: doc._id },
{
$set: { printFormIds: [] },
$set: { isLocked: false },
},
)
console.log(doc._id)
// console.log(doc._id)
}
}

Expand Down
6 changes: 4 additions & 2 deletions apps/hcdc-access-service/src/app/sample/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { SampleDownloadResultImageUseCase } from './use-case/download-result-ima
import { SampleFindOneUseCase } from './use-case/find-one'
import { SampleGeneratePrintUrlUseCase } from './use-case/generate-print-url'
import { SampleInitResultUseCase } from './use-case/init-result'
import { SampleLockUseCase } from './use-case/lock'
import { SamplePrintUseCase } from './use-case/print'
import { SampleSearchUseCase } from './use-case/search'
import { SampleUpdateUseCase } from './use-case/update'
import { SampleUnlockUseCase } from './use-case/unlock'
import { SampleUpdateInfoUseCase } from './use-case/update-info'
import { SampleUpdateResultUseCase } from './use-case/update-result'
import { SampleUploadResultImageUseCase } from './use-case/upload-result-image'
Expand All @@ -20,7 +21,8 @@ export const sampleMetadata: ModuleMetadata = {
providers: [
SampleCreateUseCase,
SampleFindOneUseCase,
SampleUpdateUseCase,
SampleLockUseCase,
SampleUnlockUseCase,
SampleUpdateInfoUseCase,
SampleUpdateResultUseCase,
SampleDeleteUseCase,
Expand Down
1 change: 1 addition & 0 deletions apps/hcdc-access-service/src/app/sample/use-case/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class SampleCreateUseCase {
const entity = await this.sampleRepository.create({
...entityData,
isConfirmed: false,
isLocked: false,
sampleCompleted: false,
infoById: user._id,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,22 @@ import {
SAMPLE_REPO_TOKEN,
} from 'src/domain'
import { SampleAssertExistsUseCase } from './assert-exists'
import { SampleValidateUseCase } from './validate'

@Injectable()
export class SampleUpdateUseCase {
export class SampleLockUseCase {
constructor(
@Inject(SAMPLE_REPO_TOKEN)
private readonly sampleRepository: ISampleRepository,
@Inject(AUTH_CONTEXT_TOKEN)
private readonly authContext: IAuthContext,
private readonly sampleAssertExistsUseCase: SampleAssertExistsUseCase,
private readonly sampleValidateUseCase: SampleValidateUseCase,
) {}

async execute(...input: Parameters<ISampleRepository['update']>) {
async execute(input: Parameters<ISampleRepository['update']>[0]) {
const entity = await this.sampleAssertExistsUseCase.execute(input[0])
const { ability } = this.authContext.getData()
assertPermission(ability, AuthSubject.Sample, SampleAction.Update, entity)
await this.sampleValidateUseCase.execute(input[1])
assertPermission(ability, AuthSubject.Sample, SampleAction.Lock, entity)

return this.sampleRepository.update(...input)
await this.sampleRepository.update(input, { isLocked: true })
}
}
29 changes: 29 additions & 0 deletions apps/hcdc-access-service/src/app/sample/use-case/unlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { AuthSubject, SampleAction } from '@diut/hcdc'
import { Inject, Injectable } from '@nestjs/common'
import { assertPermission } from 'src/app/auth/common'
import {
AUTH_CONTEXT_TOKEN,
IAuthContext,
ISampleRepository,
SAMPLE_REPO_TOKEN,
} from 'src/domain'
import { SampleAssertExistsUseCase } from './assert-exists'

@Injectable()
export class SampleUnlockUseCase {
constructor(
@Inject(SAMPLE_REPO_TOKEN)
private readonly sampleRepository: ISampleRepository,
@Inject(AUTH_CONTEXT_TOKEN)
private readonly authContext: IAuthContext,
private readonly sampleAssertExistsUseCase: SampleAssertExistsUseCase,
) {}

async execute(input: Parameters<ISampleRepository['update']>[0]) {
const entity = await this.sampleAssertExistsUseCase.execute(input[0])
const { ability } = this.authContext.getData()
assertPermission(ability, AuthSubject.Sample, SampleAction.Lock, entity)

await this.sampleRepository.update(input, { isLocked: false })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const exampleSample = {
isNgoaiGio: {},
isTraBuuDien: {},
isConfirmed: {},
isLocked: {},
infoAt: exampleDate,
sampledAt: exampleDate,
printedAt: { ...exampleDate, required: false },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import { SampleDeleteUseCase } from 'src/app/sample/use-case/delete'
import { SampleDownloadResultImageUseCase } from 'src/app/sample/use-case/download-result-image'
import { SampleFindOneUseCase } from 'src/app/sample/use-case/find-one'
import { SampleGeneratePrintUrlUseCase } from 'src/app/sample/use-case/generate-print-url'
import { SampleLockUseCase } from 'src/app/sample/use-case/lock'
import { SamplePrintUseCase } from 'src/app/sample/use-case/print'
import { SampleSearchUseCase } from 'src/app/sample/use-case/search'
import { SampleUnlockUseCase } from 'src/app/sample/use-case/unlock'
import { SampleUpdateInfoUseCase } from 'src/app/sample/use-case/update-info'
import { SampleUpdateResultUseCase } from 'src/app/sample/use-case/update-result'
import { SampleUploadResultImageUseCase } from 'src/app/sample/use-case/upload-result-image'
Expand Down Expand Up @@ -54,6 +56,8 @@ export class SampleController {
private readonly sampleUploadResultImageUseCase: SampleUploadResultImageUseCase,
private readonly sampleDownloadResultImageUseCase: SampleDownloadResultImageUseCase,
private readonly sampleGeneratePrintUrlUseCase: SampleGeneratePrintUrlUseCase,
private readonly sampleLockUseCase: SampleLockUseCase,
private readonly sampleUnlockUseCase: SampleUnlockUseCase,
) {}

@HttpRoute(sampleRoutes.uploadResultImage)
Expand Down Expand Up @@ -176,6 +180,16 @@ export class SampleController {
return this.sampleDeleteUseCase.execute({ id })
}

@HttpRoute(sampleRoutes.lock)
lock(@Param('id', ObjectIdPipe) id: string) {
return this.sampleLockUseCase.execute({ id })
}

@HttpRoute(sampleRoutes.unlock)
unlock(@Param('id', ObjectIdPipe) id: string) {
return this.sampleUnlockUseCase.execute({ id })
}

@HttpRoute(sampleRoutes.print)
async print(
@Res({ passthrough: true }) res: Response,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ export class SampleRequestDto {
@IsBoolean()
isConfirmed: boolean

@Expose()
@ApiProperty(exampleSample.isLocked)
@IsBoolean()
isLocked: boolean

@Expose()
@ApiProperty(exampleSample.sampleCompleted)
@IsBoolean()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BaseResourceResponseDto, IsObjectId } from '@diut/nestjs-infra'
import {
ApiPropertyOptional,
IntersectionType,
OmitType,
PartialType,
PickType,
} from '@nestjs/swagger'
Expand All @@ -15,9 +16,13 @@ import { OmittedSampleResponseDto } from './response-dto'
class SampleInfoDto extends PickType(SampleRequestDto, [
...sampleInfoFieldNames,
'isConfirmed',
'isLocked',
]) {}

export class SampleUpdateInfoRequestDto extends PartialType(SampleInfoDto) {
export class SampleUpdateInfoRequestDto extends OmitType(
PartialType(SampleInfoDto),
['isLocked'],
) {
@Expose()
@ApiPropertyOptional(exampleMongoObjectIds)
@IsObjectId({ each: true })
Expand Down
10 changes: 10 additions & 0 deletions apps/hcdc-access-service/src/controller/http/v1/sample/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ export const sampleRoutes = {
method: RequestMethod.POST,
},

lock: {
path: ':id/lock',
method: RequestMethod.POST,
},

unlock: {
path: ':id/unlock',
method: RequestMethod.POST,
},

getPrintPath: {
path: 'get-print-path',
method: RequestMethod.POST,
Expand Down
3 changes: 3 additions & 0 deletions apps/hcdc-access-service/src/infra/mongo/sample/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ export class SampleSchema extends BaseSchema {
@Prop({ required: true })
isConfirmed: boolean

@Prop({ required: true })
isLocked: boolean

@Prop({ required: true })
infoAt: Date

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,17 @@ export function PrintSingleDialog(props: PrintSingleDialogProps) {
defaultValues: formDefaultValues,
})

const [getPrintPath, { isFetching }] = useLazySampleGetPrintPathQuery()
const [getPrintPath, { isFetching: isFetchingPrintPath }] =
useLazySampleGetPrintPathQuery()
const handleGetLink = async () => {
console.log(
(
await getPrintPath({
requests: [getPrintRequest(getValues())],
}).unwrap()
).path,
)
}

const [printSample] = useSamplePrintMutation()

Expand Down Expand Up @@ -209,7 +219,22 @@ export function PrintSingleDialog(props: PrintSingleDialogProps) {
props.onClose()
}}
>
<DialogTitle>ID xét nghiệm: {props.sample?.sampleId}</DialogTitle>
<DialogTitle>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
ID xét nghiệm: {props.sample?.sampleId}
</Box>
<LoadingButton
variant="outlined"
loading={isFetchingPrintPath}
onClick={handleGetLink}
color="secondary"
>
Link
</LoadingButton>
</Box>
</DialogTitle>

<DialogContent dividers>
<FormContainer onSubmit={handleSubmit(handlePrint)}>
<Grid container spacing={2}>
Expand Down Expand Up @@ -305,30 +330,16 @@ export function PrintSingleDialog(props: PrintSingleDialogProps) {
</Box>
<Box>
<Button
sx={{ mx: 1 }}
variant="outlined"
autoFocus
onClick={() => {
props.onClose()
}}
>
Bỏ qua
Đóng
</Button>
<LoadingButton
sx={{ mx: 1 }}
variant="outlined"
loading={isFetching}
onClick={async () => {
console.log(
(
await getPrintPath({
requests: [getPrintRequest(getValues())],
}).unwrap()
).path,
)
}}
>
Link
</LoadingButton>

<LoadingButton
type="submit"
variant="contained"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ export function ImageCropUpload(props: ImageCropUploadProps) {
if (rightUploadFile != null) {
// NO CROP, JUST UPLOAD
rightRes = await uploadImage({
sampleUploadImageDto: prepareFormData(rightUploadFile),
sampleUploadImageRequestDto: prepareFormData(rightUploadFile),
sampleId: props.sampleId,
testElementId: props.rightElementId,
}).unwrap()
Expand All @@ -241,7 +241,7 @@ export function ImageCropUpload(props: ImageCropUploadProps) {
if (leftUploadFile != null) {
// NEW IMAGE
leftRes = await uploadImage({
sampleUploadImageDto: prepareFormData(leftUploadFile),
sampleUploadImageRequestDto: prepareFormData(leftUploadFile),
sampleId: props.sampleId,
testElementId: props.leftElementId,
}).unwrap()
Expand Down
Loading

0 comments on commit d9ece87

Please sign in to comment.