From f5ce65add8be9a5d0e11b56eeb7869cb03effe62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B9=AF=E6=9C=AC=20=E9=96=8B?= Date: Mon, 12 Jun 2023 05:26:26 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20147:=20Task=E4=B8=80=E8=A6=A7API?= =?UTF-8?q?=E3=81=AEstatus=E3=81=AE=E5=85=A5=E5=8A=9B=E3=83=81=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=92=E8=A1=8C=E3=81=86=E3=83=87=E3=82=B3?= =?UTF-8?q?=E3=83=AC=E3=83=BC=E3=82=BF=E3=82=92=E5=AE=9F=E8=A3=85=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task1957: Task一覧APIのstatusの入力チェックを行うデコレータを実装する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1957) - Statusに該当する文字列が `,` で連結されている場合のみバリデーション通過となるようなデコレータを実装 ## レビューポイント - 実装コストを考慮して汎用的な指定をできるようにしなかったが問題ないか - 実装コードは妥当な実装になっているか ## 動作確認状況 - ローカルで確認 --- .../src/common/validators/status.validator.ts | 43 +++++++++++++++++++ .../src/features/tasks/types/types.ts | 3 +- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 dictation_server/src/common/validators/status.validator.ts diff --git a/dictation_server/src/common/validators/status.validator.ts b/dictation_server/src/common/validators/status.validator.ts new file mode 100644 index 0000000..eca361e --- /dev/null +++ b/dictation_server/src/common/validators/status.validator.ts @@ -0,0 +1,43 @@ +import { + registerDecorator, + ValidationArguments, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from 'class-validator'; +import { TASK_STATUS } from '../../constants'; + +@ValidatorConstraint() +export class IsStatusConstraint implements ValidatorConstraintInterface { + private readonly STATUS: string[] = Object.values(TASK_STATUS); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + validate(value: string, args: ValidationArguments): boolean { + if (value) { + // ,で分割した文字列のすべてがTASK_STATUSのプロパティに存在する値であった場合のみtrue + return value.split(',').every((state) => this.STATUS.includes(state)); + } else { + return false; + } + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + defaultMessage(validationArguments?: ValidationArguments): string { + return `invalid status string`; + } +} +/** + * ,で分割した文字列のすべてがTASK_STATUSのプロパティに存在する値であるかをチェックする + * @param [validationOptions] + * @returns + */ +export function IsStatus(validationOptions?: ValidationOptions) { + return (object: object, propertyName: string) => { + registerDecorator({ + name: 'IsStatus', + target: object.constructor, + propertyName, + options: validationOptions, + validator: IsStatusConstraint, + }); + }; +} diff --git a/dictation_server/src/features/tasks/types/types.ts b/dictation_server/src/features/tasks/types/types.ts index 7fe5ab6..fcaa5b1 100644 --- a/dictation_server/src/features/tasks/types/types.ts +++ b/dictation_server/src/features/tasks/types/types.ts @@ -3,6 +3,7 @@ import { AudioOptionItem } from '../../../features/files/types/types'; import { Type } from 'class-transformer'; import { IsIn, IsInt, IsOptional, Min } from 'class-validator'; import { TASK_LIST_SORTABLE_ATTRIBUTES } from '../../../constants'; +import { IsStatus } from '../../../common/validators/status.validator'; export class TasksRequest { @ApiProperty({ @@ -37,7 +38,7 @@ export class TasksRequest { example: 'Uploaded,Pending,InProgress', }) @IsOptional() - // TODO: 入力チェックを行うデコレータを追加する。@Matches or カスタムデコレータで実装想定。statusの値は先頭大文字であることまで一致しなくていいはず?(実装時レビューにて要確認) + @IsStatus() status?: string; @ApiProperty({