From 9441049201d96127825e053a1b232c3fcb73f031 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Wed, 7 Jun 2023 07:45:30 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20134:=20API=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=EF=BC=88IF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task1922: API修正(IF)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1922) - タスク取得APIの引数を修正 - directionとparamNameを追加 - 定数を文字列配列からオブジェクトに変更 ## レビューポイント - 引数の型を自作のものに修正したが問題ないか。 - Pull Request 128: API実装(ソート条件変更)で議論中 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば --- dictation_server/src/api/odms/openapi.json | 14 +++++++++++ dictation_server/src/constants/index.ts | 4 ++- .../accounts/accounts.controller.spec.ts | 7 ++++++ .../features/accounts/accounts.controller.ts | 4 +-- .../licenses/licenses.service.spec.ts | 2 +- .../src/features/licenses/licenses.service.ts | 2 +- .../src/features/tasks/types/types.ts | 25 ++++++++++++++++++- .../src/features/users/users.service.spec.ts | 2 +- .../tasks/tasks.repository.service.ts | 2 +- 9 files changed, 54 insertions(+), 8 deletions(-) diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json index 1d7bb5e..05e89d6 100644 --- a/dictation_server/src/api/odms/openapi.json +++ b/dictation_server/src/api/odms/openapi.json @@ -677,6 +677,20 @@ "description": "取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup", "example": "Uploaded,Pending,InProgress", "schema": { "type": "string" } + }, + { + "name": "direction", + "required": false, + "in": "query", + "description": "ASC/DESC", + "schema": { "type": "string" } + }, + { + "name": "paramName", + "required": false, + "in": "query", + "description": "JOB_NUMBER/STATUS/ENCRYPTION/AUTHOR_ID/FILE_NAME/FILE_LENGTH/FILE_SIZE/RECORDING_STARTED_DATE/RECORDING_FINISHED_DATE/UPLOAD_DATE/TRANSCRIPTION_STARTED_DATE/TRANSCRIPTION_FINISHED_DATE", + "schema": { "type": "string" } } ], "responses": { diff --git a/dictation_server/src/constants/index.ts b/dictation_server/src/constants/index.ts index 907e75d..626e5c7 100644 --- a/dictation_server/src/constants/index.ts +++ b/dictation_server/src/constants/index.ts @@ -149,5 +149,7 @@ export const TASK_LIST_SORTABLE_ATTRIBUTES = [ 'TRANSCRIPTION_FINISHED_DATE', ] as const; -// export const SORT_DIRECTIONS = { asc: 'ASC', desc: 'DESC' } as const; +/** + * タスク一覧のソート条件(昇順・降順) + */ export const SORT_DIRECTIONS = ['ASC', 'DESC'] as const; diff --git a/dictation_server/src/features/accounts/accounts.controller.spec.ts b/dictation_server/src/features/accounts/accounts.controller.spec.ts index 078cd5f..b2bbf73 100644 --- a/dictation_server/src/features/accounts/accounts.controller.spec.ts +++ b/dictation_server/src/features/accounts/accounts.controller.spec.ts @@ -1,6 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { AccountsController } from './accounts.controller'; import { AccountsService } from './accounts.service'; +import { ConfigModule } from '@nestjs/config'; describe('AccountsController', () => { let controller: AccountsController; @@ -8,6 +9,12 @@ describe('AccountsController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ + imports: [ + ConfigModule.forRoot({ + envFilePath: ['.env.local', '.env'], + isGlobal: true, + }), + ], controllers: [AccountsController], providers: [AccountsService], }) diff --git a/dictation_server/src/features/accounts/accounts.controller.ts b/dictation_server/src/features/accounts/accounts.controller.ts index e464208..9ca5acb 100644 --- a/dictation_server/src/features/accounts/accounts.controller.ts +++ b/dictation_server/src/features/accounts/accounts.controller.ts @@ -22,8 +22,8 @@ import { GetLicenseSummaryResponse, } from './types/types'; import { USER_ROLES, ADMIN_ROLES } from '../../constants'; -import { AuthGuard } from 'src/common/guards/auth/authguards'; -import { RoleGuard } from 'src/common/guards/role/roleguards'; +import { AuthGuard } from '../../common/guards/auth/authguards'; +import { RoleGuard } from '../../common/guards/role/roleguards'; @ApiTags('accounts') @Controller('accounts') diff --git a/dictation_server/src/features/licenses/licenses.service.spec.ts b/dictation_server/src/features/licenses/licenses.service.spec.ts index 3d700a0..632ada0 100644 --- a/dictation_server/src/features/licenses/licenses.service.spec.ts +++ b/dictation_server/src/features/licenses/licenses.service.spec.ts @@ -1,4 +1,4 @@ -import { AccessToken } from 'src/common/token'; +import { AccessToken } from '../../common/token'; import { CreateOrdersRequest } from './types/types'; import { makeDefaultAccountsRepositoryMockValue, diff --git a/dictation_server/src/features/licenses/licenses.service.ts b/dictation_server/src/features/licenses/licenses.service.ts index af402c7..71cc532 100644 --- a/dictation_server/src/features/licenses/licenses.service.ts +++ b/dictation_server/src/features/licenses/licenses.service.ts @@ -1,6 +1,6 @@ import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; -import { AccessToken } from 'src/common/token'; +import { AccessToken } from '../../common/token'; import { UsersRepositoryService, UserNotFoundError, diff --git a/dictation_server/src/features/tasks/types/types.ts b/dictation_server/src/features/tasks/types/types.ts index db27726..dc7094d 100644 --- a/dictation_server/src/features/tasks/types/types.ts +++ b/dictation_server/src/features/tasks/types/types.ts @@ -1,6 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { AudioOptionItem } from '../../../features/files/types/types'; -import { IsInt, IsOptional, Min } from 'class-validator'; +import { IsIn, IsInt, IsOptional, Min } from 'class-validator'; + +import { Type } from 'class-transformer'; +import { TASK_LIST_SORTABLE_ATTRIBUTES } from '../../../constants'; export class TasksRequest { @ApiProperty({ @@ -11,6 +14,7 @@ export class TasksRequest { @IsInt() @Min(0) @IsOptional() + @Type(() => Number) limit: number; @ApiProperty({ @@ -22,6 +26,7 @@ export class TasksRequest { @IsInt() @Min(0) @IsOptional() + @Type(() => Number) offset: number; @ApiProperty({ @@ -33,6 +38,24 @@ export class TasksRequest { @IsOptional() // TODO: 入力チェックを行うデコレータを追加する。@Matches or カスタムデコレータで実装想定。statusの値は先頭大文字であることまで一致しなくていいはず?(実装時レビューにて要確認) status?: string; + + @ApiProperty({ + required: false, + description: 'ASC/DESC', + }) + @IsIn(['ASC', 'DESC'], { message: 'invalid direction' }) + @IsOptional() + direction?: string; + + @ApiProperty({ + required: false, + description: `${TASK_LIST_SORTABLE_ATTRIBUTES.join('/')}`, + }) + @IsIn(TASK_LIST_SORTABLE_ATTRIBUTES, { + message: 'invalid attributes', + }) + @IsOptional() + paramName?: string; } export class Typist { diff --git a/dictation_server/src/features/users/users.service.spec.ts b/dictation_server/src/features/users/users.service.spec.ts index 2b06fda..7a69a77 100644 --- a/dictation_server/src/features/users/users.service.spec.ts +++ b/dictation_server/src/features/users/users.service.spec.ts @@ -1,5 +1,5 @@ import { HttpException, HttpStatus } from '@nestjs/common'; -import { AccessToken } from 'src/common/token'; +import { AccessToken } from '../../common/token'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { User as EntityUser } from '../../repositories/users/entity/user.entity'; import { EmailAlreadyVerifiedError } from '../../repositories/users/users.repository.service'; diff --git a/dictation_server/src/repositories/tasks/tasks.repository.service.ts b/dictation_server/src/repositories/tasks/tasks.repository.service.ts index 1f56d92..2ef4d20 100644 --- a/dictation_server/src/repositories/tasks/tasks.repository.service.ts +++ b/dictation_server/src/repositories/tasks/tasks.repository.service.ts @@ -3,7 +3,7 @@ import { DataSource } from 'typeorm'; import { Task } from './entity/task.entity'; import { TASK_STATUS } from '../../constants/index'; import { AudioFile } from '../audio_files/entity/audio_file.entity'; -import { AudioOptionItem as ParamOptionItem } from 'src/features/files/types/types'; +import { AudioOptionItem as ParamOptionItem } from '../../features/files/types/types'; import { AudioOptionItem } from '../audio_option_items/entity/audio_option_item.entity'; @Injectable()