Skip to content

Commit

Permalink
feat: Added unique column exception
Browse files Browse the repository at this point in the history
  • Loading branch information
chavda-bhavik committed Jul 16, 2024
1 parent 770ed75 commit 9af0327
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ColumnRepository } from '@impler/dal';
import { AddColumnCommand } from '../../commands/add-column.command';
import { SaveSampleFile } from '@shared/usecases/save-sample-file/save-sample-file.usecase';
import { UpdateCustomization } from 'app/template/usecases';
import { UniqueColumnException } from '@shared/exceptions/unique-column.exception';

@Injectable()
export class AddColumn {
Expand All @@ -14,6 +15,10 @@ export class AddColumn {

async execute(command: AddColumnCommand, _templateId: string) {
const columns = await this.columnRepository.find({ _templateId });
const isKeyUnique = columns.some((column) => column.key === command.key);
if (isKeyUnique) {
throw new UniqueColumnException();
}
const column = await this.columnRepository.create({
...command,
sequence: columns.length,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Injectable } from '@nestjs/common';
import { ColumnRepository } from '@impler/dal';
import { DocumentNotFoundException } from '@shared/exceptions/document-not-found.exception';
import { SaveSampleFile } from '@shared/usecases/save-sample-file/save-sample-file.usecase';
import { UpdateCustomization } from 'app/template/usecases';
import { UpdateColumnCommand } from '../../commands/update-column.command';
import { UniqueColumnException } from '@shared/exceptions/unique-column.exception';
import { SaveSampleFile } from '@shared/usecases/save-sample-file/save-sample-file.usecase';
import { DocumentNotFoundException } from '@shared/exceptions/document-not-found.exception';

@Injectable()
export class UpdateColumn {
Expand All @@ -19,6 +20,12 @@ export class UpdateColumn {
throw new DocumentNotFoundException('Column', _id);
}

const columns = await this.columnRepository.find({ _templateId: column._templateId });
const isKeyUnique = columns.some((columnItem) => columnItem.key === command.key);
if (isKeyUnique) {
throw new UniqueColumnException();
}

command.dateFormats = command.dateFormats?.map((format) => format.toUpperCase()) || [];
const isKeyUpdated = command.key !== column.key || command.allowMultiSelect !== column.allowMultiSelect;
const isTypeUpdated = command.type !== column.type;
Expand All @@ -28,7 +35,6 @@ export class UpdateColumn {
column.isRequired !== command.isRequired;

column = await this.columnRepository.findOneAndUpdate({ _id }, command);
const columns = await this.columnRepository.find({ _templateId: column._templateId });

if (isKeyUpdated || isTypeUpdated || isFieldConditionUpdated) {
await this.saveSampleFile.execute(columns, column._templateId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';
import { Injectable, HttpStatus, HttpException, UnauthorizedException } from '@nestjs/common';
import { ProjectRepository, TemplateRepository } from '@impler/dal';
import { ValidRequestCommand } from './valid-request.command';
import { DocumentNotFoundException } from '@shared/exceptions/document-not-found.exception';

import { APIMessages } from '@shared/constants';
import { plainToClass } from 'class-transformer';
import { validate } from 'class-validator';
import { SchemaDto } from 'app/common/dtos/Schema.dto';
import { ValidRequestCommand } from './valid-request.command';
import { ProjectRepository, TemplateRepository } from '@impler/dal';
import { UniqueColumnException } from '@shared/exceptions/unique-column.exception';
import { DocumentNotFoundException } from '@shared/exceptions/document-not-found.exception';

@Injectable()
export class ValidRequest {
Expand Down Expand Up @@ -50,6 +52,11 @@ export class ValidRequest {
);
}

const columnKeysSet = new Set(parsedSchema.map((column) => column.key));
if (columnKeysSet.size !== parsedSchema.length) {
throw new UniqueColumnException(APIMessages.COLUMN_KEY_TAKEN);
}

for (const item of parsedSchema) {
const columnDto = plainToClass(SchemaDto, item);
const validationErrors = await validate(columnDto);
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/app/shared/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export const APIMessages = {
EMAIL_ALREADY_EXISTS: 'Email already exists',
INCORRECT_KEYS_FOUND: 'Invalid keys found! Please check and correct them from web',
INVALID_AUTH_TOKEN: 'Invalid authentication token',
COLUMN_KEY_TAKEN: 'Column with the same key already exists. Please provide a unique key from "Validations".',
COLUMN_KEY_DUPLICATED: 'Column with the same key already exists. Please provide a unique key.',
};

export const CONSTANTS = {
Expand Down
8 changes: 8 additions & 0 deletions apps/api/src/app/shared/exceptions/unique-column.exception.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { UnprocessableEntityException } from '@nestjs/common';
import { APIMessages } from '../constants';

export class UniqueColumnException extends UnprocessableEntityException {
constructor(message?: string) {
super(message || APIMessages.COLUMN_KEY_DUPLICATED);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { Injectable } from '@nestjs/common';

import { ColumnRepository, TemplateRepository } from '@impler/dal';
import { AddColumnCommand } from 'app/column/commands/add-column.command';
import { UniqueColumnException } from '@shared/exceptions/unique-column.exception';
import { SaveSampleFile } from '@shared/usecases/save-sample-file/save-sample-file.usecase';
import { UpdateCustomization } from '../update-customization/update-customization.usecase';
import { APIMessages } from '@shared/constants';

@Injectable()
export class UpdateTemplateColumns {
Expand All @@ -15,6 +17,10 @@ export class UpdateTemplateColumns {
) {}

async execute(command: AddColumnCommand[], _templateId: string) {
const columnKeysSet = new Set(command.map((column) => column.key));
if (columnKeysSet.size !== command.length) {
throw new UniqueColumnException(APIMessages.COLUMN_KEY_TAKEN);
}
await this.columnRepository.deleteMany({ _templateId });
command.forEach((column, index) => {
column.sequence = index;
Expand Down
2 changes: 2 additions & 0 deletions apps/web/config/constants.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ export const NOTIFICATION_KEYS = {

CARD_ADDED: 'CARD_ADDED',
CARD_REMOVED: 'CARD_REMOVED',

COLUMN_ERRROR: 'COLUMN_ERRROR',
};

export const ROUTES = {
Expand Down
13 changes: 12 additions & 1 deletion apps/web/hooks/useSchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { useEffect, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';

import { commonApi } from '@libs/api';
import { notify } from '@libs/notify';
import { track } from '@libs/amplitude';
import { IColumn, IErrorObject } from '@impler/shared';
import { API_KEYS, MODAL_KEYS, MODAL_TITLES } from '@config';
import { API_KEYS, MODAL_KEYS, MODAL_TITLES, NOTIFICATION_KEYS } from '@config';

import { useUpdateBulkColumns } from './useUpdateBulkColumns';
import { ConfirmDelete } from '@components/imports/forms/ConfirmDelete';
Expand Down Expand Up @@ -60,6 +61,11 @@ export function useSchema({ templateId }: UseSchemaProps) {
reset({});
setFocus('name');
},
onError: (error: IErrorObject) => {
notify(NOTIFICATION_KEYS.COLUMN_ERRROR, {
message: error.message,
});
},
}
);
const { mutate: updateColumn } = useMutation<IColumn, IErrorObject, { id: string; data: IColumn }, string[]>(
Expand All @@ -70,6 +76,11 @@ export function useSchema({ templateId }: UseSchemaProps) {
queryClient.invalidateQueries([API_KEYS.TEMPLATE_COLUMNS_LIST, templateId]);
modals.close(MODAL_KEYS.COLUMN_UPDATE);
},
onError: (error: IErrorObject) => {
notify(NOTIFICATION_KEYS.COLUMN_ERRROR, {
message: error.message,
});
},
}
);
const { mutate: onDelete } = useMutation<unknown, IErrorObject, string, string[]>(
Expand Down
5 changes: 5 additions & 0 deletions apps/web/libs/notify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ const Messages: Record<string, NotifyProps> = {
title: 'Card Removed',
message: 'Card is removed from the system.',
},
[NOTIFICATION_KEYS.COLUMN_ERRROR]: {
title: 'Issue with column data',
message: 'It looks like column data is not correct. Please fix it and try again.',
color: 'red',
},
};

interface NotifyProps {
Expand Down

0 comments on commit 9af0327

Please sign in to comment.