Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confirm API & Stages validation #17

Merged
merged 5 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions apps/api/src/app/mapping/mapping.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ import { MappingEntity } from '@impler/dal';

import { APIKeyGuard } from '../shared/framework/auth.gaurd';
import { ValidateMongoId } from '../shared/validations/valid-mongo-id.validation';
import { GetUploadCommand } from './../upload/usecases/get-upload/get-upload.command';
import { GetUploadCommand } from '../shared/usecases/get-upload/get-upload.command';
import { DoMapping } from './usecases/do-mapping/do-mapping.usecase';
import { DoMappingCommand } from './usecases/do-mapping/do-mapping.command';
import { GetUpload } from './../upload/usecases/get-upload/get-upload.usecase';
import { GetUpload } from '../shared/usecases/get-upload/get-upload.usecase';
import { GetMappings } from './usecases/get-mappings/get-mappings.usecase';
import { UpdateMappingCommand } from './usecases/update-mappings/update-mappings.command';
import { UpdateMappings } from './usecases/update-mappings/update-mappings.usecase';
import { FinalizeUpload } from './usecases/finalize-upload/finalize-upload.usecase';
import { UpdateMappingDto } from './dtos/update-columns.dto';
import { ValidateMapping } from './usecases/validate-mapping/validate-mapping.usecase';
import { validateUploadStatus } from '../shared/helpers/upload.helpers';
import { validateNotFound } from '../shared/helpers/common.helper';

@Controller('/mapping')
@ApiTags('Mappings')
Expand Down Expand Up @@ -42,6 +44,15 @@ export class MappingController {
})
);

// throw error if upload information not found
validateNotFound(uploadInformation, 'upload');

// Get mappings can be called only when file is uploaded or it's mapping in progress
validateUploadStatus(uploadInformation.status as UploadStatusEnum, [
UploadStatusEnum.UPLOADED,
UploadStatusEnum.MAPPING,
]);

if (uploadInformation.status === UploadStatusEnum.UPLOADED) {
await this.doMapping.execute(
DoMappingCommand.create({
Expand All @@ -64,6 +75,19 @@ export class MappingController {
@Param('uploadId', ValidateMongoId) _uploadId: string,
@Body(new ParseArrayPipe({ items: UpdateMappingDto, optional: true })) body: UpdateMappingDto[]
) {
const uploadInformation = await this.getUpload.execute(
GetUploadCommand.create({
uploadId: _uploadId,
select: 'status',
})
);

// throw error if upload information not found
validateNotFound(uploadInformation, 'upload');

// Finalize mapping can only be called after the mapping has been completed
validateUploadStatus(uploadInformation.status as UploadStatusEnum, [UploadStatusEnum.MAPPING]);

// validate mapping data
await this.validateMapping.execute(body, _uploadId);

Expand Down
3 changes: 1 addition & 2 deletions apps/api/src/app/mapping/mapping.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Module } from '@nestjs/common';
import { USE_CASES } from './usecases';
import { GetUpload } from './../upload/usecases/get-upload/get-upload.usecase';
import { MappingController } from './mapping.controller';
import { SharedModule } from '../shared/shared.module';

@Module({
imports: [SharedModule],
providers: [...USE_CASES, GetUpload],
providers: [...USE_CASES],
controllers: [MappingController],
})
export class MappingModule {}
2 changes: 2 additions & 0 deletions apps/api/src/app/mapping/usecases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { GetMappings } from './get-mappings/get-mappings.usecase';
import { UpdateMappings } from './update-mappings/update-mappings.usecase';
import { FinalizeUpload } from './finalize-upload/finalize-upload.usecase';
import { ValidateMapping } from './validate-mapping/validate-mapping.usecase';
import { GetUpload } from '../../shared/usecases/get-upload/get-upload.usecase';

export const USE_CASES = [
DoMapping,
GetMappings,
UpdateMappings,
FinalizeUpload,
ValidateMapping,
GetUpload,
//
];
13 changes: 13 additions & 0 deletions apps/api/src/app/review/dtos/confirm-review-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsOptional } from 'class-validator';

export class ConfirmReviewRequestDto {
@ApiProperty({
description: 'Boolean value indicating whether to process the invalid data or not.',
default: false,
required: false,
})
@IsBoolean()
@IsOptional()
processInvalidRecords: boolean;
}
42 changes: 40 additions & 2 deletions apps/api/src/app/review/review.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BadRequestException, Controller, Get, Param, UseGuards } from '@nestjs/common';
import { BadRequestException, Body, Controller, Get, Param, Post, UseGuards } from '@nestjs/common';
import { ApiOperation, ApiTags, ApiSecurity } from '@nestjs/swagger';
import { FileEntity } from '@impler/dal';
import { FileEntity, UploadEntity } from '@impler/dal';
import { UploadStatusEnum } from '@impler/shared';
import { APIMessages } from '../shared/constants';
import { APIKeyGuard } from '../shared/framework/auth.gaurd';
Expand All @@ -9,6 +9,13 @@ import { DoReview } from './usecases/do-review/do-review.usecase';
import { GetUploadInvalidData } from './usecases/get-upload-invalid-data/get-upload-invalid-data.usecase';
import { SaveReviewData } from './usecases/save-review-data/save-review-data.usecase';
import { GetFileInvalidData } from './usecases/get-file-invalid-data/get-file-invalid-data.usecase';
import { ValidateMongoId } from '../shared/validations/valid-mongo-id.validation';
import { ConfirmReviewRequestDto } from './dtos/confirm-review-request.dto';
import { GetUploadCommand } from '../shared/usecases/get-upload/get-upload.command';
import { GetUpload } from '../shared/usecases/get-upload/get-upload.usecase';
import { validateNotFound } from '../shared/helpers/common.helper';
import { ConfirmReview } from './usecases/confirm-review/confirm-review.usecase';
import { ConfirmReviewCommand } from './usecases/confirm-review/confirm-review.command';

@Controller('/review')
@ApiTags('Review')
Expand All @@ -17,6 +24,8 @@ import { GetFileInvalidData } from './usecases/get-file-invalid-data/get-file-in
export class ReviewController {
constructor(
private doReview: DoReview,
private getUpload: GetUpload,
private confirmReview: ConfirmReview,
private saveReviewData: SaveReviewData,
private getFileInvalidData: GetFileInvalidData,
private getUploadInvalidData: GetUploadInvalidData
Expand Down Expand Up @@ -45,4 +54,33 @@ export class ReviewController {
return this.getFileInvalidData.execute((uploadData._invalidDataFileId as unknown as FileEntity).path);
}
}

@Post(':uploadId/confirm')
@ApiOperation({
summary: 'Confirm review data for uploaded file',
})
async doConfirmReview(
@Param('uploadId', ValidateMongoId) _uploadId: string,
@Body() body: ConfirmReviewRequestDto
): Promise<UploadEntity> {
const uploadInformation = await this.getUpload.execute(
GetUploadCommand.create({
uploadId: _uploadId,
select: 'status',
})
);

// throw error if upload information not found
validateNotFound(uploadInformation, 'upload');

// upload files with status reviewing can only be confirmed
validateUploadStatus(uploadInformation.status as UploadStatusEnum, [UploadStatusEnum.REVIEWING]);

return this.confirmReview.execute(
ConfirmReviewCommand.create({
_uploadId: _uploadId,
processInvalidRecords: body.processInvalidRecords,
})
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IsBoolean, IsDefined, IsMongoId } from 'class-validator';
import { BaseCommand } from '../../../shared/commands/base.command';

export class ConfirmReviewCommand extends BaseCommand {
@IsDefined()
@IsMongoId()
_uploadId: string;

@IsDefined()
@IsBoolean()
processInvalidRecords: boolean;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Injectable } from '@nestjs/common';
import { UploadEntity, UploadRepository } from '@impler/dal';
import { ConfirmReviewCommand } from './confirm-review.command';
import { UploadStatusEnum } from '@impler/shared';

@Injectable()
export class ConfirmReview {
constructor(private uploadRepository: UploadRepository) {}

execute(command: ConfirmReviewCommand): Promise<UploadEntity> {
return this.uploadRepository.findOneAndUpdate(
{ _id: command._uploadId },
{ status: UploadStatusEnum.CONFIRMED, processInvalidRecords: command.processInvalidRecords }
);
}
}
4 changes: 4 additions & 0 deletions apps/api/src/app/review/usecases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import { DoReview } from './do-review/do-review.usecase';
import { SaveReviewData } from './save-review-data/save-review-data.usecase';
import { GetUploadInvalidData } from './get-upload-invalid-data/get-upload-invalid-data.usecase';
import { GetFileInvalidData } from './get-file-invalid-data/get-file-invalid-data.usecase';
import { GetUpload } from '../../shared/usecases/get-upload/get-upload.usecase';
import { ConfirmReview } from './confirm-review/confirm-review.usecase';

export const USE_CASES = [
DoReview,
GetUpload,
ConfirmReview,
SaveReviewData,
GetFileInvalidData,
GetUploadInvalidData,
Expand Down
14 changes: 14 additions & 0 deletions apps/api/src/app/shared/helpers/common.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { BadRequestException } from '@nestjs/common';
import { APIMessages } from '../constants';

export function validateNotFound(data: any, entityName: 'upload'): boolean {
if (data) return true;
else {
switch (entityName) {
case 'upload':
throw new BadRequestException(APIMessages.UPLOAD_NOT_FOUND);
default:
throw new BadRequestException();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IsDefined, IsMongoId, IsOptional, IsString } from 'class-validator';
import { BaseCommand } from '../../../shared/commands/base.command';
import { BaseCommand } from '../../commands/base.command';

export class GetUploadCommand extends BaseCommand {
@IsDefined()
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/app/upload/upload.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { ValidImportFile } from '../shared/validations/valid-import-file.validat
import { MakeUploadEntry } from './usecases/make-upload-entry/make-upload-entry.usecase';
import { MakeUploadEntryCommand } from './usecases/make-upload-entry/make-upload-entry.command';
import { ValidateMongoId } from '../shared/validations/valid-mongo-id.validation';
import { GetUpload } from './usecases/get-upload/get-upload.usecase';
import { GetUploadCommand } from './usecases/get-upload/get-upload.command';
import { GetUpload } from '../shared/usecases/get-upload/get-upload.usecase';
import { GetUploadCommand } from '../shared/usecases/get-upload/get-upload.command';
import { GetUploads } from './usecases/get-uploads/get-uploads.usecase';
import { GetUploadsCommand } from './usecases/get-uploads/get-uploads.command';
import { ValidateTemplate } from '../shared/validations/valid-template.validation';
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/app/upload/usecases/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MakeUploadEntry } from './make-upload-entry/make-upload-entry.usecase';
import { GetUpload } from './get-upload/get-upload.usecase';
import { GetUpload } from '../../shared/usecases/get-upload/get-upload.usecase';
import { GetUploads } from './get-uploads/get-uploads.usecase';

export const USE_CASES = [
Expand Down
2 changes: 2 additions & 0 deletions libs/dal/src/repositories/upload/upload.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ export class UploadEntity {
status: string;

extra: string;

processInvalidRecords: boolean;
}
4 changes: 4 additions & 0 deletions libs/dal/src/repositories/upload/upload.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ const uploadSchema = new Schema(
authHeaderValue: String,
status: String,
extra: String,
processInvalidRecords: {
type: Boolean,
default: false,
},
},
{ ...schemaOptions }
);
Expand Down