From 1ced5ef66d95946e1b8c3bee3b82cd9051c9d3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B9=AF=E6=9C=AC=20=E9=96=8B?= Date: Fri, 2 Jun 2023 06:12:35 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20123:=20API=E5=AE=9F=E8=A3=85?= =?UTF-8?q?=EF=BC=88I/F=E5=AE=9F=E8=A3=85=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task1836: API実装(I/F実装)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1836) - タスクのソート条件更新APIのI/Fを実装 - タスク一覧APIのI/Fを修正 - TODO/XXXですぐ対処可能、または単純に消し忘れているものを対処 ## レビューポイント - API I/Fの修正は妥当な内容であるか - 特にfilterはカンマ区切りでいいか、指定したものを除外という形式でいいか等 - TODO/XXXの対処は妥当な対処であるか ## 動作確認状況 - ローカルでswagger表示されることを確認 --- dictation_client/src/api/api.ts | 162 +++- dictation_server/package.json | 2 +- dictation_server/src/api/odms/openapi.json | 844 ++++++------------ dictation_server/src/common/auth/auth.ts | 7 +- dictation_server/src/common/token/types.ts | 12 + dictation_server/src/constants/index.ts | 21 + .../notification/notification.controller.ts | 5 +- .../src/features/tasks/tasks.controller.ts | 4 +- .../src/features/tasks/types/types.ts | 18 + .../src/features/users/types/types.ts | 13 + .../src/features/users/users.controller.ts | 31 + .../src/features/users/users.service.ts | 2 - dictation_server/src/main.ts | 2 - 13 files changed, 496 insertions(+), 627 deletions(-) diff --git a/dictation_client/src/api/api.ts b/dictation_client/src/api/api.ts index dfbe824..d6de52a 100644 --- a/dictation_client/src/api/api.ts +++ b/dictation_client/src/api/api.ts @@ -490,6 +490,25 @@ export interface SignupRequest { */ 'notification': boolean; } +/** + * + * @export + * @interface SortCriteriaRequest + */ +export interface SortCriteriaRequest { + /** + * ASC/DESC + * @type {string} + * @memberof SortCriteriaRequest + */ + 'direction': string; + /** + * 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 + * @type {string} + * @memberof SortCriteriaRequest + */ + 'paramName': string; +} /** * * @export @@ -1284,11 +1303,14 @@ export const FilesApiAxiosParamCreator = function (configuration?: Configuration /** * アップロードが完了した音声ファイルの情報を登録し、文字起こしタスクを生成します * @summary + * @param {string} authorization * @param {AudioUploadFinishedRequest} audioUploadFinishedRequest * @param {*} [options] Override http request option. * @throws {RequiredError} */ - uploadFinished: async (audioUploadFinishedRequest: AudioUploadFinishedRequest, options: AxiosRequestConfig = {}): Promise => { + uploadFinished: async (authorization: string, audioUploadFinishedRequest: AudioUploadFinishedRequest, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('uploadFinished', 'authorization', authorization) // verify required parameter 'audioUploadFinishedRequest' is not null or undefined assertParamExists('uploadFinished', 'audioUploadFinishedRequest', audioUploadFinishedRequest) const localVarPath = `/files/audio/upload-finished`; @@ -1307,6 +1329,10 @@ export const FilesApiAxiosParamCreator = function (configuration?: Configuration // http bearer authentication required await setBearerAuthToObject(localVarHeaderParameter, configuration) + if (authorization != null) { + localVarHeaderParameter['authorization'] = String(authorization); + } + localVarHeaderParameter['Content-Type'] = 'application/json'; @@ -1324,10 +1350,13 @@ export const FilesApiAxiosParamCreator = function (configuration?: Configuration /** * ログイン中ユーザー用のBlob Storage上の音声ファイルのアップロード先アクセスURLを取得します * @summary + * @param {string} authorization * @param {*} [options] Override http request option. * @throws {RequiredError} */ - uploadLocation: async (options: AxiosRequestConfig = {}): Promise => { + uploadLocation: async (authorization: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'authorization' is not null or undefined + assertParamExists('uploadLocation', 'authorization', authorization) const localVarPath = `/files/audio/upload-location`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -1344,6 +1373,10 @@ export const FilesApiAxiosParamCreator = function (configuration?: Configuration // http bearer authentication required await setBearerAuthToObject(localVarHeaderParameter, configuration) + if (authorization != null) { + localVarHeaderParameter['authorization'] = String(authorization); + } + setSearchParams(localVarUrlObj, localVarQueryParameter); @@ -1390,22 +1423,24 @@ export const FilesApiFp = function(configuration?: Configuration) { /** * アップロードが完了した音声ファイルの情報を登録し、文字起こしタスクを生成します * @summary + * @param {string} authorization * @param {AudioUploadFinishedRequest} audioUploadFinishedRequest * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async uploadFinished(audioUploadFinishedRequest: AudioUploadFinishedRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFinished(audioUploadFinishedRequest, options); + async uploadFinished(authorization: string, audioUploadFinishedRequest: AudioUploadFinishedRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFinished(authorization, audioUploadFinishedRequest, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** * ログイン中ユーザー用のBlob Storage上の音声ファイルのアップロード先アクセスURLを取得します * @summary + * @param {string} authorization * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async uploadLocation(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.uploadLocation(options); + async uploadLocation(authorization: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.uploadLocation(authorization, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, } @@ -1441,21 +1476,23 @@ export const FilesApiFactory = function (configuration?: Configuration, basePath /** * アップロードが完了した音声ファイルの情報を登録し、文字起こしタスクを生成します * @summary + * @param {string} authorization * @param {AudioUploadFinishedRequest} audioUploadFinishedRequest * @param {*} [options] Override http request option. * @throws {RequiredError} */ - uploadFinished(audioUploadFinishedRequest: AudioUploadFinishedRequest, options?: any): AxiosPromise { - return localVarFp.uploadFinished(audioUploadFinishedRequest, options).then((request) => request(axios, basePath)); + uploadFinished(authorization: string, audioUploadFinishedRequest: AudioUploadFinishedRequest, options?: any): AxiosPromise { + return localVarFp.uploadFinished(authorization, audioUploadFinishedRequest, options).then((request) => request(axios, basePath)); }, /** * ログイン中ユーザー用のBlob Storage上の音声ファイルのアップロード先アクセスURLを取得します * @summary + * @param {string} authorization * @param {*} [options] Override http request option. * @throws {RequiredError} */ - uploadLocation(options?: any): AxiosPromise { - return localVarFp.uploadLocation(options).then((request) => request(axios, basePath)); + uploadLocation(authorization: string, options?: any): AxiosPromise { + return localVarFp.uploadLocation(authorization, options).then((request) => request(axios, basePath)); }, }; }; @@ -1494,24 +1531,26 @@ export class FilesApi extends BaseAPI { /** * アップロードが完了した音声ファイルの情報を登録し、文字起こしタスクを生成します * @summary + * @param {string} authorization * @param {AudioUploadFinishedRequest} audioUploadFinishedRequest * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof FilesApi */ - public uploadFinished(audioUploadFinishedRequest: AudioUploadFinishedRequest, options?: AxiosRequestConfig) { - return FilesApiFp(this.configuration).uploadFinished(audioUploadFinishedRequest, options).then((request) => request(this.axios, this.basePath)); + public uploadFinished(authorization: string, audioUploadFinishedRequest: AudioUploadFinishedRequest, options?: AxiosRequestConfig) { + return FilesApiFp(this.configuration).uploadFinished(authorization, audioUploadFinishedRequest, options).then((request) => request(this.axios, this.basePath)); } /** * ログイン中ユーザー用のBlob Storage上の音声ファイルのアップロード先アクセスURLを取得します * @summary + * @param {string} authorization * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof FilesApi */ - public uploadLocation(options?: AxiosRequestConfig) { - return FilesApiFp(this.configuration).uploadLocation(options).then((request) => request(this.axios, this.basePath)); + public uploadLocation(authorization: string, options?: AxiosRequestConfig) { + return FilesApiFp(this.configuration).uploadLocation(authorization, options).then((request) => request(this.axios, this.basePath)); } } @@ -1942,10 +1981,11 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration * @summary * @param {number} [limit] タスクの取得件数(指定しない場合はデフォルト値) * @param {number} [offset] オフセット(何件目から取得するか 設定しない場合はデフォルト値) + * @param {string} [status] 取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getTasks: async (limit?: number, offset?: number, options: AxiosRequestConfig = {}): Promise => { + getTasks: async (limit?: number, offset?: number, status?: string, options: AxiosRequestConfig = {}): Promise => { const localVarPath = `/tasks`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -1970,6 +2010,10 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration localVarQueryParameter['offset'] = offset; } + if (status !== undefined) { + localVarQueryParameter['status'] = status; + } + setSearchParams(localVarUrlObj, localVarQueryParameter); @@ -2127,11 +2171,12 @@ export const TasksApiFp = function(configuration?: Configuration) { * @summary * @param {number} [limit] タスクの取得件数(指定しない場合はデフォルト値) * @param {number} [offset] オフセット(何件目から取得するか 設定しない場合はデフォルト値) + * @param {string} [status] 取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getTasks(limit?: number, offset?: number, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getTasks(limit, offset, options); + async getTasks(limit?: number, offset?: number, status?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTasks(limit, offset, status, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -2221,11 +2266,12 @@ export const TasksApiFactory = function (configuration?: Configuration, basePath * @summary * @param {number} [limit] タスクの取得件数(指定しない場合はデフォルト値) * @param {number} [offset] オフセット(何件目から取得するか 設定しない場合はデフォルト値) + * @param {string} [status] 取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getTasks(limit?: number, offset?: number, options?: any): AxiosPromise { - return localVarFp.getTasks(limit, offset, options).then((request) => request(axios, basePath)); + getTasks(limit?: number, offset?: number, status?: string, options?: any): AxiosPromise { + return localVarFp.getTasks(limit, offset, status, options).then((request) => request(axios, basePath)); }, /** * 指定した文字起こしタスクを差し戻します(ステータスをPendingにします) @@ -2322,12 +2368,13 @@ export class TasksApi extends BaseAPI { * @summary * @param {number} [limit] タスクの取得件数(指定しない場合はデフォルト値) * @param {number} [offset] オフセット(何件目から取得するか 設定しない場合はデフォルト値) + * @param {string} [status] 取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TasksApi */ - public getTasks(limit?: number, offset?: number, options?: AxiosRequestConfig) { - return TasksApiFp(this.configuration).getTasks(limit, offset, options).then((request) => request(this.axios, this.basePath)); + public getTasks(limit?: number, offset?: number, status?: string, options?: AxiosRequestConfig) { + return TasksApiFp(this.configuration).getTasks(limit, offset, status, options).then((request) => request(this.axios, this.basePath)); } /** @@ -2537,6 +2584,46 @@ export const UsersApiAxiosParamCreator = function (configuration?: Configuration localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; localVarRequestOptions.data = serializeDataIfNeeded(signupRequest, localVarRequestOptions, configuration) + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * ログインしているユーザーのタスクソート条件を更新します + * @summary + * @param {SortCriteriaRequest} sortCriteriaRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateSortCcriteria: async (sortCriteriaRequest: SortCriteriaRequest, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'sortCriteriaRequest' is not null or undefined + assertParamExists('updateSortCcriteria', 'sortCriteriaRequest', sortCriteriaRequest) + const localVarPath = `/users/sort-criteria`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(sortCriteriaRequest, localVarRequestOptions, configuration) + return { url: toPathString(localVarUrlObj), options: localVarRequestOptions, @@ -2605,6 +2692,17 @@ export const UsersApiFp = function(configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.signup(signupRequest, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, + /** + * ログインしているユーザーのタスクソート条件を更新します + * @summary + * @param {SortCriteriaRequest} sortCriteriaRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateSortCcriteria(sortCriteriaRequest: SortCriteriaRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateSortCcriteria(sortCriteriaRequest, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, } }; @@ -2663,6 +2761,16 @@ export const UsersApiFactory = function (configuration?: Configuration, basePath signup(signupRequest: SignupRequest, options?: any): AxiosPromise { return localVarFp.signup(signupRequest, options).then((request) => request(axios, basePath)); }, + /** + * ログインしているユーザーのタスクソート条件を更新します + * @summary + * @param {SortCriteriaRequest} sortCriteriaRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateSortCcriteria(sortCriteriaRequest: SortCriteriaRequest, options?: any): AxiosPromise { + return localVarFp.updateSortCcriteria(sortCriteriaRequest, options).then((request) => request(axios, basePath)); + }, }; }; @@ -2730,6 +2838,18 @@ export class UsersApi extends BaseAPI { public signup(signupRequest: SignupRequest, options?: AxiosRequestConfig) { return UsersApiFp(this.configuration).signup(signupRequest, options).then((request) => request(this.axios, this.basePath)); } + + /** + * ログインしているユーザーのタスクソート条件を更新します + * @summary + * @param {SortCriteriaRequest} sortCriteriaRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public updateSortCcriteria(sortCriteriaRequest: SortCriteriaRequest, options?: AxiosRequestConfig) { + return UsersApiFp(this.configuration).updateSortCcriteria(sortCriteriaRequest, options).then((request) => request(this.axios, this.basePath)); + } } diff --git a/dictation_server/package.json b/dictation_server/package.json index 5a738d6..ad284a5 100644 --- a/dictation_server/package.json +++ b/dictation_server/package.json @@ -23,7 +23,7 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", "og": "openapi-generator-cli", - "swgbundle:sentinel": "swagger-cli bundle -o openapi/build/bundle.yml -t yaml openapi/sentinel_ems/sentinel_ems.yml" + "openapi-format": "cat \"src/api/odms/openapi.json\" | jq -c . > \"src/api/odms/openapi.json\" && prettier --write \"src/api/odms/*.json\"" }, "dependencies": { "@azure/identity": "^3.1.3", diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json index 8c597b0..ef8e82e 100644 --- a/dictation_server/src/api/odms/openapi.json +++ b/dictation_server/src/api/odms/openapi.json @@ -6,11 +6,7 @@ "operationId": "checkHealth", "summary": "", "parameters": [], - "responses": { - "200": { - "description": "" - } - } + "responses": { "200": { "description": "" } } } }, "/auth/token": { @@ -23,9 +19,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenRequest" - } + "schema": { "$ref": "#/components/schemas/TokenRequest" } } } }, @@ -34,9 +28,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/TokenResponse" - } + "schema": { "$ref": "#/components/schemas/TokenResponse" } } } }, @@ -44,9 +36,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -54,9 +44,7 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } @@ -75,9 +63,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/AccessTokenResponse" - } + "schema": { "$ref": "#/components/schemas/AccessTokenResponse" } } } }, @@ -85,9 +71,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -95,19 +79,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["auth"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/accounts": { @@ -119,9 +97,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateAccountRequest" - } + "schema": { "$ref": "#/components/schemas/CreateAccountRequest" } } } }, @@ -140,9 +116,7 @@ "description": "登録済みユーザーからの登録など", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -150,9 +124,7 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } @@ -169,9 +141,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ConfirmRequest" - } + "schema": { "$ref": "#/components/schemas/ConfirmRequest" } } } }, @@ -180,9 +150,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ConfirmResponse" - } + "schema": { "$ref": "#/components/schemas/ConfirmResponse" } } } }, @@ -190,9 +158,7 @@ "description": "不正なトークン", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -200,9 +166,7 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } @@ -219,9 +183,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ConfirmRequest" - } + "schema": { "$ref": "#/components/schemas/ConfirmRequest" } } } }, @@ -230,9 +192,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ConfirmResponse" - } + "schema": { "$ref": "#/components/schemas/ConfirmResponse" } } } }, @@ -240,9 +200,7 @@ "description": "不正なトークン", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -250,9 +208,7 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } @@ -270,9 +226,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/GetUsersResponse" - } + "schema": { "$ref": "#/components/schemas/GetUsersResponse" } } } }, @@ -280,9 +234,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -290,19 +242,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["users"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/users/signup": { @@ -314,9 +260,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/SignupRequest" - } + "schema": { "$ref": "#/components/schemas/SignupRequest" } } } }, @@ -325,9 +269,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/SignupResponse" - } + "schema": { "$ref": "#/components/schemas/SignupResponse" } } } }, @@ -335,9 +277,7 @@ "description": "登録済みメールによる再登録、AuthorIDの重複など", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -345,9 +285,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -355,19 +293,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["users"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/users/relations": { @@ -391,9 +323,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -401,19 +331,59 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["users"], - "security": [ - { - "bearer": [] + "security": [{ "bearer": [] }] + } + }, + "/users/sort-criteria": { + "post": { + "operationId": "updateSortCcriteria", + "summary": "", + "description": "ログインしているユーザーのタスクソート条件を更新します", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/SortCriteriaRequest" } + } } - ] + }, + "responses": { + "200": { + "description": "成功時のレスポンス", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SortCriteriaResponse" + } + } + } + }, + "401": { + "description": "認証エラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + }, + "500": { + "description": "想定外のサーバーエラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + } + }, + "tags": ["users"], + "security": [{ "bearer": [] }] } }, "/files/audio/upload-finished": { @@ -421,7 +391,14 @@ "operationId": "uploadFinished", "summary": "", "description": "アップロードが完了した音声ファイルの情報を登録し、文字起こしタスクを生成します", - "parameters": [], + "parameters": [ + { + "name": "authorization", + "required": true, + "in": "header", + "schema": { "type": "string" } + } + ], "requestBody": { "required": true, "content": { @@ -447,9 +424,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -457,9 +432,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -467,19 +440,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["files"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/files/audio/upload-location": { @@ -487,7 +454,14 @@ "operationId": "uploadLocation", "summary": "", "description": "ログイン中ユーザー用のBlob Storage上の音声ファイルのアップロード先アクセスURLを取得します", - "parameters": [], + "parameters": [ + { + "name": "authorization", + "required": true, + "in": "header", + "schema": { "type": "string" } + } + ], "responses": { "200": { "description": "成功時のレスポンス", @@ -503,9 +477,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -513,19 +485,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["files"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/files/audio/download-location": { @@ -539,9 +505,7 @@ "required": true, "in": "query", "description": "ODMSCloud上で管理する音声ファイルのID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -559,9 +523,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -569,9 +531,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -579,19 +539,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["files"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/files/template/download-location": { @@ -605,9 +559,7 @@ "required": true, "in": "query", "description": "文字起こし対象の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -625,9 +577,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -635,9 +585,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -645,19 +593,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["files"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks": { @@ -671,20 +613,22 @@ "required": false, "in": "query", "description": "タスクの取得件数(指定しない場合はデフォルト値)", - "schema": { - "default": 200, - "type": "number" - } + "schema": { "default": 200, "type": "number" } }, { "name": "offset", "required": false, "in": "query", "description": "オフセット(何件目から取得するか 設定しない場合はデフォルト値)", - "schema": { - "default": 0, - "type": "number" - } + "schema": { "default": 0, "type": "number" } + }, + { + "name": "status", + "required": false, + "in": "query", + "description": "取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup", + "example": "Uploaded,Pending,InProgress", + "schema": { "type": "string" } } ], "responses": { @@ -692,9 +636,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/TasksResponse" - } + "schema": { "$ref": "#/components/schemas/TasksResponse" } } } }, @@ -702,9 +644,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -712,9 +652,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -722,19 +660,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/next": { @@ -748,9 +680,7 @@ "required": true, "in": "query", "description": "文字起こし完了したタスクの音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -758,9 +688,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/AudioNextResponse" - } + "schema": { "$ref": "#/components/schemas/AudioNextResponse" } } } }, @@ -768,9 +696,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -778,9 +704,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -788,19 +712,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/{audioFileId}/checkout": { @@ -814,9 +732,7 @@ "required": true, "in": "path", "description": "ODMS Cloud上の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -834,9 +750,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -844,9 +758,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -854,9 +766,7 @@ "description": "指定したIDの音声ファイルが存在しない場合", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -864,19 +774,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/{audioFileId}/checkin": { @@ -890,9 +794,7 @@ "required": true, "in": "path", "description": "ODMS Cloud上の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -910,9 +812,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -920,9 +820,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -930,9 +828,7 @@ "description": "指定したIDの音声ファイルが存在しない場合", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -940,19 +836,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/{audioFileId}/cancel": { @@ -966,9 +856,7 @@ "required": true, "in": "path", "description": "ODMS Cloud上の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -986,9 +874,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -996,9 +882,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1006,9 +890,7 @@ "description": "指定したIDの音声ファイルが存在しない場合", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1016,19 +898,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/{audioFileId}/suspend": { @@ -1042,9 +918,7 @@ "required": true, "in": "path", "description": "ODMS Cloud上の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -1062,9 +936,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1072,9 +944,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1082,9 +952,7 @@ "description": "指定したIDの音声ファイルが存在しない場合", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1092,19 +960,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/{audioFileId}/send-back": { @@ -1118,9 +980,7 @@ "required": true, "in": "path", "description": "ODMS Cloud上の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -1138,9 +998,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1148,9 +1006,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1158,9 +1014,7 @@ "description": "指定したIDの音声ファイルが存在しない場合", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1168,19 +1022,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/tasks/{audioFileId}/backup": { @@ -1194,9 +1042,7 @@ "required": true, "in": "path", "description": "ODMS Cloud上の音声ファイルID", - "schema": { - "type": "number" - } + "schema": { "type": "number" } } ], "responses": { @@ -1214,9 +1060,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1224,9 +1068,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1234,9 +1076,7 @@ "description": "指定したIDの音声ファイルが存在しない場合", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1244,19 +1084,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["tasks"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/licenses/orders": { @@ -1268,9 +1102,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateOrdersRequest" - } + "schema": { "$ref": "#/components/schemas/CreateOrdersRequest" } } } }, @@ -1289,9 +1121,7 @@ "description": "同一PONumberの注文がすでに存在する場合など", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1299,9 +1129,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1309,19 +1137,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["licenses"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } }, "/notification/register": { @@ -1333,9 +1155,7 @@ "required": true, "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/RegisterRequest" - } + "schema": { "$ref": "#/components/schemas/RegisterRequest" } } } }, @@ -1344,9 +1164,7 @@ "description": "成功時のレスポンス", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/RegisterResponse" - } + "schema": { "$ref": "#/components/schemas/RegisterResponse" } } } }, @@ -1354,9 +1172,7 @@ "description": "不正なパラメータ", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1364,9 +1180,7 @@ "description": "認証エラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, @@ -1374,19 +1188,13 @@ "description": "想定外のサーバーエラー", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } + "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "tags": ["notification"], - "security": [ - { - "bearer": [] - } - ] + "security": [{ "bearer": [] }] } } }, @@ -1400,19 +1208,13 @@ "servers": [], "components": { "securitySchemes": { - "bearer": { - "scheme": "bearer", - "bearerFormat": "JWT", - "type": "http" - } + "bearer": { "scheme": "bearer", "bearerFormat": "JWT", "type": "http" } }, "schemas": { "TokenRequest": { "type": "object", "properties": { - "idToken": { - "type": "string" - }, + "idToken": { "type": "string" }, "type": { "type": "string", "description": "web or mobile or desktop" @@ -1423,69 +1225,43 @@ "TokenResponse": { "type": "object", "properties": { - "refreshToken": { - "type": "string" - }, - "accessToken": { - "type": "string" - } + "refreshToken": { "type": "string" }, + "accessToken": { "type": "string" } }, "required": ["refreshToken", "accessToken"] }, "ErrorResponse": { "type": "object", "properties": { - "message": { - "type": "string" - }, - "code": { - "type": "string" - } + "message": { "type": "string" }, + "code": { "type": "string" } }, "required": ["message", "code"] }, "AccessTokenResponse": { "type": "object", - "properties": { - "accessToken": { - "type": "string" - } - }, + "properties": { "accessToken": { "type": "string" } }, "required": ["accessToken"] }, "CreateAccountRequest": { "type": "object", "properties": { - "companyName": { - "type": "string" - }, + "companyName": { "type": "string" }, "country": { "type": "string", "description": "国名(ISO 3166-1 alpha-2)", "minLength": 2, "maxLength": 2 }, - "dealerAccountId": { - "type": "number", - "nullable": true - }, - "adminName": { - "type": "string" - }, - "adminMail": { - "type": "string" - }, - "adminPassword": { - "type": "string" - }, + "dealerAccountId": { "type": "number", "nullable": true }, + "adminName": { "type": "string" }, + "adminMail": { "type": "string" }, + "adminPassword": { "type": "string" }, "acceptedTermsVersion": { "type": "string", "description": "同意済み利用規約のバージョン" }, - "token": { - "type": "string", - "description": "reCAPTCHA Token" - } + "token": { "type": "string", "description": "reCAPTCHA Token" } }, "required": [ "companyName", @@ -1498,56 +1274,25 @@ "token" ] }, - "CreateAccountResponse": { - "type": "object", - "properties": {} - }, + "CreateAccountResponse": { "type": "object", "properties": {} }, "ConfirmRequest": { "type": "object", - "properties": { - "token": { - "type": "string" - } - }, + "properties": { "token": { "type": "string" } }, "required": ["token"] }, - "ConfirmResponse": { - "type": "object", - "properties": {} - }, + "ConfirmResponse": { "type": "object", "properties": {} }, "User": { "type": "object", "properties": { - "name": { - "type": "string" - }, - "role": { - "type": "string", - "description": "none/author/typist" - }, - "authorId": { - "type": "string", - "nullable": true - }, - "typistGroupName": { - "type": "string", - "nullable": true - }, - "email": { - "type": "string" - }, - "emailVerified": { - "type": "boolean" - }, - "autoRenew": { - "type": "boolean" - }, - "licenseAlert": { - "type": "boolean" - }, - "notification": { - "type": "boolean" - } + "name": { "type": "string" }, + "role": { "type": "string", "description": "none/author/typist" }, + "authorId": { "type": "string", "nullable": true }, + "typistGroupName": { "type": "string", "nullable": true }, + "email": { "type": "string" }, + "emailVerified": { "type": "boolean" }, + "autoRenew": { "type": "boolean" }, + "licenseAlert": { "type": "boolean" }, + "notification": { "type": "boolean" } }, "required": [ "name", @@ -1566,9 +1311,7 @@ "properties": { "users": { "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } + "items": { "$ref": "#/components/schemas/User" } } }, "required": ["users"] @@ -1576,31 +1319,14 @@ "SignupRequest": { "type": "object", "properties": { - "name": { - "type": "string" - }, - "role": { - "type": "string", - "description": "none/author/typist" - }, - "authorId": { - "type": "string" - }, - "typistGroupId": { - "type": "number" - }, - "email": { - "type": "string" - }, - "autoRenew": { - "type": "boolean" - }, - "licenseAlert": { - "type": "boolean" - }, - "notification": { - "type": "boolean" - } + "name": { "type": "string" }, + "role": { "type": "string", "description": "none/author/typist" }, + "authorId": { "type": "string" }, + "typistGroupId": { "type": "number" }, + "email": { "type": "string" }, + "autoRenew": { "type": "boolean" }, + "licenseAlert": { "type": "boolean" }, + "notification": { "type": "boolean" } }, "required": [ "name", @@ -1611,10 +1337,7 @@ "notification" ] }, - "SignupResponse": { - "type": "object", - "properties": {} - }, + "SignupResponse": { "type": "object", "properties": {} }, "OptionItem": { "type": "object", "properties": { @@ -1640,16 +1363,12 @@ "OptionItemList": { "type": "object", "properties": { - "workTypeId": { - "type": "string" - }, + "workTypeId": { "type": "string" }, "optionItemList": { "maxItems": 10, "description": "1WorkTypeIDにつき、10個まで登録可能", "type": "array", - "items": { - "$ref": "#/components/schemas/OptionItem" - } + "items": { "$ref": "#/components/schemas/OptionItem" } } }, "required": ["workTypeId", "optionItemList"] @@ -1664,17 +1383,13 @@ "authorIdList": { "description": "属しているアカウントのAuthorID List(全て)", "type": "array", - "items": { - "type": "string" - } + "items": { "type": "string" } }, "workTypeList": { "maxItems": 20, "description": "アカウントに設定されているWorktypeIDのリスト(最大20個)", "type": "array", - "items": { - "$ref": "#/components/schemas/OptionItemList" - } + "items": { "$ref": "#/components/schemas/OptionItemList" } }, "isEncrypted": { "type": "boolean", @@ -1709,6 +1424,18 @@ "prompt" ] }, + "SortCriteriaRequest": { + "type": "object", + "properties": { + "direction": { "type": "string", "description": "ASC/DESC" }, + "paramName": { + "type": "string", + "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" + } + }, + "required": ["direction", "paramName"] + }, + "SortCriteriaResponse": { "type": "object", "properties": {} }, "AudioOptionItem": { "type": "object", "properties": { @@ -1736,10 +1463,7 @@ "type": "string", "description": "自分自身(ログイン認証)したAuthorID" }, - "fileName": { - "type": "string", - "description": "音声ファイル名" - }, + "fileName": { "type": "string", "description": "音声ファイル名" }, "duration": { "type": "string", "description": "音声ファイルの録音時間(yyyy-mm-ddThh:mm:ss.sss)" @@ -1768,24 +1492,16 @@ "type": "string", "description": "録音形式: DSS/DS2(SP)/DS2(QP)" }, - "comment": { - "type": "string" - }, - "workType": { - "type": "string" - }, + "comment": { "type": "string" }, + "workType": { "type": "string" }, "optionItemList": { "maxItems": 10, "minItems": 10, "description": "音声ファイルに紐づくOption Itemの一覧(10個固定)", "type": "array", - "items": { - "$ref": "#/components/schemas/AudioOptionItem" - } + "items": { "$ref": "#/components/schemas/AudioOptionItem" } }, - "isEncrypted": { - "type": "boolean" - } + "isEncrypted": { "type": "boolean" } }, "required": [ "url", @@ -1807,10 +1523,7 @@ "AudioUploadFinishedResponse": { "type": "object", "properties": { - "jobNumber": { - "type": "string", - "description": "8桁固定の数字" - } + "jobNumber": { "type": "string", "description": "8桁固定の数字" } }, "required": ["jobNumber"] }, @@ -1836,11 +1549,7 @@ }, "TemplateDownloadLocationResponse": { "type": "object", - "properties": { - "url": { - "type": "string" - } - }, + "properties": { "url": { "type": "string" } }, "required": ["url"] }, "Typist": { @@ -1868,30 +1577,20 @@ "type": "number", "description": "ODMS Cloud上の音声ファイルID" }, - "authorId": { - "type": "string", - "description": "AuthorID" - }, - "workType": { - "type": "string" - }, + "authorId": { "type": "string", "description": "AuthorID" }, + "workType": { "type": "string" }, "optionItemList": { "maxItems": 10, "minItems": 10, "description": "音声ファイルに紐づくOption Itemの一覧(10個固定)", "type": "array", - "items": { - "$ref": "#/components/schemas/AudioOptionItem" - } + "items": { "$ref": "#/components/schemas/AudioOptionItem" } }, "url": { "type": "string", "description": "音声ファイルのBlob Storage上での保存場所(ファイル名含む)のURL" }, - "fileName": { - "type": "string", - "description": "音声ファイル名" - }, + "fileName": { "type": "string", "description": "音声ファイル名" }, "audioDuration": { "type": "string", "description": "音声ファイルの録音時間(yyyy-mm-ddThh:mm:ss.sss)" @@ -1920,31 +1619,17 @@ "type": "string", "description": "録音形式: DSS/DS2(SP)/DS2(QP)" }, - "comment": { - "type": "string", - "description": "コメント" - }, - "isEncrypted": { - "type": "boolean" - }, - "jobNumber": { - "type": "string", - "description": "JOBナンバー" - }, + "comment": { "type": "string", "description": "コメント" }, + "isEncrypted": { "type": "boolean" }, + "jobNumber": { "type": "string", "description": "JOBナンバー" }, "typist": { "description": "割り当てられたユーザー", - "allOf": [ - { - "$ref": "#/components/schemas/Typist" - } - ] + "allOf": [{ "$ref": "#/components/schemas/Typist" }] }, "assignees": { "description": "文字起こしに着手できる(チェックアウト可能な)、タスクにアサインされているグループ/個人の一覧", "type": "array", - "items": { - "$ref": "#/components/schemas/Typist" - } + "items": { "$ref": "#/components/schemas/Typist" } }, "status": { "type": "string", @@ -1993,16 +1678,11 @@ "type": "number", "description": "オフセット(何件目から取得するか 設定しない場合はデフォルト値)" }, - "total": { - "type": "number", - "description": "タスクの総件数" - }, + "total": { "type": "number", "description": "タスクの総件数" }, "tasks": { "description": "音声ファイル/タスク一覧", "type": "array", - "items": { - "$ref": "#/components/schemas/Task" - } + "items": { "$ref": "#/components/schemas/Task" } } }, "required": ["limit", "offset", "total", "tasks"] @@ -2016,33 +1696,20 @@ } } }, - "ChangeStatusResponse": { - "type": "object", - "properties": {} - }, + "ChangeStatusResponse": { "type": "object", "properties": {} }, "CreateOrdersRequest": { "type": "object", "properties": { - "poNumber": { - "type": "string" - }, - "orderCount": { - "type": "number" - } + "poNumber": { "type": "string" }, + "orderCount": { "type": "number" } }, "required": ["poNumber", "orderCount"] }, - "CreateOrdersResponse": { - "type": "object", - "properties": {} - }, + "CreateOrdersResponse": { "type": "object", "properties": {} }, "RegisterRequest": { "type": "object", "properties": { - "pns": { - "type": "string", - "description": "wns or apns" - }, + "pns": { "type": "string", "description": "wns or apns" }, "handler": { "type": "string", "description": "wnsのチャネルURI or apnsのデバイストークン" @@ -2050,10 +1717,7 @@ }, "required": ["pns", "handler"] }, - "RegisterResponse": { - "type": "object", - "properties": {} - } + "RegisterResponse": { "type": "object", "properties": {} } } } } diff --git a/dictation_server/src/common/auth/auth.ts b/dictation_server/src/common/auth/auth.ts index 90d8479..231f181 100644 --- a/dictation_server/src/common/auth/auth.ts +++ b/dictation_server/src/common/auth/auth.ts @@ -3,14 +3,9 @@ * @param {string[]} * @return {boolean} */ +// XXX: deprecated 削除予定 export const confirmPermission = (authority: string): boolean => { console.log(authority); return true; - // TODO 将来的にscopeの内容に応じた処理を入れることになる - //  if (authority.startsWith('hogehoge')) { - //    return true; - //  } else { - //    return false; - //  } }; diff --git a/dictation_server/src/common/token/types.ts b/dictation_server/src/common/token/types.ts index d3d91d4..59542d3 100644 --- a/dictation_server/src/common/token/types.ts +++ b/dictation_server/src/common/token/types.ts @@ -1,10 +1,22 @@ export type RefreshToken = { + /** + * 外部認証サービスの識別子 + */ userId: string; + /** + * 半角スペース区切りのRoleを表現する文字列(ex. "author admin") + */ role: string; }; export type AccessToken = { + /** + * 外部認証サービスの識別子 + */ userId: string; + /** + * 半角スペース区切りのRoleを表現する文字列(ex. "author admin") + */ role: string; }; diff --git a/dictation_server/src/constants/index.ts b/dictation_server/src/constants/index.ts index 19d6bb6..93e84f7 100644 --- a/dictation_server/src/constants/index.ts +++ b/dictation_server/src/constants/index.ts @@ -130,3 +130,24 @@ export const TASK_STATUS = { FINISHED: 'Finished', BACKUP: 'Backup', } as const; + +/** + * タスク一覧でソート可能な属性の一覧 + */ +export const TASK_LIST_SORTABLE_ATTRIBUTES = [ + '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', +] as const; + +export type TaskListSortableAttribute = + (typeof TASK_LIST_SORTABLE_ATTRIBUTES)[number]; diff --git a/dictation_server/src/features/notification/notification.controller.ts b/dictation_server/src/features/notification/notification.controller.ts index 63c7c31..7697f3a 100644 --- a/dictation_server/src/features/notification/notification.controller.ts +++ b/dictation_server/src/features/notification/notification.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, HttpStatus, Post } from '@nestjs/common'; +import { Body, Controller, HttpStatus, Post, UseGuards } from '@nestjs/common'; import { ApiResponse, ApiOperation, @@ -8,6 +8,7 @@ import { import { ErrorResponse } from '../../common/error/types/types'; import { RegisterRequest, RegisterResponse } from './types/types'; import { NotificationService } from './notification.service'; +import { AuthGuard } from 'src/common/guards/auth/authguards'; @ApiTags('notification') @Controller('notification') @@ -36,9 +37,9 @@ export class NotificationController { type: ErrorResponse, }) @ApiOperation({ operationId: 'register' }) + @UseGuards(AuthGuard) async register(@Body() body: RegisterRequest): Promise { const { handler, pns } = body; - // XXX 登録処理の前にアクセストークンの認証を行う await this.notificationService.register(pns, handler); return {}; } diff --git a/dictation_server/src/features/tasks/tasks.controller.ts b/dictation_server/src/features/tasks/tasks.controller.ts index 1abb828..1e24675 100644 --- a/dictation_server/src/features/tasks/tasks.controller.ts +++ b/dictation_server/src/features/tasks/tasks.controller.ts @@ -6,7 +6,6 @@ import { Param, Post, Query, - UseGuards, } from '@nestjs/common'; import { ApiResponse, @@ -24,7 +23,6 @@ import { TasksRequest, TasksResponse, } from './types/types'; -import { AuthGuard } from '../../common/guards/auth/authguards'; @ApiTags('tasks') @Controller('tasks') @@ -317,7 +315,7 @@ export class TasksController { return {}; } - // TODO 操作としてarchiveの方が適切かもしれない + @Post(':audioFileId/backup') @ApiResponse({ status: HttpStatus.OK, diff --git a/dictation_server/src/features/tasks/types/types.ts b/dictation_server/src/features/tasks/types/types.ts index 4d51d2c..db27726 100644 --- a/dictation_server/src/features/tasks/types/types.ts +++ b/dictation_server/src/features/tasks/types/types.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { AudioOptionItem } from '../../../features/files/types/types'; +import { IsInt, IsOptional, Min } from 'class-validator'; export class TasksRequest { @ApiProperty({ @@ -7,14 +8,31 @@ export class TasksRequest { default: 200, description: 'タスクの取得件数(指定しない場合はデフォルト値)', }) + @IsInt() + @Min(0) + @IsOptional() limit: number; + @ApiProperty({ required: false, default: 0, description: 'オフセット(何件目から取得するか 設定しない場合はデフォルト値)', }) + @IsInt() + @Min(0) + @IsOptional() offset: number; + + @ApiProperty({ + required: false, + description: + '取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup', + example: 'Uploaded,Pending,InProgress', + }) + @IsOptional() + // TODO: 入力チェックを行うデコレータを追加する。@Matches or カスタムデコレータで実装想定。statusの値は先頭大文字であることまで一致しなくていいはず?(実装時レビューにて要確認) + status?: string; } export class Typist { diff --git a/dictation_server/src/features/users/types/types.ts b/dictation_server/src/features/users/types/types.ts index a960eba..f621d00 100644 --- a/dictation_server/src/features/users/types/types.ts +++ b/dictation_server/src/features/users/types/types.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsIn } from 'class-validator'; +import { TASK_LIST_SORTABLE_ATTRIBUTES } from '../../../constants'; import { USER_ROLES } from '../../../constants'; export class ConfirmRequest { @@ -132,3 +133,15 @@ export class GetRelationsResponse { }) prompt: boolean; } + +export class SortCriteriaRequest { + @ApiProperty({ description: 'ASC/DESC' }) + @IsIn(['ASC', 'DESC'], { message: 'invalid direction' }) + direction: string; + + @ApiProperty({ description: `${TASK_LIST_SORTABLE_ATTRIBUTES.join('/')}` }) + @IsIn(TASK_LIST_SORTABLE_ATTRIBUTES, { message: 'invalid attributes' }) + paramName: string; +} + +export class SortCriteriaResponse {} diff --git a/dictation_server/src/features/users/users.controller.ts b/dictation_server/src/features/users/users.controller.ts index efe8c68..f3b7721 100644 --- a/dictation_server/src/features/users/users.controller.ts +++ b/dictation_server/src/features/users/users.controller.ts @@ -29,6 +29,8 @@ import { GetUsersResponse, SignupRequest, SignupResponse, + SortCriteriaRequest, + SortCriteriaResponse, } from './types/types'; import { UsersService } from './users.service'; import { AuthGuard } from '../../common/guards/auth/authguards'; @@ -271,4 +273,33 @@ export class UsersController { prompt: true, }; } + + @ApiResponse({ + status: HttpStatus.OK, + type: SortCriteriaResponse, + description: '成功時のレスポンス', + }) + @ApiResponse({ + status: HttpStatus.UNAUTHORIZED, + description: '認証エラー', + type: ErrorResponse, + }) + @ApiResponse({ + status: HttpStatus.INTERNAL_SERVER_ERROR, + description: '想定外のサーバーエラー', + type: ErrorResponse, + }) + @ApiOperation({ + operationId: 'updateSortCcriteria', + description: 'ログインしているユーザーのタスクソート条件を更新します', + }) + @ApiBearerAuth() + @UseGuards(AuthGuard) + @Post('sort-criteria') + async updateSortCriteria( + @Body() body: SortCriteriaRequest, + ): Promise { + console.log(body); + return {}; + } } diff --git a/dictation_server/src/features/users/users.service.ts b/dictation_server/src/features/users/users.service.ts index a80a9df..4194a54 100644 --- a/dictation_server/src/features/users/users.service.ts +++ b/dictation_server/src/features/users/users.service.ts @@ -95,8 +95,6 @@ export class UsersService { authorId?: string | undefined, groupID?: number | undefined, ): Promise { - //アクセストークンからユーザーIDを取得する - // TODO アクセストークンの中身が具体的に確定したら、型変換を取り払う必要があるかも this.logger.log(`[IN] ${this.createUser.name}`); //DBよりアクセス者の所属するアカウントIDを取得する diff --git a/dictation_server/src/main.ts b/dictation_server/src/main.ts index b588c44..5bcba7f 100644 --- a/dictation_server/src/main.ts +++ b/dictation_server/src/main.ts @@ -49,8 +49,6 @@ async function bootstrap() { SwaggerModule.setup('api', app, document); } - // TODO:検証のためポートを固定 後で直す - // await app.listen(process.env.PORT || 80); await app.listen(process.env.PORT || 80); } bootstrap();